From 6df739a0459d7b88caea8b4a2d182fa968709884 Mon Sep 17 00:00:00 2001 From: Seris02 Date: Thu, 19 Dec 2019 00:39:29 +0800 Subject: [PATCH 001/203] changes holofan, adds holofirelock --- code/game/objects/items/holosign_creator.dm | 10 +++++++- code/game/objects/structures/holosign.dm | 28 ++++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/code/game/objects/items/holosign_creator.dm b/code/game/objects/items/holosign_creator.dm index 78881d901e..c241ca50ae 100644 --- a/code/game/objects/items/holosign_creator.dm +++ b/code/game/objects/items/holosign_creator.dm @@ -78,12 +78,20 @@ /obj/item/holosign_creator/atmos name = "ATMOS holofan projector" - desc = "A holographic projector that creates holographic barriers that prevent changes in atmosphere conditions." + desc = "A holographic projector that creates holographic fans that prevent changes in atmosphere conditions. Somehow." icon_state = "signmaker_engi" holosign_type = /obj/structure/holosign/barrier/atmos creation_time = 0 max_signs = 3 +/obj/item/holosign_creator/firelock + name = "ATMOS holofirelock projector" + desc = "A holographic projector that creates holographic barriers that prevent changes in temperature conditions." + icon_state = "signmaker_engi" + holosign_type = /obj/structure/holosign/barrier/firelock + creation_time = 0 + max_signs = 3 + /obj/item/holosign_creator/medical name = "\improper PENLITE barrier projector" desc = "A holographic projector that creates PENLITE holobarriers. Useful during quarantines since they halt those with malicious diseases." diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm index 1f007b6993..383ddd929f 100644 --- a/code/game/objects/structures/holosign.dm +++ b/code/game/objects/structures/holosign.dm @@ -69,9 +69,9 @@ rad_insulation = RAD_LIGHT_INSULATION /obj/structure/holosign/barrier/atmos - name = "holo firelock" - desc = "A holographic barrier resembling a firelock. Though it does not prevent solid objects from passing through, gas is kept out." - icon_state = "holo_firelock" + name = "holo fan" + desc = "A holographic barrier resembling a tiny fan. Though it does not prevent solid objects from passing through, gas is kept out. Somehow." + icon_state = "holo_fan" density = FALSE anchored = TRUE CanAtmosPass = ATMOS_PASS_NO @@ -81,6 +81,28 @@ . = ..() air_update_turf(TRUE) +/obj/structure/holosign/barrier/firelock + name = "holo firelock" + desc = "A holographic barrier resembling a firelock. Though it does not prevent solid objects or gas from passing through, temperature changes are kept out." + icon_state = "holo_firelock" + density = TRUE + anchored = TRUE + alpha = 150 + +/obj/structure/holosign/barrier/firelock/BlockSuperconductivity() + return TRUE + +/obj/structure/holosign/barrier/firelock/fire_act(exposed_temperature,exposed_volume) + return + +/obj/structure/holosign/barrier/firelock/CanPass(atom/movable/mover, turf/target) + if(mover.pass_flags & (PASSGLASS|PASSTABLE|PASSGRILLE)) + return 1 + if(iscarbon(mover)) + var/mob/living/carbon/C = mover + if(allow_walk && C.m_intent == MOVE_INTENT_WALK) + return 1 + /obj/structure/holosign/barrier/cyborg name = "Energy Field" desc = "A fragile energy field that blocks movement. Excels at blocking lethal projectiles." From 61ab3685f1c51ba8b164bbb5318dbe81022809c8 Mon Sep 17 00:00:00 2001 From: Seris02 Date: Fri, 20 Dec 2019 14:14:01 +0800 Subject: [PATCH 002/203] atmos firelock, changes to temp blocking --- .../crates_lockers/closets/secure/engineering.dm | 1 + code/game/objects/structures/holosign.dm | 16 +++------------- .../environmental/LINDA_turf_tile.dm | 12 +++++++++--- code/modules/research/designs/misc_designs.dm | 10 ++++++++++ code/modules/research/techweb/all_nodes.dm | 2 +- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm index 8da50d488f..fdc8d03374 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm @@ -98,6 +98,7 @@ new /obj/item/tank/internals/emergency_oxygen/engi(src) new /obj/item/analyzer(src) new /obj/item/holosign_creator/atmos(src) + new /obj/item/holosign_creator/firelock(src) new /obj/item/watertank/atmos(src) new /obj/item/clothing/suit/fire/atmos(src) new /obj/item/clothing/head/hardhat/atmos(src) diff --git a/code/game/objects/structures/holosign.dm b/code/game/objects/structures/holosign.dm index 383ddd929f..69ad9f1567 100644 --- a/code/game/objects/structures/holosign.dm +++ b/code/game/objects/structures/holosign.dm @@ -85,24 +85,14 @@ name = "holo firelock" desc = "A holographic barrier resembling a firelock. Though it does not prevent solid objects or gas from passing through, temperature changes are kept out." icon_state = "holo_firelock" - density = TRUE + density = FALSE anchored = TRUE alpha = 150 + resistance_flags = FIRE_PROOF -/obj/structure/holosign/barrier/firelock/BlockSuperconductivity() +/obj/structure/holosign/barrier/firelock/blocksTemperature() return TRUE -/obj/structure/holosign/barrier/firelock/fire_act(exposed_temperature,exposed_volume) - return - -/obj/structure/holosign/barrier/firelock/CanPass(atom/movable/mover, turf/target) - if(mover.pass_flags & (PASSGLASS|PASSTABLE|PASSGRILLE)) - return 1 - if(iscarbon(mover)) - var/mob/living/carbon/C = mover - if(allow_walk && C.m_intent == MOVE_INTENT_WALK) - return 1 - /obj/structure/holosign/barrier/cyborg name = "Energy Field" desc = "A fragile energy field that blocks movement. Excels at blocking lethal projectiles." diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm index 196bf70fdc..389f1a69f3 100644 --- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm +++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm @@ -358,6 +358,9 @@ SSair.excited_groups -= src ////////////////////////SUPERCONDUCTIVITY///////////////////////////// +/atom/movable/proc/blocksTemperature() + return FALSE + /turf/proc/conductivity_directions() if(archived_cycle < SSair.times_fired) archive() @@ -372,6 +375,9 @@ . |= direction /turf/proc/neighbor_conduct_with_src(turf/open/other) + for (var/atom/movable/G in src) + if (G.blocksTemperature()) + return if(!other.blocks_air) //Open but neighbor is solid other.temperature_share_open_to_solid(src) else //Both tiles are solid @@ -382,7 +388,9 @@ if(blocks_air) ..() return - + for (var/atom/movable/G in src) + if (G.blocksTemperature()) + return if(!other.blocks_air) //Both tiles are open var/turf/open/T = other T.air.temperature_share(air, WINDOW_HEAT_TRANSFER_COEFFICIENT) @@ -401,10 +409,8 @@ if(!neighbor.thermal_conductivity) continue - if(neighbor.archived_cycle < SSair.times_fired) neighbor.archive() - neighbor.neighbor_conduct_with_src(src) neighbor.consider_superconductivity() diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index 5f7648b245..302ac345b7 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -364,6 +364,16 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING +/datum/design/holosignfirelock + name = "ATMOS Holofirelock Projector" + desc = "A holographic projector that creates holographic barriers that prevent changes in temperature conditions." + id = "holosignfirelock" + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_GLASS = 1000, MAT_GOLD = 1000, MAT_SILVER = 1000) + build_path = /obj/item/holosign_creator/firelock + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + /datum/design/forcefield_projector name = "Forcefield Projector" desc = "A device which can project temporary forcefields to seal off an area." diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index eed1e4aefd..2df93ca0e8 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -430,7 +430,7 @@ display_name = "Electromagnetic Theory" description = "Study into usage of frequencies in the electromagnetic spectrum." prereq_ids = list("base") - design_ids = list("holosign", "holosignsec", "holosignengi", "holosignatmos", "inducer", "tray_goggles", "holopad") + design_ids = list("holosign", "holosignsec", "holosignengi", "holosignatmos", "holosignfirelock", "inducer", "tray_goggles", "holopad") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 From ffa013af6eae12be04d8ef6f1d8d71786be2fddb Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Wed, 25 Dec 2019 03:59:21 +0100 Subject: [PATCH 003/203] Minor captains closet cleanup. --- .../structures/crates_lockers/closets/secure/security.dm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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 835be8d2fc..058782e1ab 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -19,7 +19,6 @@ new /obj/item/clothing/under/captainparade(src) new /obj/item/clothing/suit/armor/vest/capcarapace/alt(src) new /obj/item/clothing/head/caphat/parade(src) - new /obj/item/clothing/head/caphat/beret(src) new /obj/item/clothing/suit/captunic(src) new /obj/item/clothing/under/rank/captain/femformal(src) //citadel edit new /obj/item/clothing/head/crown/fancy(src) @@ -29,12 +28,14 @@ new /obj/item/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/restraints/handcuffs/cable/zipties(src) new /obj/item/storage/belt/sabre(src) new /obj/item/gun/energy/e_gun(src) new /obj/item/door_remote/captain(src) new /obj/item/storage/photo_album/Captain(src) - new /obj/item/clothing/head/caphat/beret/white(src) + if(prob(50)) + new /obj/item/clothing/head/caphat/beret(src) + else + new /obj/item/clothing/head/caphat/beret/white(src) /obj/structure/closet/secure_closet/hop name = "\proper head of personnel's locker" From 6222b41204c1546d339356c3cb40f98c5621560b Mon Sep 17 00:00:00 2001 From: chefferz Date: Wed, 1 Jan 2020 20:44:16 -0500 Subject: [PATCH 004/203] Update forcefieldprojector.dm --- code/game/objects/items/devices/forcefieldprojector.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/devices/forcefieldprojector.dm b/code/game/objects/items/devices/forcefieldprojector.dm index 0c73d829ff..dda75ca1ec 100644 --- a/code/game/objects/items/devices/forcefieldprojector.dm +++ b/code/game/objects/items/devices/forcefieldprojector.dm @@ -10,7 +10,7 @@ lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' materials = list(MAT_METAL=250, MAT_GLASS=500) - var/max_shield_integrity = 250 + var/max_shield_integrity = 100 var/shield_integrity = 250 var/max_fields = 3 var/list/current_fields @@ -87,7 +87,7 @@ mouse_opacity = MOUSE_OPACITY_OPAQUE resistance_flags = INDESTRUCTIBLE CanAtmosPass = ATMOS_PASS_DENSITY - armor = list("melee" = 0, "bullet" = 25, "laser" = 50, "energy" = 50, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) + armor = list("melee" = 0, "bullet" = 25, "laser" = 25, "energy" = 25, "bomb" = 25, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) var/obj/item/forcefield_projector/generator /obj/structure/projected_forcefield/Initialize(mapload, obj/item/forcefield_projector/origin) From 0b02439b08eb459cf77f5fa8dcc951a431bc14b7 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 2 Jan 2020 03:53:04 -0700 Subject: [PATCH 005/203] Puts an end to the Christmas Menace --- code/modules/vending/autodrobe.dm | 6 ++++++ code/modules/vending/clothesmate.dm | 4 ++++ modular_citadel/code/modules/client/loadout/head.dm | 4 +++- modular_citadel/code/modules/client/loadout/uniform.dm | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/code/modules/vending/autodrobe.dm b/code/modules/vending/autodrobe.dm index 8cd7fc8539..0911258692 100644 --- a/code/modules/vending/autodrobe.dm +++ b/code/modules/vending/autodrobe.dm @@ -131,6 +131,12 @@ /obj/item/clothing/suit/drfreeze_coat = 1, /obj/item/clothing/suit/gothcoat = 2, /obj/item/clothing/under/draculass = 1, + /obj/item/clothing/under/christmas/christmasmaler = 3, + /obj/item/clothing/under/christmas/christmasmaleg = 3, + /obj/item/clothing/under/christmas/christmasfemaler = 3, + /obj/item/clothing/under/christmas/christmasfemaleg = 3, + /obj/item/clothing/head/christmashat = 3, + /obj/item/clothing/head/christmashatg = 3, /obj/item/clothing/under/drfreeze = 1) //End of Cit Changes refill_canister = /obj/item/vending_refill/autodrobe diff --git a/code/modules/vending/clothesmate.dm b/code/modules/vending/clothesmate.dm index 6144f4c57a..826650db36 100644 --- a/code/modules/vending/clothesmate.dm +++ b/code/modules/vending/clothesmate.dm @@ -123,15 +123,19 @@ /obj/item/clothing/ears/headphones = 10, /obj/item/clothing/suit/apron/purple_bartender = 4, /obj/item/clothing/under/rank/bartender/purple = 4, + /* Commenting out until next Christmas or made automatic /obj/item/clothing/under/christmas/christmasmaler = 3, /obj/item/clothing/under/christmas/christmasmaleg = 3, /obj/item/clothing/under/christmas/christmasfemaler = 3, /obj/item/clothing/under/christmas/christmasfemaleg = 3, + */ /obj/item/clothing/suit/hooded/wintercoat/christmascoatr = 3, /obj/item/clothing/suit/hooded/wintercoat/christmascoatg = 3, /obj/item/clothing/suit/hooded/wintercoat/christmascoatrg = 3, + /*Commenting out until next Christmas or made automatic /obj/item/clothing/head/christmashat = 3, /obj/item/clothing/head/christmashatg = 3, + */ /obj/item/clothing/shoes/winterboots/christmasbootsr = 3, /obj/item/clothing/shoes/winterboots/christmasbootsg = 3, /obj/item/clothing/shoes/winterboots/santaboots = 3) diff --git a/modular_citadel/code/modules/client/loadout/head.dm b/modular_citadel/code/modules/client/loadout/head.dm index 3e7eb39823..efe1fb524c 100644 --- a/modular_citadel/code/modules/client/loadout/head.dm +++ b/modular_citadel/code/modules/client/loadout/head.dm @@ -93,6 +93,7 @@ restricted_desc = "Engineering, Security, and Cargo" restricted_roles = list("Chief Engineer","Atmospheric Technician","Station Engineer","Warden","Detective","Security Officer","Head of Security","Cargo Technician", "Shaft Miner", "Quartermaster") +/*Commenting out Until next Christmas or made automatic /datum/gear/santahatr name = "Red Santa Hat" category = SLOT_HEAD @@ -101,4 +102,5 @@ /datum/gear/santahatg name = "Green Santa Hat" category = SLOT_HEAD - path = /obj/item/clothing/head/christmashatg \ No newline at end of file + path = /obj/item/clothing/head/christmashatg +*/ \ No newline at end of file diff --git a/modular_citadel/code/modules/client/loadout/uniform.dm b/modular_citadel/code/modules/client/loadout/uniform.dm index 64ed0d363d..46692ea7a9 100644 --- a/modular_citadel/code/modules/client/loadout/uniform.dm +++ b/modular_citadel/code/modules/client/loadout/uniform.dm @@ -390,6 +390,7 @@ path = /obj/item/clothing/under/gear_harness //Christmas +/*Commenting out Until next Christmas or made automatic /datum/gear/christmasmaler name = "Red Masculine Christmas Suit" category = SLOT_W_UNIFORM @@ -415,6 +416,7 @@ category = SLOT_W_UNIFORM path = /obj/item/clothing/under/stripper_pink cost = 3 +*/ /datum/gear/greenstripper name = "Green stripper outfit" From b793bceffcd424ed9dbd7ff14346896172782bab Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Thu, 2 Jan 2020 10:51:06 -0800 Subject: [PATCH 006/203] A --- code/modules/admin/IsBanned.dm | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 839292871c..59b207109c 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -7,14 +7,23 @@ #define STICKYBAN_MAX_ADMIN_MATCHES 2 /world/IsBanned(key,address,computer_id,type,real_bans_only=FALSE) + var/static/key_cache = list() + if(!real_bans_only) + if(key_cache[key]) + return list("reason"="concurrent connection attempts", "desc"="You are attempting to connect too fast. Try again.") + key_cache[key] = 1 + if (!key || !address || !computer_id) if(real_bans_only) + key_cache[key] = 0 return FALSE log_access("Failed Login (invalid data): [key] [address]-[computer_id]") + key_cache[key] = 0 return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided invalid or blank information to the server on connection (byond username, IP, and Computer ID.) Provided information for reference: Username:'[key]' IP:'[address]' Computer ID:'[computer_id]'. (If you continue to get this error, please restart byond or contact byond support.)") if (text2num(computer_id) == 2147483647) //this cid causes stickybans to go haywire log_access("Failed Login (invalid cid): [key] [address]-[computer_id]") + key_cache[key] = 0 return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided an invalid Computer ID.)") var/admin = 0 var/ckey = ckey(key) @@ -30,21 +39,25 @@ addclientmessage(ckey,"You have been allowed to bypass the whitelist") else log_access("Failed Login: [key] - Not on whitelist") + key_cache[key] = 0 return list("reason"="whitelist", "desc" = "\nReason: You are not on the white list for this server") //Guest Checking if(!real_bans_only && IsGuestKey(key)) if (CONFIG_GET(flag/guest_ban)) log_access("Failed Login: [key] - Guests not allowed") + key_cache[key] = 0 return list("reason"="guest", "desc"="\nReason: Guests not allowed. Please sign in with a byond account.") if (CONFIG_GET(flag/panic_bunker) && SSdbcore.Connect()) log_access("Failed Login: [key] - Guests not allowed during panic bunker") + key_cache[key] = 0 return list("reason"="guest", "desc"="\nReason: Sorry but the server is currently not accepting connections from never before seen players or guests. If you have played on this server with a byond account before, please log in to the byond account you have played from.") //Population Cap Checking var/extreme_popcap = CONFIG_GET(number/extreme_popcap) if(!real_bans_only && extreme_popcap && living_player_count() >= extreme_popcap && !admin) log_access("Failed Login: [key] - Population cap reached") + key_cache[key] = 0 return list("reason"="popcap", "desc"= "\nReason: [CONFIG_GET(string/extreme_popcap_message)]") if(CONFIG_GET(flag/ban_legacy_system)) @@ -58,6 +71,7 @@ addclientmessage(ckey,"You have been allowed to bypass a matching ban on [.["key"]]") else log_access("Failed Login: [key] [computer_id] [address] - Banned [.["reason"]]") + key_cache[key] = 0 return . else @@ -65,6 +79,7 @@ var/msg = "Ban database connection failure. Key [ckey] not checked" log_world(msg) message_admins(msg) + key_cache[key] = 0 return var/ipquery = "" @@ -78,6 +93,7 @@ var/datum/DBQuery/query_ban_check = SSdbcore.NewQuery("SELECT IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].ckey), ckey), IFNULL((SELECT byond_key FROM [format_table_name("player")] WHERE [format_table_name("player")].ckey = [format_table_name("ban")].a_ckey), a_ckey), reason, expiration_time, duration, bantime, bantype, id, round_id FROM [format_table_name("ban")] WHERE (ckey = '[ckey]' [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR bantype = 'ADMIN_PERMABAN' OR ((bantype = 'TEMPBAN' OR bantype = 'ADMIN_TEMPBAN') AND expiration_time > Now())) AND isnull(unbanned)") if(!query_ban_check.Execute(async = TRUE)) qdel(query_ban_check) + key_cache[key] = 0 return while(query_ban_check.NextRow()) var/pkey = query_ban_check.item[1] @@ -116,6 +132,7 @@ log_access("Failed Login: [key] [computer_id] [address] - Banned (#[banid]) [.["reason"]]") qdel(query_ban_check) + key_cache[key] = 0 return . qdel(query_ban_check) @@ -131,6 +148,7 @@ //rogue ban in the process of being reverted. if (cachedban && cachedban["reverting"]) + key_cache[key] = 0 return null if (cachedban && ckey != bannedckey) @@ -158,6 +176,7 @@ newmatches_admin.len > STICKYBAN_MAX_ADMIN_MATCHES \ ) if (cachedban["reverting"]) + key_cache[key] = 0 return null cachedban["reverting"] = TRUE @@ -175,6 +194,7 @@ cachedban["admin_matches_this_round"] = list() cachedban -= "reverting" world.SetConfig("ban", bannedckey, list2stickyban(cachedban)) + key_cache[key] = 0 return null //byond will not trigger isbanned() for "global" host bans, @@ -184,6 +204,7 @@ log_admin("The admin [key] has been allowed to bypass a matching host/sticky ban on [bannedckey]") message_admins("The admin [key] has been allowed to bypass a matching host/sticky ban on [bannedckey]") addclientmessage(ckey,"You have been allowed to bypass a matching host/sticky ban on [bannedckey]") + key_cache[key] = 0 return null if (C) //user is already connected!. @@ -193,6 +214,7 @@ . = list("reason" = "Stickyban", "desc" = desc) log_access("Failed Login: [key] [computer_id] [address] - StickyBanned [ban["message"]] Target Username: [bannedckey] Placed by [ban["admin"]]") + key_cache[key] = 0 return . From 5e3abec7046ebe5ae1d8b72444a96572d0eef8cd Mon Sep 17 00:00:00 2001 From: r4d6 Date: Fri, 3 Jan 2020 02:06:47 -0500 Subject: [PATCH 007/203] Removing turf with RCD cost mats. Port : https://github.com/tgstation/tgstation/pull/46801 --- code/game/turfs/simulated/floor.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/turfs/simulated/floor.dm b/code/game/turfs/simulated/floor.dm index d14a4c7385..60ac502c52 100644 --- a/code/game/turfs/simulated/floor.dm +++ b/code/game/turfs/simulated/floor.dm @@ -267,7 +267,7 @@ A.autoclose = TRUE return TRUE if(RCD_DECONSTRUCT) - if(ScrapeAway() == src) + if(!ScrapeAway(flags = CHANGETURF_INHERIT_AIR)) return FALSE to_chat(user, "You deconstruct [src].") return TRUE From 37d50e2aafd3c2e041e89d85fb1384660de5d44a Mon Sep 17 00:00:00 2001 From: r4d6 Date: Fri, 3 Jan 2020 02:13:20 -0500 Subject: [PATCH 008/203] Add RCD effects Port : https://github.com/tgstation/tgstation/pull/47894 & https://github.com/tgstation/tgstation/pull/48362/files --- .../temporary_visuals/miscellaneous.dm | 42 +++++++++++++++++- code/game/objects/items/RCD.dm | 6 ++- icons/effects/effects_rcd.dmi | Bin 0 -> 22425 bytes 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 icons/effects/effects_rcd.dmi diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 1b85a41f7c..2f18fa0ecb 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -452,4 +452,44 @@ icon_state = "slugboom" randomdir = FALSE duration = 30 - pixel_x = -24 \ No newline at end of file + pixel_x = -24 + +/obj/effect/constructing_effect + icon = 'icons/effects/effects_rcd.dmi' + icon_state = "" + layer = ABOVE_ALL_MOB_LAYER + anchored = TRUE + var/status = 0 + var/delay = 0 + +/obj/effect/constructing_effect/Initialize(mapload, rcd_delay, rcd_status) + . = ..() + status = rcd_status + delay = rcd_delay + if (status == RCD_DECONSTRUCT) + addtimer(CALLBACK(src, /atom/.proc/update_icon), 11) + delay -= 11 + icon_state = "rcd_end_reverse" + else + update_icon() + +/obj/effect/constructing_effect/update_icon() + icon_state = "rcd" + if (delay < 10) + icon_state += "_shortest" + else if (delay < 20) + icon_state += "_shorter" + else if (delay < 37) + icon_state += "_short" + if (status == RCD_DECONSTRUCT) + icon_state += "_reverse" + +/obj/effect/constructing_effect/proc/end_animation() + if (status == RCD_DECONSTRUCT) + qdel(src) + else + icon_state = "rcd_end" + addtimer(CALLBACK(src, .proc/end), 15) + +/obj/effect/constructing_effect/proc/end() + qdel(src) \ No newline at end of file diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index 24c241aabc..c21c975f1a 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -439,18 +439,22 @@ RLD var/list/rcd_results = A.rcd_vals(user, src) if(!rcd_results) return FALSE + var/delay = rcd_results["delay"] * delay_mod + var/obj/effect/constructing_effect/rcd_effect = new(get_turf(A), delay, src.mode) var/turf/the_turf = get_turf(A) var/turf_coords = "[COORD(the_turf)]" investigate_log("[user] is attempting to use [src] on [A] (loc [turf_coords] at [the_turf]) with cost [rcd_results["cost"]], delay [rcd_results["delay"]], mode [rcd_results["mode"]].", INVESTIGATE_RCD) - if(do_after(user, rcd_results["delay"] * delay_mod, target = A)) + if(do_after(user, delay, target = A)) if(checkResource(rcd_results["cost"], user)) var/atom/cached = A if(A.rcd_act(user, src, rcd_results["mode"])) + rcd_effect.end_animation() useResource(rcd_results["cost"], user) activate() investigate_log("[user] used [src] on [cached] (loc [turf_coords] at [the_turf]) with cost [rcd_results["cost"]], delay [rcd_results["delay"]], mode [rcd_results["mode"]].", INVESTIGATE_RCD) playsound(src, 'sound/machines/click.ogg', 50, 1) return TRUE + qdel(rcd_effect) /obj/item/construction/rcd/Initialize() . = ..() diff --git a/icons/effects/effects_rcd.dmi b/icons/effects/effects_rcd.dmi new file mode 100644 index 0000000000000000000000000000000000000000..efb13bfb11a15a8d03bb24d5da9c89e3d2f59de2 GIT binary patch literal 22425 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 Rf=gm{eH-9+f5-9c{{u)XGM)ec literal 0 HcmV?d00001 From 15d79d8818fafdbf33b472789ec2679a9f2d5269 Mon Sep 17 00:00:00 2001 From: r4d6 Date: Fri, 3 Jan 2020 02:14:41 -0500 Subject: [PATCH 009/203] RCD don't work on R-Doors Port : https://github.com/tgstation/tgstation/pull/43598 --- code/game/machinery/doors/airlock.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 52b52eb288..7f953052f5 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1408,6 +1408,9 @@ /obj/machinery/door/airlock/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) switch(the_rcd.mode) if(RCD_DECONSTRUCT) + if(security_level != AIRLOCK_SECURITY_NONE) + to_chat(user, "[src]'s reinforcement needs to be removed first.") + return FALSE return list("mode" = RCD_DECONSTRUCT, "delay" = 50, "cost" = 32) return FALSE From 031f485e4dd8b95012d0c79a3907db80e3929761 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Thu, 2 Jan 2020 23:24:47 -0800 Subject: [PATCH 010/203] updates --- code/__DEFINES/callbacks.dm | 3 +- code/__DEFINES/qdel.dm | 10 +- code/__HELPERS/unsorted.dm | 31 ++++ code/controllers/master.dm | 7 +- code/controllers/subsystem/server_maint.dm | 28 +++- code/controllers/subsystem/timer.dm | 51 ++++++- code/datums/callback.dm | 161 +++++++++++++-------- 7 files changed, 213 insertions(+), 78 deletions(-) diff --git a/code/__DEFINES/callbacks.dm b/code/__DEFINES/callbacks.dm index 126ef1ea1c..f25dfdf150 100644 --- a/code/__DEFINES/callbacks.dm +++ b/code/__DEFINES/callbacks.dm @@ -1,4 +1,5 @@ #define GLOBAL_PROC "some_magic_bullshit" - +/// A shorthand for the callback datum, [documented here](datum/callback.html) #define CALLBACK new /datum/callback #define INVOKE_ASYNC world.ImmediateInvokeAsync +#define CALLBACK_NEW(typepath, args) CALLBACK(GLOBAL_PROC, /proc/___callbacknew, typepath, args) diff --git a/code/__DEFINES/qdel.dm b/code/__DEFINES/qdel.dm index 71dbf82734..4296e3c2e9 100644 --- a/code/__DEFINES/qdel.dm +++ b/code/__DEFINES/qdel.dm @@ -11,14 +11,12 @@ #define QDEL_HINT_IFFAIL_FINDREFERENCE 6 //Above but only if gc fails. //defines for the gc_destroyed var -#define GC_QUEUE_PREQUEUE 1 -#define GC_QUEUE_CHECK 2 -#define GC_QUEUE_HARDDELETE 3 -#define GC_QUEUE_COUNT 3 //increase this when adding more steps. +#define GC_QUEUE_CHECK 1 +#define GC_QUEUE_HARDDELETE 2 +#define GC_QUEUE_COUNT 2 //increase this when adding more steps. #define GC_QUEUED_FOR_QUEUING -1 -#define GC_QUEUED_FOR_HARD_DEL -2 -#define GC_CURRENTLY_BEING_QDELETED -3 +#define GC_CURRENTLY_BEING_QDELETED -2 #define QDELING(X) (X.gc_destroyed) #define QDELETED(X) (!X || QDELING(X)) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 74c32dd52f..e64ed8fd55 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1452,6 +1452,37 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) else D.vars[var_name] = var_value +#define TRAIT_CALLBACK_ADD(target, trait, source) CALLBACK(GLOBAL_PROC, /proc/___TraitAdd, ##target, ##trait, ##source) +#define TRAIT_CALLBACK_REMOVE(target, trait, source) CALLBACK(GLOBAL_PROC, /proc/___TraitRemove, ##target, ##trait, ##source) + +///DO NOT USE ___TraitAdd OR ___TraitRemove as a replacement for ADD_TRAIT / REMOVE_TRAIT defines. To be used explicitly for callback. +/proc/___TraitAdd(target,trait,source) + if(!target || !trait || !source) + return + if(islist(target)) + for(var/i in target) + if(!isatom(i)) + continue + var/atom/the_atom = i + ADD_TRAIT(the_atom,trait,source) + else if(isatom(target)) + var/atom/the_atom2 = target + ADD_TRAIT(the_atom2,trait,source) + +///DO NOT USE ___TraitAdd OR ___TraitRemove as a replacement for ADD_TRAIT / REMOVE_TRAIT defines. To be used explicitly for callback. +/proc/___TraitRemove(target,trait,source) + if(!target || !trait || !source) + return + if(islist(target)) + for(var/i in target) + if(!isatom(i)) + continue + var/atom/the_atom = i + REMOVE_TRAIT(the_atom,trait,source) + else if(isatom(target)) + var/atom/the_atom2 = target + REMOVE_TRAIT(the_atom2,trait,source) + /proc/get_random_food() var/list/blocked = list(/obj/item/reagent_containers/food/snacks, /obj/item/reagent_containers/food/snacks/store/bread, diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 125da84a30..8772fac5af 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -8,6 +8,7 @@ **/ //This is the ABSOLUTE ONLY THING that should init globally like this +//2019 update: the failsafe,config and Global controllers also do it GLOBAL_REAL(Master, /datum/controller/master) = new //THIS IS THE INIT ORDER @@ -54,7 +55,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new var/static/restart_clear = 0 var/static/restart_timeout = 0 var/static/restart_count = 0 - + var/static/random_seed //current tick limit, assigned before running a subsystem. @@ -69,7 +70,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new if(!random_seed) random_seed = (TEST_RUN_PARAMETER in world.params) ? 29051994 : rand(1, 1e9) rand_seed(random_seed) - + var/list/_subsystems = list() subsystems = _subsystems if (Master != src) @@ -614,4 +615,4 @@ GLOBAL_REAL(Master, /datum/controller/master) = new if (client_count < CONFIG_GET(number/mc_tick_rate/disable_high_pop_mc_mode_amount)) processing = CONFIG_GET(number/mc_tick_rate/base_mc_tick_rate) else if (client_count > CONFIG_GET(number/mc_tick_rate/high_pop_mc_mode_amount)) - processing = CONFIG_GET(number/mc_tick_rate/high_pop_mc_tick_rate) \ No newline at end of file + processing = CONFIG_GET(number/mc_tick_rate/high_pop_mc_tick_rate) diff --git a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm index 15d3e17d29..9e926b29a1 100644 --- a/code/controllers/subsystem/server_maint.dm +++ b/code/controllers/subsystem/server_maint.dm @@ -8,6 +8,10 @@ SUBSYSTEM_DEF(server_maint) init_order = INIT_ORDER_SERVER_MAINT runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT var/list/currentrun + var/cleanup_ticker = 0 + +/datum/controller/subsystem/server_maint/PreInit() + world.hub_password = "" //quickly! before the hubbies see us. /datum/controller/subsystem/server_maint/Initialize(timeofday) if (CONFIG_GET(flag/hub)) @@ -18,10 +22,30 @@ SUBSYSTEM_DEF(server_maint) if(!resumed) if(listclearnulls(GLOB.clients)) log_world("Found a null in clients list!") - if(listclearnulls(GLOB.player_list)) - log_world("Found a null in player list!") src.currentrun = GLOB.clients.Copy() + switch (cleanup_ticker) // do only one of these at a time, once per 5 fires + if (0) + if(listclearnulls(GLOB.player_list)) + log_world("Found a null in player_list!") + cleanup_ticker++ + if (5) + if(listclearnulls(GLOB.mob_list)) + log_world("Found a null in mob_list!") + cleanup_ticker++ + if (10) + if(listclearnulls(GLOB.alive_mob_list)) + log_world("Found a null in alive_mob_list!") + cleanup_ticker++ + if (15) + if(listclearnulls(GLOB.dead_mob_list)) + log_world("Found a null in dead_mob_list!") + cleanup_ticker++ + if (20) + cleanup_ticker = 0 + else + cleanup_ticker++ + var/list/currentrun = src.currentrun var/round_started = SSticker.HasRoundStarted() diff --git a/code/controllers/subsystem/timer.dm b/code/controllers/subsystem/timer.dm index d0eb0b9ce2..bd2fb854af 100644 --- a/code/controllers/subsystem/timer.dm +++ b/code/controllers/subsystem/timer.dm @@ -1,5 +1,5 @@ #define BUCKET_LEN (world.fps*1*60) //how many ticks should we keep in the bucket. (1 minutes worth) -#define BUCKET_POS(timer) ((round((timer.timeToRun - SStimer.head_offset) / world.tick_lag) % BUCKET_LEN)||BUCKET_LEN) +#define BUCKET_POS(timer) (((round((timer.timeToRun - SStimer.head_offset) / world.tick_lag)+1) % BUCKET_LEN)||BUCKET_LEN) #define TIMER_MAX (world.time + TICKS2DS(min(BUCKET_LEN-(SStimer.practical_offset-DS2TICKS(world.time - SStimer.head_offset))-1, BUCKET_LEN-1))) #define TIMER_ID_MAX (2**24) //max float with integer precision @@ -38,15 +38,15 @@ SUBSYSTEM_DEF(timer) /datum/controller/subsystem/timer/fire(resumed = FALSE) var/lit = last_invoke_tick - var/last_check = world.time - TIMER_NO_INVOKE_WARNING + var/last_check = world.time - TICKS2DS(BUCKET_LEN*1.5) var/list/bucket_list = src.bucket_list if(!bucket_count) last_invoke_tick = world.time - if(lit && lit < last_check && last_invoke_warning < last_check) + if(lit && lit < last_check && head_offset < last_check && last_invoke_warning < last_check) last_invoke_warning = world.time - var/msg = "No regular timers processed in the last [TIMER_NO_INVOKE_WARNING] ticks[bucket_auto_reset ? ", resetting buckets" : ""]!" + var/msg = "No regular timers processed in the last [BUCKET_LEN*1.5] ticks[bucket_auto_reset ? ", resetting buckets" : ""]!" message_admins(msg) WARNING(msg) if(bucket_auto_reset) @@ -121,7 +121,7 @@ SUBSYSTEM_DEF(timer) if (!resumed) timer = null - while (practical_offset <= BUCKET_LEN && head_offset + (practical_offset*world.tick_lag) <= world.time) + while (practical_offset <= BUCKET_LEN && head_offset + ((practical_offset-1)*world.tick_lag) <= world.time) var/datum/timedevent/head = bucket_list[practical_offset] if (!timer || !head || timer == head) head = bucket_list[practical_offset] @@ -159,7 +159,7 @@ SUBSYSTEM_DEF(timer) if (timer.timeToRun < head_offset) bucket_resolution = null //force bucket recreation - CRASH("[i] Invalid timer state: Timer in long run queue with a time to run less then head_offset. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]") + stack_trace("[i] Invalid timer state: Timer in long run queue with a time to run less then head_offset. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]") if (timer.callBack && !timer.spent) timer.callBack.InvokeAsync() @@ -169,9 +169,9 @@ SUBSYSTEM_DEF(timer) qdel(timer) continue - if (timer.timeToRun < head_offset + TICKS2DS(practical_offset)) + if (timer.timeToRun < head_offset + TICKS2DS(practical_offset-1)) bucket_resolution = null //force bucket recreation - CRASH("[i] Invalid timer state: Timer in long run queue that would require a backtrack to transfer to short run queue. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]") + stack_trace("[i] Invalid timer state: Timer in long run queue that would require a backtrack to transfer to short run queue. [get_timer_debug_string(timer)] world.time: [world.time], head_offset: [head_offset], practical_offset: [practical_offset]") if (timer.callBack && !timer.spent) timer.callBack.InvokeAsync() spent += timer @@ -447,6 +447,7 @@ SUBSYSTEM_DEF(timer) next.prev = src prev.next = src +///Returns a string of the type of the callback for this timer /datum/timedevent/proc/getcallingtype() . = "ERROR" if (callBack.object == GLOBAL_PROC) @@ -454,6 +455,14 @@ SUBSYSTEM_DEF(timer) else . = "[callBack.object.type]" +/** + * Create a new timer and insert it in the queue + * + * Arguments: + * * callback the callback to call on timer finish + * * wait deciseconds to run the timer for + * * flags flags for this timer, see: code\__DEFINES\subsystems.dm + */ /proc/addtimer(datum/callback/callback, wait = 0, flags = 0) if (!callback) CRASH("addtimer called without a callback") @@ -498,6 +507,12 @@ SUBSYSTEM_DEF(timer) var/datum/timedevent/timer = new(callback, wait, flags, hash) return timer.id +/** + * Delete a timer + * + * Arguments: + * * id a timerid or a /datum/timedevent + */ /proc/deltimer(id) if (!id) return FALSE @@ -514,6 +529,26 @@ SUBSYSTEM_DEF(timer) return TRUE return FALSE +/** + * Get the remaining deciseconds on a timer + * + * Arguments: + * * id a timerid or a /datum/timedevent + */ +/proc/timeleft(id) + if (!id) + return null + if (id == TIMER_ID_NULL) + CRASH("Tried to get timeleft of a null timerid. Use TIMER_STOPPABLE flag") + if (!istext(id)) + if (istype(id, /datum/timedevent)) + var/datum/timedevent/timer = id + return timer.timeToRun - world.time + //id is string + var/datum/timedevent/timer = SStimer.timer_id_dict[id] + if (timer && !timer.spent) + return timer.timeToRun - world.time + return null #undef BUCKET_LEN #undef BUCKET_POS diff --git a/code/datums/callback.dm b/code/datums/callback.dm index 1a26052cc9..62e10922f3 100644 --- a/code/datums/callback.dm +++ b/code/datums/callback.dm @@ -1,55 +1,72 @@ -/* - USAGE: - - var/datum/callback/C = new(object|null, /proc/type/path|"procstring", arg1, arg2, ... argn) - var/timerid = addtimer(C, time, timertype) - OR - var/timerid = addtimer(CALLBACK(object|null, /proc/type/path|procstring, arg1, arg2, ... argn), time, timertype) - - Note: proc strings can only be given for datum proc calls, global procs must be proc paths - Also proc strings are strongly advised against because they don't compile error if the proc stops existing - See the note on proc typepath shortcuts - - INVOKING THE CALLBACK: - var/result = C.Invoke(args, to, add) //additional args are added after the ones given when the callback was created - OR - var/result = C.InvokeAsync(args, to, add) //Sleeps will not block, returns . on the first sleep (then continues on in the "background" after the sleep/block ends), otherwise operates normally. - OR - INVOKE_ASYNC() to immediately create and call InvokeAsync - - PROC TYPEPATH SHORTCUTS (these operate on paths, not types, so to these shortcuts, datum is NOT a parent of atom, etc...) - - global proc while in another global proc: - .procname - Example: - CALLBACK(GLOBAL_PROC, .some_proc_here) - - proc defined on current(src) object (when in a /proc/ and not an override) OR overridden at src or any of it's parents: - .procname - Example: - CALLBACK(src, .some_proc_here) - - - when the above doesn't apply: - .proc/procname - Example: - CALLBACK(src, .proc/some_proc_here) - - proc defined on a parent of a some type: - /some/type/.proc/some_proc_here - - - - Other wise you will have to do the full typepath of the proc (/type/of/thing/proc/procname) - -*/ - +/** + *# Callback Datums + *A datum that holds a proc to be called on another object, used to track proccalls to other objects + * + * ## USAGE + * + * ``` + * var/datum/callback/C = new(object|null, /proc/type/path|"procstring", arg1, arg2, ... argn) + * var/timerid = addtimer(C, time, timertype) + * you can also use the compiler define shorthand + * var/timerid = addtimer(CALLBACK(object|null, /proc/type/path|procstring, arg1, arg2, ... argn), time, timertype) + * ``` + * + * Note: proc strings can only be given for datum proc calls, global procs must be proc paths + * + * Also proc strings are strongly advised against because they don't compile error if the proc stops existing + * + * In some cases you can provide a shortform of the procname, see the proc typepath shortcuts documentation below + * + * ## INVOKING THE CALLBACK + *`var/result = C.Invoke(args, to, add)` additional args are added after the ones given when the callback was created + * + * `var/result = C.InvokeAsync(args, to, add)` Asyncronous - returns . on the first sleep then continues on in the background + * after the sleep/block ends, otherwise operates normally. + * + * ## PROC TYPEPATH SHORTCUTS + * (these operate on paths, not types, so to these shortcuts, datum is NOT a parent of atom, etc...) + * + * ### global proc while in another global proc: + * .procname + * + * `CALLBACK(GLOBAL_PROC, .some_proc_here)` + * + * ### proc defined on current(src) object (when in a /proc/ and not an override) OR overridden at src or any of it's parents: + * .procname + * + * `CALLBACK(src, .some_proc_here)` + * + * ### when the above doesn't apply: + *.proc/procname + * + * `CALLBACK(src, .proc/some_proc_here)` + * + * + * proc defined on a parent of a some type + * + * `/some/type/.proc/some_proc_here` + * + * Otherwise you must always provide the full typepath of the proc (/type/of/thing/proc/procname) + */ /datum/callback + + ///The object we will be calling the proc on var/datum/object = GLOBAL_PROC + ///The proc we will be calling on the object var/delegate + ///A list of arguments to pass into the proc var/list/arguments + ///A weak reference to the user who triggered this callback var/datum/weakref/user +/** + * Create a new callback datum + * + * Arguments + * * thingtocall the object to call the proc on + * * proctocall the proc to call on the target object + * * ... an optional list of extra arguments to pass to the proc + */ /datum/callback/New(thingtocall, proctocall, ...) if (thingtocall) object = thingtocall @@ -58,7 +75,14 @@ arguments = args.Copy(3) if(usr) user = WEAKREF(usr) - +/** + * Immediately Invoke proctocall on thingtocall, with waitfor set to false + * + * Arguments: + * * thingtocall Object to call on + * * proctocall Proc to call on that object + * * ... optional list of arguments to pass as arguments to the proc being called + */ /world/proc/ImmediateInvokeAsync(thingtocall, proctocall, ...) set waitfor = FALSE @@ -72,6 +96,14 @@ else call(thingtocall, proctocall)(arglist(calling_arguments)) +/** + * Invoke this callback + * + * Calls the registered proc on the registered object, if the user ref + * can be resolved it also inclues that as an arg + * + * If the datum being called on is varedited, the call is wrapped via WrapAdminProcCall + */ /datum/callback/proc/Invoke(...) if(!usr) var/datum/weakref/W = user @@ -97,7 +129,14 @@ return call(delegate)(arglist(calling_arguments)) return call(object, delegate)(arglist(calling_arguments)) -//copy and pasted because fuck proc overhead +/** + * Invoke this callback async (waitfor=false) + * + * Calls the registered proc on the registered object, if the user ref + * can be resolved it also inclues that as an arg + * + * If the datum being called on is varedited, the call is wrapped via WrapAdminProcCall + */ /datum/callback/proc/InvokeAsync(...) set waitfor = FALSE @@ -125,7 +164,9 @@ return call(delegate)(arglist(calling_arguments)) return call(object, delegate)(arglist(calling_arguments)) - +/** + Helper datum for the select callbacks proc + */ /datum/callback_select var/list/finished var/pendingcount @@ -150,15 +191,17 @@ if (savereturn) finished[index] = rtn - - - -//runs a list of callbacks asynchronously, returning once all of them return. -//callbacks can be repeated. -//callbacks-args is an optional list of argument lists, in the same order as the callbacks, -// the inner lists will be sent to the callbacks when invoked() as additional args. -//can optionly save and return a list of return values, in the same order as the original list of callbacks -//resolution is the number of byond ticks between checks. +/** + * Runs a list of callbacks asyncronously, returning only when all have finished + * + * Callbacks can be repeated, to call it multiple times + * + * Arguments: + * * list/callbacks the list of callbacks to be called + * * list/callback_args the list of lists of arguments to pass into each callback + * * savereturns Optionally save and return the list of returned values from each of the callbacks + * * resolution The number of byond ticks between each time you check if all callbacks are complete + */ /proc/callback_select(list/callbacks, list/callback_args, savereturns = TRUE, resolution = 1) if (!callbacks) return @@ -178,3 +221,5 @@ sleep(resolution*world.tick_lag) return CS.finished +/proc/___callbacknew(typepath, arguments) + new typepath(arglist(arguments)) From 5c94e02eac37cd3e5edd027ebb2593ff835c4b29 Mon Sep 17 00:00:00 2001 From: r4d6 Date: Fri, 3 Jan 2020 02:32:43 -0500 Subject: [PATCH 011/203] Add simple RCD Circuits Port : https://github.com/tgstation/tgstation/pull/45357 --- code/__DEFINES/construction.dm | 5 +- code/game/machinery/doors/firedoor.dm | 15 ++++++ code/game/machinery/firealarm.dm | 14 ++++++ code/game/objects/items/RCD.dm | 25 +++++++--- .../atmospherics/machinery/airalarm.dm | 15 ++++++ code/modules/power/apc.dm | 46 +++++++++++++++++++ code/modules/research/designs/misc_designs.dm | 18 ++++++-- code/modules/research/techweb/all_nodes.dm | 2 +- 8 files changed, 127 insertions(+), 13 deletions(-) diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm index c394d003d8..c93f1b2435 100644 --- a/code/__DEFINES/construction.dm +++ b/code/__DEFINES/construction.dm @@ -110,4 +110,7 @@ #define RCD_DECONSTRUCT 3 #define RCD_WINDOWGRILLE 4 #define RCD_MACHINE 8 -#define RCD_COMPUTER 16 \ No newline at end of file +#define RCD_COMPUTER 16 + +#define RCD_UPGRADE_FRAMES 1 +#define RCD_UPGRADE_SIMPLE_CIRCUITS 2 \ No newline at end of file diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index dec41b0a59..39b6c8da1d 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -450,6 +450,21 @@ return return ..() +/obj/structure/firelock_frame/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) + if((constructionStep == CONSTRUCTION_NOCIRCUIT) && (the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS)) + return list("mode" = RCD_UPGRADE_SIMPLE_CIRCUITS, "delay" = 20, "cost" = 1) + return FALSE + +/obj/structure/firelock_frame/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_UPGRADE_SIMPLE_CIRCUITS) + user.visible_message("[user] fabricates a circuit and places it into [src].", \ + "You adapt a firelock circuit and slot it into the assembly.") + constructionStep = CONSTRUCTION_GUTTED + update_icon() + return TRUE + return FALSE + /obj/structure/firelock_frame/heavy name = "heavy firelock frame" reinforced = TRUE diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 71f39608b5..51cd9de2d1 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -256,6 +256,20 @@ return return ..() +/obj/machinery/firealarm/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) + if((buildstage == 0) && (the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS)) + return list("mode" = RCD_UPGRADE_SIMPLE_CIRCUITS, "delay" = 20, "cost" = 1) + return FALSE + +/obj/machinery/firealarm/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_UPGRADE_SIMPLE_CIRCUITS) + user.visible_message("[user] fabricates a circuit and places it into [src].", \ + "You adapt a fire alarm circuit and slot it into the assembly.") + buildstage = 1 + update_icon() + return TRUE + return FALSE /obj/machinery/firealarm/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) . = ..() diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index c21c975f1a..b4f0f1459a 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -85,9 +85,11 @@ RLD to_chat(user, "[src] now holds [matter]/[max_matter] matter-units.") else if(istype(W, /obj/item/rcd_upgrade)) to_chat(user, "You upgrade the RCD with the [W]!") - upgrade = TRUE - playsound(src.loc, 'sound/machines/click.ogg', 50, 1) - qdel(W) + var/obj/item/rcd_upgrade/rcd_up = W + if(!(upgrade & rcd_up.upgrade)) + upgrade |= rcd_up.upgrade + playsound(src.loc, 'sound/machines/click.ogg', 50, 1) + qdel(W) else return ..() update_icon() //ensures that ammo counters (if present) get updated @@ -116,10 +118,10 @@ RLD if(matter < amount) if(user) to_chat(user, no_ammo_message) - return 0 + return FALSE matter -= amount update_icon() - return 1 + return TRUE /obj/item/construction/proc/checkResource(amount, mob/user) . = matter >= amount @@ -471,7 +473,7 @@ RLD "Grilles & Windows" = image(icon = 'icons/mob/radial.dmi', icon_state = "grillewindow"), "Floors & Walls" = image(icon = 'icons/mob/radial.dmi', icon_state = "wallfloor") ) - if(upgrade) + if(upgrade & RCD_UPGRADE_FRAMES) choices += list( "Deconstruct" = image(icon= 'icons/mob/radial.dmi', icon_state = "delete"), "Machine Frames" = image(icon = 'icons/mob/radial.dmi', icon_state = "machine"), @@ -829,9 +831,18 @@ RLD /obj/item/rcd_upgrade name = "RCD advanced design disk" - desc = "It contains the design for machine frames, computer frames, and deconstruction." + desc = "It seems to be empty." icon = 'icons/obj/module.dmi' icon_state = "datadisk3" + var/upgrade + +/obj/item/rcd_upgrade/frames + desc = "It contains the design for machine frames, computer frames and deconstruction." + upgrade = RCD_UPGRADE_FRAMES + +/obj/item/rcd_upgrade/simple_circuits + desc = "It contains the design for firelock, air alarm, fire alarm, apc circuits and crap power cells." + upgrade = RCD_UPGRADE_SIMPLE_CIRCUITS #undef GLOW_MODE #undef LIGHT_MODE diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index cbbfc05f39..e49368016b 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -822,6 +822,21 @@ return ..() +/obj/machinery/airalarm/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) + if((buildstage == 0) && (the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS)) + return list("mode" = RCD_UPGRADE_SIMPLE_CIRCUITS, "delay" = 20, "cost" = 1) + return FALSE + +/obj/machinery/airalarm/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_UPGRADE_SIMPLE_CIRCUITS) + user.visible_message("[user] fabricates a circuit and places it into [src].", \ + "You adapt an air alarm circuit and slot it into the assembly.") + buildstage = 1 + update_icon() + return TRUE + return FALSE + /obj/machinery/airalarm/AltClick(mob/user) . = ..() if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc)) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 2652026a11..0ad2983b91 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -701,6 +701,52 @@ else return ..() +/obj/machinery/power/apc/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) + if(the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS) + if(!has_electronics) + if(stat & BROKEN) + to_chat(user, "[src]'s frame is too damaged to support a circuit.") + return FALSE + return list("mode" = RCD_UPGRADE_SIMPLE_CIRCUITS, "delay" = 20, "cost" = 1) + else if(!cell) + if(stat & MAINT) + to_chat(user, "There's no connector for a power cell.") + return FALSE + return list("mode" = RCD_UPGRADE_SIMPLE_CIRCUITS, "delay" = 50, "cost" = 10) //16 for a wall + else + to_chat(user, "[src] has both electronics and a cell.") + return FALSE + return FALSE + +/obj/machinery/power/apc/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_UPGRADE_SIMPLE_CIRCUITS) + if(!has_electronics) + if(stat & BROKEN) + to_chat(user, "[src]'s frame is too damaged to support a circuit.") + return + user.visible_message("[user] fabricates a circuit and places it into [src].", \ + "You adapt a power control board and click it into place in [src]'s guts.") + has_electronics = TRUE + locked = TRUE + return TRUE + else if(!cell) + if(stat & MAINT) + to_chat(user, "There's no connector for a power cell.") + return FALSE + var/obj/item/stock_parts/cell/crap/empty/C = new(src) + C.forceMove(src) + cell = C + chargecount = 0 + user.visible_message("[user] fabricates a weak power cell and places it into [src].", \ + "Your [the_rcd.name] whirrs with strain as you create a weak power cell and place it into [src]!") + update_icon() + return TRUE + else + to_chat(user, "[src] has both electronics and a cell.") + return FALSE + return FALSE + /obj/machinery/power/apc/AltClick(mob/user) . = ..() if(!user.canUseTopic(src, !issilicon(user)) || !isturf(loc)) diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index 5f7648b245..eeac6a5818 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -379,13 +379,23 @@ ////////////Tools////////////// /////////////////////////////// -/datum/design/rcd_upgrade - name = "Advanced RCD designs upgrade" +/datum/design/rcd_upgrade/frames + name = "RCD frames designs upgrade" desc = "Adds the computer frame and machine frame to the RCD." - id = "rcd_upgrade" + id = "rcd_upgrade_frames" build_type = PROTOLATHE materials = list(MAT_METAL = 5000, MAT_GLASS = 2500, MAT_SILVER = 1500, MAT_TITANIUM = 2000) - build_path = /obj/item/rcd_upgrade + build_path = /obj/item/rcd_upgrade/frames + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/rcd_upgrade/simple_circuits + name = "RCD simple circuits designs upgrade" + desc = "Adds the simple circuits to the RCD." + id = "rcd_upgrade_simple_circuits" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 5000, /datum/material/glass = 2500, /datum/material/silver = 1500, /datum/material/titanium = 2000) + build_path = /obj/item/rcd_upgrade/simple_circuits category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 5f3fc0e85e..ce32c467c9 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -200,7 +200,7 @@ display_name = "Advanced Engineering" description = "Pushing the boundaries of physics, one chainsaw-fist at a time." prereq_ids = list("engineering", "emp_basic") - design_ids = list("engine_goggles", "magboots", "forcefield_projector", "weldingmask", "tray_goggles_prescription", "engine_goggles_prescription", "mesons_prescription", "rcd_upgrade") + design_ids = list("engine_goggles", "magboots", "forcefield_projector", "weldingmask", "tray_goggles_prescription", "engine_goggles_prescription", "mesons_prescription", "rcd_upgrade_frames", "rcd_upgrade_simple_circuits") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 4000) export_price = 5000 From 58a986696f6e33c7600c3a9204ad004aa6def2b1 Mon Sep 17 00:00:00 2001 From: r4d6 Date: Fri, 3 Jan 2020 02:46:25 -0500 Subject: [PATCH 012/203] Add RCD and RPD to Engie's protolathe Half-port with bonus : https://github.com/tgstation/tgstation/pull/47289 --- code/modules/research/designs/misc_designs.dm | 20 +++++++++++++++++++ code/modules/research/techweb/all_nodes.dm | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index eeac6a5818..5ae33a4752 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -429,6 +429,26 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING +/datum/design/rcd_loaded + name = "Rapid Construction Device" + desc = "A tool that can construct and deconstruct walls, airlocks and floors on the fly." + id = "rcd_loaded" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 60000, /datum/material/glass = 5000) // costs more than what it did in the autolathe, this one comes loaded. + build_path = /obj/item/construction/rcd/loaded + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/rpd + name = "Rapid Pipe Dispenser" + desc = "A tool that can construct and deconstruct pipes on the fly." + id = "rpd" + build_type = PROTOLATHE + materials = list(/datum/material/iron = 75000, /datum/material/glass = 37500) // costs more than what it did in the autolathe, this one comes loaded. + build_path = /obj/item/construction/rcd/loaded + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + /datum/design/alienwrench name = "Alien Wrench" desc = "An advanced wrench obtained through Abductor technology." diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index ce32c467c9..1ce28c9ba9 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -200,7 +200,7 @@ display_name = "Advanced Engineering" description = "Pushing the boundaries of physics, one chainsaw-fist at a time." prereq_ids = list("engineering", "emp_basic") - design_ids = list("engine_goggles", "magboots", "forcefield_projector", "weldingmask", "tray_goggles_prescription", "engine_goggles_prescription", "mesons_prescription", "rcd_upgrade_frames", "rcd_upgrade_simple_circuits") + design_ids = list("engine_goggles", "magboots", "forcefield_projector", "weldingmask" , "rcd_loaded", "tray_goggles_prescription", "engine_goggles_prescription", "mesons_prescription", "rcd_upgrade_frames", "rcd_upgrade_simple_circuits") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 4000) export_price = 5000 From 3f5d4ad83519e8c7a2dd8e20a0c1be86792adecf Mon Sep 17 00:00:00 2001 From: r4d6 Date: Fri, 3 Jan 2020 03:13:03 -0500 Subject: [PATCH 013/203] remove a duplicate comment --- code/modules/research/designs/misc_designs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index 5ae33a4752..a75a8697fd 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -444,7 +444,7 @@ desc = "A tool that can construct and deconstruct pipes on the fly." id = "rpd" build_type = PROTOLATHE - materials = list(/datum/material/iron = 75000, /datum/material/glass = 37500) // costs more than what it did in the autolathe, this one comes loaded. + materials = list(/datum/material/iron = 75000, /datum/material/glass = 37500) build_path = /obj/item/construction/rcd/loaded category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING From aedf634355766059c1aa42a77a7cc2c872aeb778 Mon Sep 17 00:00:00 2001 From: r4d6 Date: Fri, 3 Jan 2020 03:15:30 -0500 Subject: [PATCH 014/203] Fix mats. --- code/modules/research/designs/misc_designs.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index a75a8697fd..ebc1f8a39c 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -434,7 +434,7 @@ desc = "A tool that can construct and deconstruct walls, airlocks and floors on the fly." id = "rcd_loaded" build_type = PROTOLATHE - materials = list(/datum/material/iron = 60000, /datum/material/glass = 5000) // costs more than what it did in the autolathe, this one comes loaded. + materials = list(MAT_METAL = 60000, MAT_GLASS = 5000) // costs more than what it did in the autolathe, this one comes loaded. build_path = /obj/item/construction/rcd/loaded category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING @@ -444,7 +444,7 @@ desc = "A tool that can construct and deconstruct pipes on the fly." id = "rpd" build_type = PROTOLATHE - materials = list(/datum/material/iron = 75000, /datum/material/glass = 37500) + materials = list(MAT_METAL = 75000, MAT_GLASS = 37500) build_path = /obj/item/construction/rcd/loaded category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING From 880db10033685e0d0bcc9b27aa400fb4d3593857 Mon Sep 17 00:00:00 2001 From: r4d6 Date: Fri, 3 Jan 2020 03:22:18 -0500 Subject: [PATCH 015/203] Forgot some more mats --- code/modules/research/designs/misc_designs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index ebc1f8a39c..ae19b6d053 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -394,7 +394,7 @@ desc = "Adds the simple circuits to the RCD." id = "rcd_upgrade_simple_circuits" build_type = PROTOLATHE - materials = list(/datum/material/iron = 5000, /datum/material/glass = 2500, /datum/material/silver = 1500, /datum/material/titanium = 2000) + materials = list(/AT_METAL = 5000, MAT_GLASS = 2500, MAT_SILVER = 1500, MAT_TITANIUM = 2000) build_path = /obj/item/rcd_upgrade/simple_circuits category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING From 221cb980d61a3595b7beee8ac853859037cc16fa Mon Sep 17 00:00:00 2001 From: r4d6 Date: Fri, 3 Jan 2020 03:25:53 -0500 Subject: [PATCH 016/203] forgot a / --- code/modules/research/designs/misc_designs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index ae19b6d053..a49dd76ede 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -394,7 +394,7 @@ desc = "Adds the simple circuits to the RCD." id = "rcd_upgrade_simple_circuits" build_type = PROTOLATHE - materials = list(/AT_METAL = 5000, MAT_GLASS = 2500, MAT_SILVER = 1500, MAT_TITANIUM = 2000) + materials = list(AT_METAL = 5000, MAT_GLASS = 2500, MAT_SILVER = 1500, MAT_TITANIUM = 2000) build_path = /obj/item/rcd_upgrade/simple_circuits category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING From 62ea644dd0155fba3c05a22f9c24c39cbba46f15 Mon Sep 17 00:00:00 2001 From: r4d6 Date: Fri, 3 Jan 2020 16:26:53 -0500 Subject: [PATCH 017/203] ugh, make rcds that are able to remove r-wall be able to remvoe r-doors too. THERE I DID GRAY YOU CAN NOW SHUT UP!! --- code/game/machinery/doors/airlock.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 6959ab971c..3e88223037 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1408,7 +1408,7 @@ /obj/machinery/door/airlock/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) switch(the_rcd.mode) if(RCD_DECONSTRUCT) - if(security_level != AIRLOCK_SECURITY_NONE) + if(security_level != AIRLOCK_SECURITY_NONE && the_rcd.canRturf != TRUE) to_chat(user, "[src]'s reinforcement needs to be removed first.") return FALSE return list("mode" = RCD_DECONSTRUCT, "delay" = 50, "cost" = 32) From 4e528da5c283fa00367b809a3010268fee970dfe Mon Sep 17 00:00:00 2001 From: r4d6 Date: Sat, 4 Jan 2020 19:06:56 -0500 Subject: [PATCH 018/203] Correct price and rpd --- code/game/objects/items/RCD.dm | 1 + code/modules/research/designs/misc_designs.dm | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index b4f0f1459a..420f5467d8 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -599,6 +599,7 @@ RLD energyfactor = 66 /obj/item/construction/rcd/loaded + materials = list(MAT_METAL=48000, MAT_GLASS=32000) matter = 160 /obj/item/construction/rcd/loaded/upgraded diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index a49dd76ede..198f06ed3f 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -434,7 +434,7 @@ desc = "A tool that can construct and deconstruct walls, airlocks and floors on the fly." id = "rcd_loaded" build_type = PROTOLATHE - materials = list(MAT_METAL = 60000, MAT_GLASS = 5000) // costs more than what it did in the autolathe, this one comes loaded. + materials = list(MAT_METAL = MINERAL_MATERIAL_AMOUNT, MAT_GLASS = MINERAL_MATERIAL_AMOUNT) // costs more than what it did in the autolathe, this one comes loaded. build_path = /obj/item/construction/rcd/loaded category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING @@ -445,7 +445,7 @@ id = "rpd" build_type = PROTOLATHE materials = list(MAT_METAL = 75000, MAT_GLASS = 37500) - build_path = /obj/item/construction/rcd/loaded + build_path = /obj/item/pipe_dispenser category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING From 46cf029a2823871e647f4f5600882e6cd88cf795 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Sun, 5 Jan 2020 11:19:18 -0800 Subject: [PATCH 019/203] Update twohanded.dm --- code/game/objects/items/twohanded.dm | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm index d7891feaa0..a81a45d6e4 100644 --- a/code/game/objects/items/twohanded.dm +++ b/code/game/objects/items/twohanded.dm @@ -781,6 +781,9 @@ throwforce = 20 throw_speed = 4 attack_verb = list("gored") + var/clonechance = 50 + var/clonedamage = 12 + var/clonespeed = 0.5 /obj/item/twohanded/spear/grey_tide/afterattack(atom/movable/AM, mob/living/user, proximity) . = ..() @@ -791,9 +794,11 @@ var/mob/living/L = AM if(istype (L, /mob/living/simple_animal/hostile/illusion)) return - if(!L.stat && prob(50)) + if(!L.stat && prob(clonechance)) var/mob/living/simple_animal/hostile/illusion/M = new(user.loc) M.faction = user.faction.Copy() + M.melee_damage_upper = M.melee_damage_lower = clonedamage + M.set_varspeed(clonespeed) M.Copy_Parent(user, 100, user.health/2.5, 12, 30) M.GiveTarget(L) @@ -1010,4 +1015,4 @@ var/client/C = user.client C.change_view(CONFIG_GET(string/default_view)) user.client.pixel_x = 0 - user.client.pixel_y = 0 \ No newline at end of file + user.client.pixel_y = 0 From 4d151b2a7ca731992c7ad972ab5b94270a5437eb Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Sun, 5 Jan 2020 11:20:13 -0800 Subject: [PATCH 020/203] Update twohanded.dm --- code/game/objects/items/twohanded.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm index a81a45d6e4..3802b01bc4 100644 --- a/code/game/objects/items/twohanded.dm +++ b/code/game/objects/items/twohanded.dm @@ -783,7 +783,7 @@ attack_verb = list("gored") var/clonechance = 50 var/clonedamage = 12 - var/clonespeed = 0.5 + var/clonespeed = 0 /obj/item/twohanded/spear/grey_tide/afterattack(atom/movable/AM, mob/living/user, proximity) . = ..() From 1a834edd5f964b3c9842b716d02c9e9b947683ec Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sun, 5 Jan 2020 21:27:04 +0100 Subject: [PATCH 021/203] f --- .../structures/crates_lockers/closets/secure/security.dm | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) 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 058782e1ab..c671af0e5d 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -19,6 +19,7 @@ new /obj/item/clothing/under/captainparade(src) new /obj/item/clothing/suit/armor/vest/capcarapace/alt(src) new /obj/item/clothing/head/caphat/parade(src) + new /obj/item/clothing/head/caphat/beret(src) new /obj/item/clothing/suit/captunic(src) new /obj/item/clothing/under/rank/captain/femformal(src) //citadel edit new /obj/item/clothing/head/crown/fancy(src) @@ -32,10 +33,7 @@ new /obj/item/gun/energy/e_gun(src) new /obj/item/door_remote/captain(src) new /obj/item/storage/photo_album/Captain(src) - if(prob(50)) - new /obj/item/clothing/head/caphat/beret(src) - else - new /obj/item/clothing/head/caphat/beret/white(src) + new /obj/item/clothing/head/caphat/beret/white(src) /obj/structure/closet/secure_closet/hop name = "\proper head of personnel's locker" From 0f909a1437f4ea84e65a215f134dc298bae88968 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Sun, 5 Jan 2020 12:50:51 -0800 Subject: [PATCH 022/203] Update twohanded.dm --- code/game/objects/items/twohanded.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm index 3802b01bc4..3f180bdce8 100644 --- a/code/game/objects/items/twohanded.dm +++ b/code/game/objects/items/twohanded.dm @@ -784,6 +784,8 @@ var/clonechance = 50 var/clonedamage = 12 var/clonespeed = 0 + var/clone_replication_chance = 30 + var/clone_lifespan = 100 /obj/item/twohanded/spear/grey_tide/afterattack(atom/movable/AM, mob/living/user, proximity) . = ..() @@ -797,9 +799,8 @@ if(!L.stat && prob(clonechance)) var/mob/living/simple_animal/hostile/illusion/M = new(user.loc) M.faction = user.faction.Copy() - M.melee_damage_upper = M.melee_damage_lower = clonedamage M.set_varspeed(clonespeed) - M.Copy_Parent(user, 100, user.health/2.5, 12, 30) + M.Copy_Parent(user, clone_lifespan, user.health/2.5, clonedamage, clone_replication_chance) M.GiveTarget(L) /obj/item/twohanded/pitchfork From 62b85137954a8a0370be0f901293a0393015a901 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Mon, 6 Jan 2020 19:50:46 -0800 Subject: [PATCH 023/203] fix --- code/modules/admin/IsBanned.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 0dc6825cf6..09d90a32ca 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -27,11 +27,13 @@ return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided an invalid Computer ID.)") if (type == "world") + key_cache[key] = 0 return ..() //shunt world topic banchecks to purely to byond's internal ban system var/ckey = ckey(key) var/client/C = GLOB.directory[ckey] if (C && ckey == C.ckey && computer_id == C.computer_id && address == C.address) + key_cache[key] = 0 return //don't recheck connected clients. var/admin = FALSE From 2ab07fdb82a75b1cb9de7556b89562be140ef018 Mon Sep 17 00:00:00 2001 From: r4d6 Date: Mon, 6 Jan 2020 23:43:04 -0500 Subject: [PATCH 024/203] Conflict Fix part 1 --- code/game/machinery/firealarm.dm | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 51cd9de2d1..8f7fce8e3e 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -256,21 +256,6 @@ return return ..() -/obj/machinery/firealarm/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) - if((buildstage == 0) && (the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS)) - return list("mode" = RCD_UPGRADE_SIMPLE_CIRCUITS, "delay" = 20, "cost" = 1) - return FALSE - -/obj/machinery/firealarm/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - switch(passed_mode) - if(RCD_UPGRADE_SIMPLE_CIRCUITS) - user.visible_message("[user] fabricates a circuit and places it into [src].", \ - "You adapt a fire alarm circuit and slot it into the assembly.") - buildstage = 1 - update_icon() - return TRUE - return FALSE - /obj/machinery/firealarm/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) . = ..() if(.) //damage received From d7718c8dd1d883757a9cc3201ad9cf56fcfeda81 Mon Sep 17 00:00:00 2001 From: r4d6 Date: Mon, 6 Jan 2020 23:43:27 -0500 Subject: [PATCH 025/203] Revert "Conflict Fix part 1" This reverts commit 2ab07fdb82a75b1cb9de7556b89562be140ef018. --- code/game/machinery/firealarm.dm | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 8f7fce8e3e..51cd9de2d1 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -256,6 +256,21 @@ return return ..() +/obj/machinery/firealarm/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) + if((buildstage == 0) && (the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS)) + return list("mode" = RCD_UPGRADE_SIMPLE_CIRCUITS, "delay" = 20, "cost" = 1) + return FALSE + +/obj/machinery/firealarm/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_UPGRADE_SIMPLE_CIRCUITS) + user.visible_message("[user] fabricates a circuit and places it into [src].", \ + "You adapt a fire alarm circuit and slot it into the assembly.") + buildstage = 1 + update_icon() + return TRUE + return FALSE + /obj/machinery/firealarm/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) . = ..() if(.) //damage received From 20d5e4f480fc515a7ed9a4466f5eecd9e56b7ff9 Mon Sep 17 00:00:00 2001 From: r4d6 Date: Tue, 7 Jan 2020 01:45:59 -0500 Subject: [PATCH 026/203] Make the RCD show its upgrades on examination. And remove a small copy-pasta. --- code/game/objects/items/RCD.dm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index 420f5467d8..f5f489fd2e 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -47,7 +47,11 @@ RLD /obj/item/construction/examine(mob/user) . = ..() - . += "\A [src]. It currently holds [matter]/[max_matter] matter-units." + . += "\It currently holds [matter]/[max_matter] matter-units." + if(upgrade & RCD_UPGRADE_FRAMES) + . += "\It contains the design for machine frames, computer frames and deconstruction." + if(upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS) + . += "\It contains the design for firelock, air alarm, fire alarm, apc circuits and crap power cells." /obj/item/construction/Destroy() QDEL_NULL(spark_system) From 68e48209da8694fd5e743f4f2fffbc76407a97f7 Mon Sep 17 00:00:00 2001 From: r4d6 Date: Tue, 7 Jan 2020 02:04:06 -0500 Subject: [PATCH 027/203] Fix --- code/game/objects/items/RCD.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index f5f489fd2e..e151450d8a 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -47,11 +47,11 @@ RLD /obj/item/construction/examine(mob/user) . = ..() - . += "\It currently holds [matter]/[max_matter] matter-units." + . += "It currently holds [matter]/[max_matter] matter-units." if(upgrade & RCD_UPGRADE_FRAMES) - . += "\It contains the design for machine frames, computer frames and deconstruction." + . += "It contains the design for machine frames, computer frames and deconstruction." if(upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS) - . += "\It contains the design for firelock, air alarm, fire alarm, apc circuits and crap power cells." + . += "It contains the design for firelock, air alarm, fire alarm, apc circuits and crap power cells." /obj/item/construction/Destroy() QDEL_NULL(spark_system) From 6f6f0cbb6222f3d20cd1aba9daa4fcebcaef4070 Mon Sep 17 00:00:00 2001 From: Putnam Date: Mon, 6 Jan 2020 23:33:29 -0800 Subject: [PATCH 028/203] Tweaks to ghost dojo --- _maps/map_files/generic/CentCom.dmm | 18 +++++++++++++++--- .../objects/structures/ghost_role_spawners.dm | 3 ++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index 6129d263fd..735d6c72e3 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -16736,6 +16736,10 @@ smooth = 1 }, /area/centcom/holding) +"Nf" = ( +/obj/machinery/autoylathe, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "Ni" = ( /obj/structure/table/reinforced, /obj/item/clipboard, @@ -18166,6 +18170,13 @@ }, /turf/open/indestructible/hotelwood, /area/centcom/holding) +"VL" = ( +/obj/machinery/button/crematorium{ + id = crematoriumGhostDojo; + pixel_x = -25 + }, +/turf/open/indestructible/hotelwood, +/area/centcom/holding) "VO" = ( /turf/closed/indestructible/riveted, /area/centcom/supplypod) @@ -18248,7 +18259,8 @@ /area/centcom/holding) "Ww" = ( /obj/structure/bodycontainer/crematorium{ - dir = 4 + dir = 4; + id = crematoriumGhostDojo }, /turf/open/indestructible/hotelwood, /area/centcom/holding) @@ -43145,7 +43157,7 @@ CT oV CT Nd -Sd +VL Ww Sd Nd @@ -45169,7 +45181,7 @@ aa aa aa Nd -Sd +Nf Sd Rh Mm diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 705ca9a884..418884435c 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -629,7 +629,8 @@ new_spawn.AddElement(/datum/element/ghost_role_eligibility) ADD_TRAIT(new_spawn, TRAIT_SIXTHSENSE, GHOSTROLE_TRAIT) ADD_TRAIT(new_spawn,TRAIT_EXEMPT_HEALTH_EVENTS,GHOSTROLE_TRAIT) - to_chat(new_spawn,"You maybe sharing your cafe with some ninja-captured individuals, so make sure to only interact with the ghosts you hear as a ghost!") + ADD_TRAIT(new_spawn,TRAIT_PACIFISM,GHOSTROLE_TRAIT) + to_chat(new_spawn,"You may be sharing your cafe with some ninja-captured individuals, so make sure to only interact with the ghosts you hear as a ghost!") to_chat(new_spawn,"You can turn yourself into a ghost and freely reenter your body with the ghost action.") var/datum/action/ghost/G = new(new_spawn) G.Grant(new_spawn) From b5026256db7be01e70adb7d45ea7baaf7c8bd527 Mon Sep 17 00:00:00 2001 From: Putnam Date: Mon, 6 Jan 2020 23:42:27 -0800 Subject: [PATCH 029/203] aaand a few more --- _maps/map_files/generic/CentCom.dmm | 67 +++++++---------------------- 1 file changed, 15 insertions(+), 52 deletions(-) diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index 735d6c72e3..3df84a9f86 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -6418,15 +6418,6 @@ /obj/effect/turf_decal/tile/brown, /turf/open/floor/plasteel, /area/centcom/supplypod/loading/two) -"oV" = ( -/obj/machinery/vr_sleeper{ - dir = 4 - }, -/obj/machinery/light{ - dir = 8 - }, -/turf/open/indestructible/hotelwood, -/area/centcom/holding) "oX" = ( /obj/structure/bookcase/random, /obj/machinery/light{ @@ -12460,12 +12451,6 @@ }, /turf/open/floor/plasteel/dark, /area/centcom/evac) -"CT" = ( -/obj/machinery/vr_sleeper{ - dir = 4 - }, -/turf/open/indestructible/hotelwood, -/area/centcom/holding) "CV" = ( /obj/structure/chair/stool, /turf/open/indestructible/hotelwood, @@ -12658,12 +12643,6 @@ "Di" = ( /turf/closed/indestructible/riveted, /area/ai_multicam_room) -"Dj" = ( -/obj/machinery/vr_sleeper{ - dir = 8 - }, -/turf/open/indestructible/hotelwood, -/area/centcom/holding) "Dk" = ( /obj/structure/table, /turf/open/floor/plasteel/cafeteria, @@ -13266,7 +13245,7 @@ /turf/open/floor/engine/cult, /area/wizard_station) "ED" = ( -/obj/machinery/vending/boozeomat, +/obj/machinery/vending/boozeomat/all_access, /turf/closed/indestructible{ icon = 'icons/turf/walls/wood_wall.dmi'; icon_state = "wood"; @@ -16804,13 +16783,6 @@ /obj/machinery/recharge_station, /turf/open/floor/plasteel/white, /area/centcom/holding) -"Ny" = ( -/obj/machinery/modular_computer/console/preset/research, -/obj/machinery/light{ - dir = 1 - }, -/turf/open/indestructible/hotelwood, -/area/centcom/holding) "Nz" = ( /obj/effect/turf_decal/tile/brown{ dir = 8 @@ -17127,15 +17099,6 @@ "PD" = ( /turf/open/floor/plasteel/cafeteria, /area/syndicate_mothership) -"PF" = ( -/obj/machinery/vr_sleeper{ - dir = 8 - }, -/obj/machinery/light{ - dir = 4 - }, -/turf/open/indestructible/hotelwood, -/area/centcom/holding) "PG" = ( /obj/structure/table/reinforced, /obj/item/camera, @@ -43149,13 +43112,13 @@ UV CV Sd NT -CT -oV -CT -CT -CT -oV -CT +Sd +Sd +Sd +Sd +Sd +Sd +Sd Nd VL Ww @@ -43663,13 +43626,13 @@ UV CV Sd NT -Dj -PF -Dj Sd -Dj -PF -Dj +MR +Sd +Sd +Sd +MR +Sd Nd Sd Sd @@ -47237,7 +47200,7 @@ aa aa aa Nd -Ny +Gs Sd Sd Sd From 9750eb3d422d8c9d7a2bc88877db320e265f14f2 Mon Sep 17 00:00:00 2001 From: Putnam Date: Mon, 6 Jan 2020 23:52:07 -0800 Subject: [PATCH 030/203] "quotation marks" --- _maps/map_files/generic/CentCom.dmm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index 3df84a9f86..2cca63db46 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -18135,7 +18135,7 @@ /area/centcom/holding) "VL" = ( /obj/machinery/button/crematorium{ - id = crematoriumGhostDojo; + id = "crematoriumGhostDojo"; pixel_x = -25 }, /turf/open/indestructible/hotelwood, @@ -18223,7 +18223,7 @@ "Ww" = ( /obj/structure/bodycontainer/crematorium{ dir = 4; - id = crematoriumGhostDojo + id = "crematoriumGhostDojo" }, /turf/open/indestructible/hotelwood, /area/centcom/holding) From 19887691f35ba063b87d9d018ee0ca65f53947ed Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 7 Jan 2020 04:39:04 -0800 Subject: [PATCH 031/203] added deadchat toggle to dojo mobs too --- .../objects/structures/ghost_role_spawners.dm | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 418884435c..8aa84f2210 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -619,6 +619,24 @@ skip_reentry_check = TRUE banType = "ghostcafe" +/datum/action/toggle_dead_chat_mob + icon_icon = 'icons/mob/mob.dmi' + button_icon_state = "ghost" + name = "Toggle deadchat" + desc = "Turn off or on your ability to hear ghosts." + +/datum/action/toggle_dead_chat_mob/Trigger() + if(!..()) + return 0 + var/mob/M = target + if(HAS_TRAIT(M,TRAIT_SIXTHSENSE)) + REMOVE_TRAIT(M,TRAIT_SIXTHSENSE,GHOSTROLE_TRAIT) + to_chat(M,"You're no longer hearing deadchat.") + else + ADD_TRAIT(M,TRAIT_SIXTHSENSE,GHOSTROLE_TRAIT) + to_chat(M,"You're once again longer hearing deadchat.") + + /obj/effect/mob_spawn/human/ghostcafe/special(mob/living/carbon/human/new_spawn) if(new_spawn.client) new_spawn.client.prefs.copy_to(new_spawn) @@ -634,6 +652,8 @@ to_chat(new_spawn,"You can turn yourself into a ghost and freely reenter your body with the ghost action.") var/datum/action/ghost/G = new(new_spawn) G.Grant(new_spawn) + var/datum/action/toggle_dead_chat_mob/D = new(new_spawn) + D.Grant(new_spawn) /datum/outfit/ghostcafe name = "ID, jumpsuit and shoes" From a91f31d9e68eaec6247f0bf7e78190aec7905698 Mon Sep 17 00:00:00 2001 From: r4d6 Date: Tue, 7 Jan 2020 11:21:00 -0500 Subject: [PATCH 032/203] Fix a typo --- code/modules/research/designs/misc_designs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index 198f06ed3f..55a2442f07 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -394,7 +394,7 @@ desc = "Adds the simple circuits to the RCD." id = "rcd_upgrade_simple_circuits" build_type = PROTOLATHE - materials = list(AT_METAL = 5000, MAT_GLASS = 2500, MAT_SILVER = 1500, MAT_TITANIUM = 2000) + materials = list(MAT_METAL = 5000, MAT_GLASS = 2500, MAT_SILVER = 1500, MAT_TITANIUM = 2000) build_path = /obj/item/rcd_upgrade/simple_circuits category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING From f6fef849841a995647848583fec63cb2687e217e Mon Sep 17 00:00:00 2001 From: r4d6 Date: Tue, 7 Jan 2020 11:23:25 -0500 Subject: [PATCH 033/203] Make the RCD effect not right-clickable. --- code/game/objects/effects/temporary_visuals/miscellaneous.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index 2f18fa0ecb..cdf6b77a76 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -461,6 +461,7 @@ anchored = TRUE var/status = 0 var/delay = 0 + mouse_opacity = MOUSE_OPACITY_TRANSPARENT /obj/effect/constructing_effect/Initialize(mapload, rcd_delay, rcd_status) . = ..() From 7c757900f2dcbc6e656300cfc588007847658cfd Mon Sep 17 00:00:00 2001 From: r4d6 <50276533+r4d6@users.noreply.github.com> Date: Tue, 7 Jan 2020 13:27:44 -0500 Subject: [PATCH 034/203] Fix the category --- code/modules/research/designs/misc_designs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index 55a2442f07..0790cc488f 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -386,7 +386,7 @@ build_type = PROTOLATHE materials = list(MAT_METAL = 5000, MAT_GLASS = 2500, MAT_SILVER = 1500, MAT_TITANIUM = 2000) build_path = /obj/item/rcd_upgrade/frames - category = list("Tool Designs") + category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING /datum/design/rcd_upgrade/simple_circuits From 12a04da2d22365b50f9b00983677410e6a92ac32 Mon Sep 17 00:00:00 2001 From: Putnam Date: Wed, 8 Jan 2020 00:57:42 -0800 Subject: [PATCH 035/203] Added second flavor text, not copied on save. --- code/__HELPERS/_cit_helpers.dm | 11 +++++++++ .../mob/living/carbon/human/examine.dm | 7 ++++++ code/modules/mob/say_vr.dm | 24 +++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/code/__HELPERS/_cit_helpers.dm b/code/__HELPERS/_cit_helpers.dm index 8134494306..e874097e88 100644 --- a/code/__HELPERS/_cit_helpers.dm +++ b/code/__HELPERS/_cit_helpers.dm @@ -121,6 +121,17 @@ GLOBAL_VAR_INIT(miscreants_allowed, FALSE) flavor_text = sanitize(new_flavor) to_chat(src, "Your flavor text has been updated.") +//Flavor Text +/mob/living/carbon/human/verb/set_flavor_2() + set name = "Set Temporary Flavor Text" + set desc = "Sets a description of your character's current appearance. Use this for emotions, poses etc." + set category = "IC" + + var/new_flavor = input(src, "Enter your new temporary flavor text:", "Temporary flavor text", null) as message|null + if(!isnull(new_flavor)) + flavor_text_2 = sanitize(new_flavor) + to_chat(src, "Your temporary flavor text has been updated.") + //LOOC toggles /client/verb/listen_looc() set name = "Show/Hide LOOC" diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 3a6f0e6724..51ed433a7d 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -392,6 +392,13 @@ . += "...?" else . += "[print_flavor_text()]" + if(print_flavor_text_2()) + if(get_visible_name() == "Unknown") //Are we sure we know who this is? Don't show flavor text unless we can recognize them. Prevents certain metagaming with impersonation. + . += "...?" + else if(skipface) //Sometimes we're not unknown, but impersonating someone in a hardsuit, let's not reveal our flavor text then either. + . += "...?" + else + . += "[print_flavor_text_2()]" . += "*---------*" /mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects! diff --git a/code/modules/mob/say_vr.dm b/code/modules/mob/say_vr.dm index a7ffd29463..a387dcb1d2 100644 --- a/code/modules/mob/say_vr.dm +++ b/code/modules/mob/say_vr.dm @@ -3,6 +3,7 @@ ////////////////////////////////////////////////////// /mob var/flavor_text = "" //tired of fucking double checking this + var/flavor_text_2 = "" /mob/proc/update_flavor_text() set src in usr @@ -16,6 +17,19 @@ flavor_text = msg +/mob/proc/update_flavor_text_2() + set src in usr + if(usr != src) + to_chat(usr, "No.") + var/msg = stripped_multiline_input(usr, "Set the temporary flavor text in your 'examine' verb. This should be used only for things pertaining to the current round!", "Short-Term Flavor Text", html_decode(flavor_text_2), MAX_MESSAGE_LEN*2, TRUE) + + if(!isnull(msg)) + msg = copytext(msg, 1, MAX_MESSAGE_LEN) + msg = html_encode(msg) + + flavor_text_2 = msg + + /mob/proc/warn_flavor_changed() if(flavor_text && flavor_text != "") // don't spam people that don't use it! to_chat(src, "

OOC Warning:

") @@ -30,6 +44,16 @@ else return "[html_encode(copytext(msg, 1, 37))]... More..." +/mob/proc/print_flavor_text_2() + if(flavor_text && flavor_text != "") + // We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown. + var/msg = html_decode(replacetext(flavor_text_2, "\n", " ")) + if(length(msg) <= 40) + return "[html_encode(msg)]" + else + return "[html_encode(copytext(msg, 1, 37))]... More..." + + /mob/proc/get_top_level_mob() if(istype(src.loc,/mob)&&src.loc!=src) var/mob/M=src.loc From 83eff390634353e698f2fc1146bfb8335ecbc39b Mon Sep 17 00:00:00 2001 From: Seris02 Date: Wed, 8 Jan 2020 17:20:58 +0800 Subject: [PATCH 036/203] nope --- code/datums/shuttles.dm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/datums/shuttles.dm b/code/datums/shuttles.dm index e6d80bedb5..e355a507f3 100644 --- a/code/datums/shuttles.dm +++ b/code/datums/shuttles.dm @@ -380,9 +380,14 @@ /datum/map_template/shuttle/emergency/gorilla suffix = "gorilla" name = "Gorilla Cargo Freighter" - description = "A rustic, barely excuseable shuttle transporting important cargo. Not for crew who are about to go ape." + description = "(Emag only) A rustic, barely excuseable shuttle transporting important cargo. Not for crew who are about to go ape." credit_cost = 2000 +/datum/map_template/shuttle/emergency/gorilla/prerequisites_met() + if("emagged" in SSshuttle.shuttle_purchase_requirements_met) + return TRUE + return FALSE + /datum/map_template/shuttle/ferry/base suffix = "base" name = "transport ferry" From 56c0800609ce98b0109846b367f93aeb042ce670 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Wed, 8 Jan 2020 09:57:26 -0500 Subject: [PATCH 037/203] this file literally does nothing --- modular_citadel/code/datums/components/material_container.dm | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 modular_citadel/code/datums/components/material_container.dm diff --git a/modular_citadel/code/datums/components/material_container.dm b/modular_citadel/code/datums/components/material_container.dm deleted file mode 100644 index a7c50e37c5..0000000000 --- a/modular_citadel/code/datums/components/material_container.dm +++ /dev/null @@ -1,4 +0,0 @@ -/datum/material/plastic - name = "Plastic" - id = MAT_PLASTIC - sheet_type = /obj/item/stack/sheet/plastic \ No newline at end of file From 7f3802d2e2f324bbcd95656a6496207e76620f2e Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Wed, 8 Jan 2020 09:57:58 -0500 Subject: [PATCH 038/203] nay --- tgstation.dme | 1 - 1 file changed, 1 deletion(-) diff --git a/tgstation.dme b/tgstation.dme index 0bad708dc4..5879e3b53a 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -3063,7 +3063,6 @@ #include "modular_citadel\code\_onclick\hud\screen_objects.dm" #include "modular_citadel\code\_onclick\hud\sprint.dm" #include "modular_citadel\code\_onclick\hud\stamina.dm" -#include "modular_citadel\code\datums\components\material_container.dm" #include "modular_citadel\code\datums\components\souldeath.dm" #include "modular_citadel\code\datums\status_effects\chems.dm" #include "modular_citadel\code\datums\status_effects\debuffs.dm" From c2a8c23751bbb82707136f6dee709bd0838c7e68 Mon Sep 17 00:00:00 2001 From: Commandersand Date: Sun, 5 Jan 2020 19:03:54 -0600 Subject: [PATCH 039/203] fixes --- code/modules/clothing/under/miscellaneous.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 177bce672f..2a2973dadd 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -599,6 +599,7 @@ icon_state = "corset" item_color = "corset" body_parts_covered = CHEST|GROIN + mutantrace_variation = NO_MUTANTRACE_VARIATION fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE @@ -876,6 +877,7 @@ icon_state = "gear_harness" item_state = "gear_harness" body_parts_covered = CHEST|GROIN + mutantrace_variation = NO_MUTANTRACE_VARIATION can_adjust = FALSE /obj/item/clothing/under/telegram From 11aab548641464cc904c23ca031573177cbbaf69 Mon Sep 17 00:00:00 2001 From: Commandersand Date: Sun, 5 Jan 2020 20:19:03 -0600 Subject: [PATCH 040/203] oops --- code/modules/clothing/under/miscellaneous.dm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 2a2973dadd..5124bb2935 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -606,9 +606,8 @@ /obj/item/clothing/under/croptop name = "crop top" desc = "We've saved money by giving you half a shirt!" - icon_state = "sailor_dress" - item_state = "sailordress" - item_color = "sailor_dress" + icon_state = "croptop" + item_color = "croptop" body_parts_covered = CHEST|GROIN|ARMS fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE From 20948b66bbd0c0b31d2a25140a90240281d6522b Mon Sep 17 00:00:00 2001 From: loginsandylogout Date: Wed, 8 Jan 2020 02:49:08 -0600 Subject: [PATCH 041/203] should hide legs --- code/modules/clothing/under/miscellaneous.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 5124bb2935..13763ac972 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -580,7 +580,7 @@ icon_state = "flower_dress" item_state = "sailordress" item_color = "flower_dress" - body_parts_covered = CHEST|GROIN + body_parts_covered = CHEST|GROIN|LEGS fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE @@ -936,4 +936,4 @@ icon_state = "christmasfemaleg" item_state = "christmasfemaleg" body_parts_covered = CHEST|GROIN - can_adjust = FALSE \ No newline at end of file + can_adjust = FALSE From 248785dc94be18a7758406d106f73bb12e7f7b94 Mon Sep 17 00:00:00 2001 From: loginsandylogout Date: Wed, 8 Jan 2020 03:00:35 -0600 Subject: [PATCH 042/203] aaa --- code/modules/clothing/under/miscellaneous.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 13763ac972..d9bf978756 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -937,3 +937,4 @@ item_state = "christmasfemaleg" body_parts_covered = CHEST|GROIN can_adjust = FALSE + From 725828b99692b8a0694e07f12aded0307ae09d73 Mon Sep 17 00:00:00 2001 From: loginsandylogout Date: Wed, 8 Jan 2020 22:52:47 -0600 Subject: [PATCH 043/203] fixes ti? --- code/modules/clothing/under/miscellaneous.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index d9bf978756..ebc40acdec 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -471,6 +471,7 @@ name = "white sundress" desc = "Makes you want to frolic in a field of lillies." icon_state = "sundress_white" + item_state = "sundress" item_color = "sundress_white" body_parts_covered = CHEST|GROIN fitted = FEMALE_UNIFORM_TOP From be35379387d3e745f33560c4f902e42ed6edbf75 Mon Sep 17 00:00:00 2001 From: Commandersand Date: Wed, 8 Jan 2020 22:56:18 -0600 Subject: [PATCH 044/203] obj psrite fixes --- icons/obj/clothing/uniforms.dmi | Bin 113512 -> 103324 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi index e6474e7899af7b04a1d89f08b02ccf78e241b446..89f9a6fd93575fb88367b1699e0401a52b1246e3 100644 GIT binary patch literal 103324 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�`<1q!l&nD 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�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ð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 literal 113512 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

)gl-T`v^0Y_;`i2 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 From 02541f1e3e8715c13b43ef1696fedea50c280af5 Mon Sep 17 00:00:00 2001 From: loginsandylogout Date: Wed, 8 Jan 2020 23:34:26 -0600 Subject: [PATCH 045/203] thisis it --- code/modules/clothing/under/miscellaneous.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index ebc40acdec..c4f22ee3eb 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -19,7 +19,7 @@ desc = "Motorcycle not included." icon_state = "ek" item_state = "ek" - item_color = "ek" + item_color = "ek"f can_adjust = FALSE /obj/item/clothing/under/scratch @@ -474,6 +474,7 @@ item_state = "sundress" item_color = "sundress_white" body_parts_covered = CHEST|GROIN + mutantrace_variation = NO_MUTANTRACE_VARIATION fitted = FEMALE_UNIFORM_TOP can_adjust = FALSE From 709a803f192591763afd7a2b0c98f030fb0fe9fb Mon Sep 17 00:00:00 2001 From: loginsandylogout Date: Wed, 8 Jan 2020 23:34:43 -0600 Subject: [PATCH 046/203] oops --- code/modules/clothing/under/miscellaneous.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index c4f22ee3eb..756812f631 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -19,7 +19,7 @@ desc = "Motorcycle not included." icon_state = "ek" item_state = "ek" - item_color = "ek"f + item_color = "ek" can_adjust = FALSE /obj/item/clothing/under/scratch From 34c6288d227c7ee91efbba0030ce4e1ce30382fa Mon Sep 17 00:00:00 2001 From: TrilbySpaceClone Date: Thu, 9 Jan 2020 05:46:30 -0500 Subject: [PATCH 047/203] so fantastic! --- .../objects/items/stacks/sheets/mineral.dm | 46 +++++++++---------- .../items/stacks/sheets/sheet_types.dm | 24 ++++++---- .../reagents/chemistry/recipes/others.dm | 38 +++++++++++++++ 3 files changed, 76 insertions(+), 32 deletions(-) diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index fe42f88f56..b70388d9e0 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -332,29 +332,6 @@ GLOBAL_LIST_INIT(plastitanium_recipes, list ( \ . = ..() -/* - * Snow - */ -/obj/item/stack/sheet/mineral/snow - name = "snow" - icon_state = "sheet-snow" - item_state = "sheet-snow" - singular_name = "snow block" - force = 1 - throwforce = 2 - grind_results = list("ice" = 20) - merge_type = /obj/item/stack/sheet/mineral/snow - -GLOBAL_LIST_INIT(snow_recipes, list ( \ - new/datum/stack_recipe("Snow Wall", /turf/closed/wall/mineral/snow, 5, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("Snowman", /obj/structure/statue/snow/snowman, 5, one_per_turf = 1, on_floor = 1), \ - new/datum/stack_recipe("Snowball", /obj/item/toy/snowball, 1), \ - )) - -/obj/item/stack/sheet/mineral/snow/Initialize(mapload, new_amount, merge = TRUE) - recipes = GLOB.snow_recipes - . = ..() - /****************************** Others ****************************/ /* @@ -386,6 +363,29 @@ GLOBAL_LIST_INIT(adamantine_recipes, list( novariants = TRUE merge_type = /obj/item/stack/sheet/mineral/mythril +/* + * Snow + */ +/obj/item/stack/sheet/mineral/snow + name = "snow" + icon_state = "sheet-snow" + item_state = "sheet-snow" + singular_name = "snow block" + force = 1 + throwforce = 2 + grind_results = list("ice" = 20) + merge_type = /obj/item/stack/sheet/mineral/snow + +GLOBAL_LIST_INIT(snow_recipes, list ( \ + new/datum/stack_recipe("Snow Wall", /turf/closed/wall/mineral/snow, 5, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("Snowman", /obj/structure/statue/snow/snowman, 5, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("Snowball", /obj/item/toy/snowball, 1), \ + )) + +/obj/item/stack/sheet/mineral/snow/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.snow_recipes + . = ..() + /* * Alien Alloy */ diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index b20f412620..ce2d2a5e5a 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -3,13 +3,18 @@ * Metal * Plasteel * Wood + * Bamboo * Cloth - * Plastic + * Silk + * Durathread * Cardboard - * Paper Frames * Runed Metal (cult) * Brass (clockwork cult) * Bronze (bake brass) + * Gems + * Bones + * Plastic + * Paper Frames * Cotton/Duracotton */ @@ -240,7 +245,6 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \ novariants = TRUE grind_results = list("carbon" = 20) - /obj/item/stack/sheet/mineral/wood/attackby(obj/item/W, mob/user, params) // NOTE: sheet_types.dm is where the WOOD stack lives. Maybe move this over there. // Taken from /obj/item/stack/rods/attackby in [rods.dm] if(W.get_sharpness()) @@ -302,7 +306,6 @@ GLOBAL_LIST_INIT(bamboo_recipes, list ( \ recipes = GLOB.bamboo_recipes return ..() - /* * Cloth */ @@ -356,6 +359,10 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ /obj/item/stack/sheet/cloth/thirty amount = 30 +/* + * Silk + */ + /obj/item/stack/sheet/silk name = "silk" desc = "A long soft material. This one is just made out of cotton rather then any spiders or wyrms" @@ -369,7 +376,9 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ // recipes = GLOB.silk_recipes // return ..() -//Durathread fuck slash-asterisk comments +/* + * Durathread + */ GLOBAL_LIST_INIT(durathread_recipes, list ( \ new/datum/stack_recipe("durathread jumpsuit", /obj/item/clothing/under/durathread, 4, time = 40), new/datum/stack_recipe("durathread beret", /obj/item/clothing/head/beret/durathread, 2, time = 40), \ @@ -392,8 +401,6 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ recipes = GLOB.durathread_recipes return ..() - - /* * Cardboard */ @@ -487,7 +494,6 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \ else . = ..() - /* * Runed Metal */ @@ -712,6 +718,7 @@ GLOBAL_LIST_INIT(plastic_recipes, list( item_state = "sheet-plastic" materials = list(MAT_PLASTIC=MINERAL_MATERIAL_AMOUNT) throwforce = 7 + grind_results = list("white_glitter" = 60) merge_type = /obj/item/stack/sheet/plastic /obj/item/stack/sheet/plastic/fifty @@ -748,7 +755,6 @@ new /datum/stack_recipe("paper frame door", /obj/structure/mineral_door/paperfra /obj/item/stack/sheet/paperframes/fifty amount = 50 - //durathread and cotton raw /obj/item/stack/sheet/cotton name = "raw cotton bundle" diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index ad349ea926..2b775bcbe2 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -709,3 +709,41 @@ id = "royalbluecarpet" results = list("royalbluecarpet" = 2) required_reagents = list("carpet" = 1, "clonexadone" = 1) + +//////////////////////////////////// Glitter /////////////////////////////////////////// + +/datum/chemical_reaction/white_glitter/blue + name = "white glitter from blue" + id = "white_glitter_blue" + results = list("white_glitter" = 2) + required_reagents = list("blue_glitter" = 1, "whitecrayonpowder" = 1) + +/datum/chemical_reaction/white_glitter/pink + name = "white glitter from pink" + id = "white_glitter_pink" + results = list("white_glitter" = 2) + required_reagents = list("pink_glitter" = 1, "whitecrayonpowder" = 1) + +/datum/chemical_reaction/pink_glitter/blue + name = "pink glitter from blue" + id = "pink_glitter_blue" + results = list("pink_glitter" = 2) + required_reagents = list("blue_glitter" = 1, "redcrayonpowder" = 1) + +/datum/chemical_reaction/pink_glitter/white + name = "pink glitter from white" + id = "pink_glitter_white" + results = list("pink_glitter" = 2) + required_reagents = list("white_glitter" = 1, "redcrayonpowder" = 1) + +/datum/chemical_reaction/blue_glitter/pink + name = "blue glitter from pink" + id = "blue_glitter_pink" + results = list("blue_glitter" = 2) + required_reagents = list("pink_glitter" = 1, "bluecrayonpowder" = 1) + +/datum/chemical_reaction/blue_glitter/white + name = "blue glitter from white" + id = "blue_glitter_white" + results = list("blue_glitter" = 2) + required_reagents = list("white_glitter" = 1, "bluecrayonpowder" = 1) \ No newline at end of file From 17afb84f949eeeeee4edeca778ca569b8385939c Mon Sep 17 00:00:00 2001 From: Trilbyspaceclone <30435998+Trilbyspaceclone@users.noreply.github.com> Date: Thu, 9 Jan 2020 05:53:23 -0500 Subject: [PATCH 048/203] I didnt even touch any maps --- code/game/objects/items/stacks/sheets/sheet_types.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index ce2d2a5e5a..5ddf7e6c5a 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -362,7 +362,6 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ /* * Silk */ - /obj/item/stack/sheet/silk name = "silk" desc = "A long soft material. This one is just made out of cotton rather then any spiders or wyrms" From 896df2ace373fe545be1cb0b40a7737a2c816711 Mon Sep 17 00:00:00 2001 From: Putnam Date: Thu, 9 Jan 2020 04:47:14 -0800 Subject: [PATCH 049/203] score instead of ranked choice --- .../configuration/configuration.dm | 2 +- code/controllers/subsystem/vote.dm | 32 +++++++++++++------ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index 730a3f17f4..240f7de2d5 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -341,7 +341,7 @@ if(probabilities[M.config_tag]<=0) qdel(M) continue - if(M.config_tag in SSvote.stored_modetier_results && SSvote.stored_modetier_results[M.config_tag] < Get(/datum/config_entry/number/dropped_modes)) + if(!(M.config_tag in SSvote.stored_modetier_results)) qdel(M) continue if(min_pop[M.config_tag]) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index f82954276e..9603edacef 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -212,6 +212,7 @@ SUBSYSTEM_DEF(vote) calculate_condorcet_votes(vote_title_text) if(vote_system == SCORE_VOTING) calculate_majority_judgement_vote(vote_title_text) + calculate_scores(vote_title_text) var/list/winners = get_result() var/was_roundtype_vote = mode == "roundtype" || mode == "dynamic" if(winners.len > 0) @@ -219,13 +220,20 @@ SUBSYSTEM_DEF(vote) stored_gamemode_votes = list() if(!obfuscated && vote_system == RANKED_CHOICE_VOTING) text += "\nIt should be noted that this is not a raw tally of votes (impossible in ranked choice) but the score determined by the schulze method of voting, so the numbers will look weird!" - for(var/i=1,i<=choices.len,i++) - var/votes = choices[choices[i]] - if(!votes) - votes = 0 - if(was_roundtype_vote) - stored_gamemode_votes[choices[i]] = votes - text += "\n[choices[i]]: [obfuscated ? "???" : votes]" //CIT CHANGE - adds obfuscated votes + if(mode == "mode tiers") + for(var/score_name in scores) + var/score = scores[score_name] + if(!score) + score = 0 + text = "\n[score_name]: [obfuscated ? "???" : score]" + else + for(var/i=1,i<=choices.len,i++) + var/votes = choices[choices[i]] + if(!votes) + votes = 0 + if(was_roundtype_vote) + stored_gamemode_votes[choices[i]] = votes + text += "\n[choices[i]]: [obfuscated ? "???" : votes]" //CIT CHANGE - adds obfuscated votes if(mode != "custom") if(winners.len > 1 && !obfuscated) //CIT CHANGE - adds obfuscated votes text = "\nVote Tied Between:" @@ -276,7 +284,7 @@ SUBSYSTEM_DEF(vote) if(CONFIG_GET(flag/modetier_voting)) reset() started_time = 0 - initiate_vote("mode tiers","server",hideresults=FALSE,votesystem=RANKED_CHOICE_VOTING,forced=TRUE, vote_time = 30 MINUTES) + initiate_vote("mode tiers","server",hideresults=FALSE,votesystem=SCORE_VOTING,forced=TRUE, vote_time = 30 MINUTES) to_chat(world,"The vote will end right as the round starts.") return . if("restart") @@ -290,7 +298,13 @@ SUBSYSTEM_DEF(vote) else GLOB.master_mode = . if("mode tiers") - stored_modetier_results = choices.Copy() + var/list/raw_score_numbers = list() + for(var/score_name in scores) + sorted_insert(raw_score_numbers,scores[score_name],/proc/cmp_numeric_asc) + stored_modetier_results = scores.Copy() + for(var/score_name in stored_modetier_results) + if(stored_modetier_results[score_name] <= raw_score_numbers[CONFIG_GET(number/dropped_modes)]) + stored_modetier_results -= score_name if("dynamic") if(SSticker.current_state > GAME_STATE_PREGAME)//Don't change the mode if the round already started. return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.") From dfce4ea75fc0eae6575b0ea7b5283e95047fe1ec Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Thu, 9 Jan 2020 09:30:49 -0800 Subject: [PATCH 050/203] Update looc.dm --- code/modules/client/verbs/looc.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/modules/client/verbs/looc.dm b/code/modules/client/verbs/looc.dm index b371372dfe..38cfd84b9c 100644 --- a/code/modules/client/verbs/looc.dm +++ b/code/modules/client/verbs/looc.dm @@ -10,9 +10,7 @@ GLOBAL_VAR_INIT(normal_looc_colour, "#6699CC") to_chat(usr, " Speech is currently admin-disabled.") return - if(!mob) return - if(IsGuestKey(key)) - to_chat(src, "Guests may not use OOC.") + if(!mob) return msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN) From 581654f13f6d101c01084c81274c47585f5c554e Mon Sep 17 00:00:00 2001 From: r4d6 <50276533+r4d6@users.noreply.github.com> Date: Thu, 9 Jan 2020 13:55:31 -0500 Subject: [PATCH 051/203] Add RPD to research --- code/modules/research/techweb/all_nodes.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 7592e54b95..e52bde8a7c 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -200,7 +200,7 @@ display_name = "Advanced Engineering" description = "Pushing the boundaries of physics, one chainsaw-fist at a time." prereq_ids = list("engineering", "emp_basic") - design_ids = list("engine_goggles", "magboots", "forcefield_projector", "weldingmask" , "rcd_loaded", "tray_goggles_prescription", "engine_goggles_prescription", "mesons_prescription", "rcd_upgrade_frames", "rcd_upgrade_simple_circuits") + design_ids = list("engine_goggles", "magboots", "forcefield_projector", "weldingmask" , "rcd_loaded", "rpd", "tray_goggles_prescription", "engine_goggles_prescription", "mesons_prescription", "rcd_upgrade_frames", "rcd_upgrade_simple_circuits") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 4000) export_price = 5000 From 9361fe6d8e1ef852f7e230bbcd1da45def478b8f Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Thu, 9 Jan 2020 21:03:09 +0100 Subject: [PATCH 052/203] :joy: Vitaly matrixes weren't actually succing slimes.. nice. --- .../antagonists/clockcult/clock_effects/clock_sigils.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm index b5a218131b..8a9d2e9382 100644 --- a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm +++ b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm @@ -316,9 +316,9 @@ L.dust() else if(!GLOB.ratvar_awakens && L.stat == CONSCIOUS) - vitality_drained = L.adjustToxLoss(1) + vitality_drained = L.adjustToxLoss(1, forced = TRUE) else - vitality_drained = L.adjustToxLoss(1.5) + vitality_drained = L.adjustToxLoss(1.5, forced = TRUE) if(vitality_drained) GLOB.clockwork_vitality += vitality_drained else From 74d881388ecec983848b9a328db7b7c2c3f47cb9 Mon Sep 17 00:00:00 2001 From: TrilbySpaceClone Date: Thu, 9 Jan 2020 15:42:09 -0500 Subject: [PATCH 053/203] so much cleaner --- code/modules/uplink/uplink_items.dm | 1865 +---------------- .../uplink/uplink_items/uplink_ammo.dm | 255 +++ .../uplink/uplink_items/uplink_badass.dm | 77 + .../uplink/uplink_items/uplink_bundles.dm | 179 ++ .../uplink/uplink_items/uplink_clothing.dm | 80 + .../uplink/uplink_items/uplink_dangerous.dm | 260 +++ .../uplink/uplink_items/uplink_devices.dm | 251 +++ .../uplink/uplink_items/uplink_explosives.dm | 161 ++ .../uplink/uplink_items/uplink_implants.dm | 102 + .../uplink/uplink_items/uplink_roles.dm | 226 ++ .../uplink/uplink_items/uplink_stealth.dm | 134 ++ .../uplink_items/uplink_stealthdevices.dm | 125 ++ .../uplink/uplink_items/uplink_support.dm | 76 + tgstation.dme | 12 + 14 files changed, 1939 insertions(+), 1864 deletions(-) create mode 100644 code/modules/uplink/uplink_items/uplink_ammo.dm create mode 100644 code/modules/uplink/uplink_items/uplink_badass.dm create mode 100644 code/modules/uplink/uplink_items/uplink_bundles.dm create mode 100644 code/modules/uplink/uplink_items/uplink_clothing.dm create mode 100644 code/modules/uplink/uplink_items/uplink_dangerous.dm create mode 100644 code/modules/uplink/uplink_items/uplink_devices.dm create mode 100644 code/modules/uplink/uplink_items/uplink_explosives.dm create mode 100644 code/modules/uplink/uplink_items/uplink_implants.dm create mode 100644 code/modules/uplink/uplink_items/uplink_roles.dm create mode 100644 code/modules/uplink/uplink_items/uplink_stealth.dm create mode 100644 code/modules/uplink/uplink_items/uplink_stealthdevices.dm create mode 100644 code/modules/uplink/uplink_items/uplink_support.dm diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index 97fa6041a9..3acdf6c827 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -164,1867 +164,4 @@ //Discounts (dynamically filled above) /datum/uplink_item/discounts - category = "Discounted Gear" - - -/* - Uplink Items: - Unlike categories, uplink item entries are automatically sorted alphabetically on server init in a global list, - When adding new entries to the file, please keep them sorted by category. -*/ - -//All bundles and telecrystals - -/datum/uplink_item/bundles_TC/chemical - name = "Bioterror bundle" - desc = "For the madman: Contains a handheld Bioterror chem sprayer, a Bioterror foam grenade, a box of lethal chemicals, a dart pistol, \ - box of syringes, Donksoft assault rifle, and some riot darts. Remember: Seal suit and equip internals before use." - item = /obj/item/storage/backpack/duffelbag/syndie/med/bioterrorbundle - cost = 30 // normally 42 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/bundles_TC/bulldog - name = "Bulldog bundle" - desc = "Lean and mean: Optimized for people that want to get up close and personal. Contains the popular \ - Bulldog shotgun, a 12g buckshot drum, a 12g taser slug drum and a pair of Thermal imaging goggles." - item = /obj/item/storage/backpack/duffelbag/syndie/bulldogbundle - cost = 13 // normally 16 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/bundles_TC/c20r - name = "C-20r bundle" - desc = "Old Faithful: The classic C-20r, bundled with two magazines, and a (surplus) suppressor at discount price." - item = /obj/item/storage/backpack/duffelbag/syndie/c20rbundle - cost = 14 // normally 16 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/bundles_TC/cybernetics_bundle - name = "Cybernetic Implants Bundle" - desc = "A random selection of cybernetic implants. Guaranteed 5 high quality implants. Comes with an autosurgeon." - item = /obj/item/storage/box/cyber_implants - cost = 40 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/bundles_TC/medical - name = "Medical bundle" - desc = "The support specialist: Aid your fellow operatives with this medical bundle. Contains a tactical medkit, \ - a Donksoft LMG, a box of riot darts and a pair of magboots to rescue your friends in no-gravity environments." - item = /obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle - cost = 15 // normally 20 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/bundles_TC/modular - name = "Modular Pistol Kit" - desc = "A heavy briefcase containing one modular pistol (chambered in 10mm), one supressor, and spare ammunition, including a box of soporific ammo. \ - Includes a suit jacket that is padded with a robust liner." - item = /obj/item/storage/briefcase/modularbundle - cost = 12 - -/datum/uplink_item/bundles_TC/shredder - name = "Shredder bundle" - desc = "A truly horrific weapon designed simply to maim its victim, the CX Shredder is banned by several intergalactic treaties. \ - You'll get two of them with this. And spare ammo to boot. And we'll throw in an extra elite hardsuit and chest rig to hold them all!" - item = /obj/item/storage/backpack/duffelbag/syndie/shredderbundle - cost = 30 // normally 41 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/bundles_TC/sniper - name = "Sniper bundle" - desc = "Elegant and refined: Contains a collapsed sniper rifle in an expensive carrying case, \ - two soporific knockout magazines, a free surplus supressor, and a sharp-looking tactical turtleneck suit. \ - We'll throw in a free red tie if you order NOW." - item = /obj/item/storage/briefcase/sniperbundle - cost = 20 // normally 26 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/bundles_TC/firestarter - name = "Spetsnaz Pyro bundle" - desc = "For systematic suppression of carbon lifeforms in close quarters: Contains a lethal New Russian backpack spray, Elite hardsuit, \ - Stechkin APS pistol, two magazines, a minibomb and a stimulant syringe. \ - Order NOW and comrade Boris will throw in an extra tracksuit." - item = /obj/item/storage/backpack/duffelbag/syndie/firestarter - cost = 30 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/bundles_TC/bundle - name = "Syndicate Bundle" - desc = "Syndicate Bundles are specialized groups of items that arrive in a plain box. \ - These items are collectively worth more than 20 telecrystals, but you do not know which specialization \ - you will receive. May contain discontinued and/or exotic items." - item = /obj/item/storage/box/syndicate - cost = 20 - exclude_modes = list(/datum/game_mode/nuclear) - cant_discount = TRUE - -/datum/uplink_item/bundles_TC/surplus - name = "Syndicate Surplus Crate" - desc = "A dusty crate from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \ - but you never know. Contents are sorted to always be worth 50 TC." - item = /obj/structure/closet/crate - cost = 20 - player_minimum = 25 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - cant_discount = TRUE - var/starting_crate_value = 50 - -/datum/uplink_item/bundles_TC/surplus/super - name = "Super Surplus Crate" - desc = "A dusty SUPER-SIZED from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \ - but you never know. Contents are sorted to always be worth 125 TC." - cost = 40 - player_minimum = 40 - starting_crate_value = 125 - -/datum/uplink_item/bundles_TC/surplus/purchase(mob/user, datum/component/uplink/U) - var/list/uplink_items = get_uplink_items(SSticker && SSticker.mode? SSticker.mode : null, FALSE) - - var/crate_value = starting_crate_value - var/obj/structure/closet/crate/C = spawn_item(/obj/structure/closet/crate, user, U) - if(U.purchase_log) - U.purchase_log.LogPurchase(C, src, cost) - while(crate_value) - var/category = pick(uplink_items) - var/item = pick(uplink_items[category]) - var/datum/uplink_item/I = uplink_items[category][item] - - if(!I.surplus || prob(100 - I.surplus)) - continue - if(crate_value < I.cost) - continue - crate_value -= I.cost - var/obj/goods = new I.item(C) - if(U.purchase_log) - U.purchase_log.LogPurchase(goods, I, 0) - return C - -/datum/uplink_item/bundles_TC/random - name = "Random Item" - desc = "Picking this will purchase a random item. Useful if you have some TC to spare or if you haven't decided on a strategy yet." - item = /obj/effect/gibspawner/generic // non-tangible item because techwebs use this path to determine illegal tech - cost = 0 - cant_discount = TRUE - -/datum/uplink_item/bundles_TC/random/purchase(mob/user, datum/component/uplink/U) - var/list/uplink_items = U.uplink_items - var/list/possible_items = list() - for(var/category in uplink_items) - for(var/item in uplink_items[category]) - var/datum/uplink_item/I = uplink_items[category][item] - if(src == I || !I.item) - continue - if(U.telecrystals < I.cost) - continue - if(I.limited_stock == 0) - continue - possible_items += I - - if(possible_items.len) - var/datum/uplink_item/I = pick(possible_items) - SSblackbox.record_feedback("tally", "traitor_random_uplink_items_gotten", 1, initial(I.name)) - U.MakePurchase(user, I) - -/datum/uplink_item/bundles_TC/telecrystal - name = "1 Raw Telecrystal" - desc = "A telecrystal in its rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - item = /obj/item/stack/telecrystal - cost = 1 - surplus = 0 - cant_discount = TRUE - // Don't add telecrystals to the purchase_log since - // it's just used to buy more items (including itself!) - purchase_log_vis = FALSE - -/datum/uplink_item/bundles_TC/telecrystal/five - name = "5 Raw Telecrystals" - desc = "Five telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - item = /obj/item/stack/telecrystal/five - cost = 5 - -/datum/uplink_item/bundles_TC/telecrystal/twenty - name = "20 Raw Telecrystals" - desc = "Twenty telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." - item = /obj/item/stack/telecrystal/twenty - cost = 20 - -// Dangerous Items - -/datum/uplink_item/dangerous/pistol - name = "Stechkin Pistol" - desc = "A small, easily concealable handgun that uses 10mm auto rounds in 8-round magazines and is compatible \ - with suppressors." - item = /obj/item/gun/ballistic/automatic/pistol - cost = 7 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/dangerous/revolver - name = "Syndicate Revolver Kit" - desc = "A sleek box containing a brutally simple Syndicate revolver that fires .357 Magnum rounds and has 7 chambers, and an extra speedloader." - item = /obj/item/storage/box/syndie_kit/revolver - cost = 13 - surplus = 50 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/dangerous/rawketlawnchair - name = "84mm Rocket Propelled Grenade Launcher" - desc = "A reusable rocket propelled grenade launcher preloaded with a low-yield 84mm HE round. \ - Guaranteed to send your target out with a bang or your money back!" - item = /obj/item/gun/ballistic/rocketlauncher - cost = 8 - surplus = 30 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/antitank - name = "Anti Tank Pistol" - desc = "Essentially amounting to a sniper rifle with no stock and barrel (or indeed, any rifling at all), \ - this extremely dubious pistol is guaranteed to dislocate your wrists and hit the broad side of a barn! \ - Uses sniper ammo. \ - Bullets tend to veer off-course. We are not responsible for any unintentional damage or injury resulting from inaacuracy." - item = /obj/item/gun/ballistic/automatic/pistol/antitank/syndicate - cost = 14 - surplus = 25 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/pie_cannon - name = "Banana Cream Pie Cannon" - desc = "A special pie cannon for a special clown, this gadget can hold up to 20 pies and automatically fabricates one every two seconds!" - cost = 10 - item = /obj/item/pneumatic_cannon/pie/selfcharge - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/dangerous/bananashield - name = "Bananium Energy Shield" - desc = "A clown's most powerful defensive weapon, this personal shield provides near immunity to ranged energy attacks \ - by bouncing them back at the ones who fired them. It can also be thrown to bounce off of people, slipping them, \ - and returning to you even if you miss. WARNING: DO NOT ATTEMPT TO STAND ON SHIELD WHILE DEPLOYED, EVEN IF WEARING ANTI-SLIP SHOES." - item = /obj/item/shield/energy/bananium - cost = 16 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/dangerous/clownsword - name = "Bananium Energy Sword" - desc = "An energy sword that deals no damage, but will slip anyone it contacts, be it by melee attack, thrown \ - impact, or just stepping on it. Beware friendly fire, as even anti-slip shoes will not protect against it." - item = /obj/item/melee/transforming/energy/sword/bananium - cost = 3 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/dangerous/bioterror - name = "Biohazardous Chemical Sprayer" - desc = "A handheld chemical sprayer that allows a wide dispersal of selected chemicals. Especially tailored by the Tiger \ - Cooperative, the deadly blend it comes stocked with will disorient, damage, and disable your foes... \ - Use with extreme caution, to prevent exposure to yourself and your fellow operatives." - item = /obj/item/reagent_containers/spray/chemsprayer/bioterror - cost = 20 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/dangerous/throwingweapons - name = "Box of Throwing Weapons" - desc = "A box of shurikens and reinforced bolas from ancient Earth martial arts. They are highly effective \ - throwing weapons. The bolas can knock a target down and the shurikens will embed into limbs." - item = /obj/item/storage/box/syndie_kit/throwing_weapons - cost = 3 - -/datum/uplink_item/dangerous/shotgun - name = "Bulldog Shotgun" - desc = "A fully-loaded semi-automatic drum-fed shotgun. Compatible with all 12g rounds. Designed for close \ - quarter anti-personnel engagements." - item = /obj/item/gun/ballistic/automatic/shotgun/bulldog - cost = 8 - surplus = 40 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/smg - name = "C-20r Submachine Gun" - desc = "A fully-loaded Scarborough Arms bullpup submachine gun. The C-20r fires .45 rounds with a \ - 24-round magazine and is compatible with suppressors." - item = /obj/item/gun/ballistic/automatic/c20r - cost = 10 - surplus = 40 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/doublesword - name = "Double-Bladed Energy Sword" - desc = "The double-bladed energy sword does slightly more damage than a standard energy sword and will deflect \ - all energy projectiles, but requires two hands to wield." - item = /obj/item/twohanded/dualsaber - player_minimum = 25 - cost = 16 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/dangerous/doublesword/get_discount() - return pick(4;0.8,2;0.65,1;0.5) - -/datum/uplink_item/dangerous/cxneb - name = "Dragon's Tooth Non-Eutactic Blade" - desc = "An illegal modification of a weapon that is functionally identical to the energy sword, \ - the Non-Eutactic Blade (NEB) forges a hardlight blade on-demand, \ - generating an extremely sharp, unbreakable edge that is guaranteed to satisfy your every need. \ - This particular model has a polychromic hardlight generator, allowing you to murder in style! \ - The illegal modifications bring this weapon up to par with the classic energy sword, and also gives it the energy sword's distinctive sounds." - item = /obj/item/melee/transforming/energy/sword/cx/traitor - cost = 8 - -/datum/uplink_item/dangerous/sword - name = "Energy Sword" - desc = "The energy sword is an edged weapon with a blade of pure energy. The sword is small enough to be \ - pocketed when inactive. Activating it produces a loud, distinctive noise." - item = /obj/item/melee/transforming/energy/sword/saber - cost = 8 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/dangerous/shield - name = "Energy Shield" - desc = "An incredibly useful personal shield projector, capable of reflecting energy projectiles and defending \ - against other attacks. Pair with an Energy Sword for a killer combination." - item = /obj/item/shield/energy - cost = 16 - surplus = 20 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/rapier - name = "Rapier" - desc = "A fancy rapier with a diamond tip piercing anything that it comes into contack with. \ - The rapier comes with its own sheath, this is rather noticeable as only the captain is known to carry a sheath. \ - The sheath itself can be used to block melee attacks only. Its also jet black colours." - item = /obj/item/storage/belt/sabre/rapier - cost = 8 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/dangerous/flamethrower - name = "Flamethrower" - desc = "A flamethrower, fueled by a portion of highly flammable biotoxins stolen previously from Nanotrasen \ - stations. Make a statement by roasting the filth in their own greed. Use with caution." - item = /obj/item/flamethrower/full/tank - cost = 4 - surplus = 40 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/flechettegun - name = "Flechette Launcher" - desc = "A compact bullpup that fires micro-flechettes.\ - Flechettes have very poor performance idividually, but can be very deadly in numbers. \ - Pre-loaded with armor piercing flechettes that are capable of puncturing most kinds of armor." - item = /obj/item/gun/ballistic/automatic/flechette - cost = 12 - surplus = 30 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/rapid - name = "Gloves of the North Star" - desc = "These gloves let the user punch people very fast. Does not improve weapon attack speed or the meaty fists of a hulk." - item = /obj/item/clothing/gloves/rapid - cost = 8 - -/datum/uplink_item/dangerous/guardian - name = "Holoparasites" - desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an \ - organic host as a home base and source of fuel. Holoparasites come in various types and share damage with their host." - item = /obj/item/storage/box/syndie_kit/guardian - cost = 15 - refundable = TRUE - cant_discount = TRUE - surplus = 0 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - player_minimum = 25 - restricted = TRUE - refund_path = /obj/item/guardiancreator/tech/choose/traitor - -/datum/uplink_item/dangerous/machinegun - name = "L6 Squad Automatic Weapon" - desc = "A fully-loaded Aussec Armoury belt-fed machine gun. \ - This deadly weapon has a massive 50-round magazine of devastating 1.95x129mm ammunition." - item = /obj/item/gun/ballistic/automatic/l6_saw - cost = 18 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/carbine - name = "M-90gl Carbine" - desc = "A fully-loaded, specialized three-round burst carbine that fires 5.56mm ammunition from a 30 round magazine \ - with a toggleable 40mm underbarrel grenade launcher." - item = /obj/item/gun/ballistic/automatic/m90 - cost = 18 - surplus = 50 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/powerfist - name = "Power Fist" - desc = "The power-fist is a metal gauntlet with a built-in piston-ram powered by an external gas supply.\ - Upon hitting a target, the piston-ram will extend forward to make contact for some serious damage. \ - Using a wrench on the piston valve will allow you to tweak the amount of gas used per punch to \ - deal extra damage and hit targets further. Use a screwdriver to take out any attached tanks." - item = /obj/item/melee/powerfist - cost = 8 - -/datum/uplink_item/dangerous/sniper - name = "Sniper Rifle" - desc = "Ranged fury, Syndicate style. Guaranteed to cause shock and awe or your TC back!" - item = /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate - cost = 16 - surplus = 25 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/bolt_action - name = "Surplus Rifle" - desc = "A horribly outdated bolt action weapon. You've got to be desperate to use this." - item = /obj/item/gun/ballistic/shotgun/boltaction - cost = 2 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/dangerous/foamsmg - name = "Toy Submachine Gun" - desc = "A fully-loaded Donksoft bullpup submachine gun that fires riot grade darts with a 20-round magazine." - item = /obj/item/gun/ballistic/automatic/c20r/toy - cost = 5 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/dangerous/foammachinegun - name = "Toy Machine Gun" - desc = "A fully-loaded Donksoft belt-fed machine gun. This weapon has a massive 50-round magazine of devastating \ - riot grade darts, that can briefly incapacitate someone in just one volley." - item = /obj/item/gun/ballistic/automatic/l6_saw/toy - cost = 10 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/dangerous/foampistol - name = "Toy Pistol with Riot Darts" - desc = "An innocent-looking toy pistol designed to fire foam darts. Comes loaded with riot-grade \ - darts effective at incapacitating a target." - item = /obj/item/gun/ballistic/automatic/toy/pistol/riot - cost = 3 - surplus = 10 - -// Stealthy Weapons - -/datum/uplink_item/stealthy_weapons/combatglovesplus - name = "Combat Gloves Plus" - desc = "A pair of gloves that are fireproof and shock resistant, however unlike the regular Combat Gloves this one uses nanotechnology \ - to learn the abilities of krav maga to the wearer." - item = /obj/item/clothing/gloves/krav_maga/combatglovesplus - cost = 5 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - surplus = 0 - -/datum/uplink_item/stealthy_weapons/cqc - name = "CQC Manual" - desc = "A manual that teaches a single user tactical Close-Quarters Combat before self-destructing." - item = /obj/item/book/granter/martial/cqc - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - cost = 13 - surplus = 0 - -/datum/uplink_item/stealthy_weapons/dart_pistol - name = "Dart Pistol" - desc = "A miniaturized version of a normal syringe gun. It is very quiet when fired and can fit into any \ - space a small item can." - item = /obj/item/gun/syringe/syndicate - cost = 4 - surplus = 50 - -/datum/uplink_item/stealthy_weapons/dehy_carp - name = "Dehydrated Space Carp" - desc = "Looks like a plush toy carp, but just add water and it becomes a real-life space carp! Activate in \ - your hand before use so it knows not to kill you." - item = /obj/item/toy/plush/carpplushie/dehy_carp - cost = 1 - -/datum/uplink_item/stealthy_weapons/edagger - name = "Energy Dagger" - desc = "A dagger made of energy that looks and functions as a pen when off." - item = /obj/item/pen/edagger - cost = 2 - -/datum/uplink_item/stealthy_weapons/martialarts - name = "Sleeping Carp Scroll" - desc = "This scroll contains the secrets of an ancient martial arts technique. You will master unarmed combat, \ - deflecting all ranged weapon fire, but you also refuse to use dishonorable ranged weaponry." - item = /obj/item/book/granter/martial/carp - cost = 17 - surplus = 0 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/stealthy_weapons/martialartstwo - name = "Rising Bass Scroll" - desc = "This scroll contains the secrets of an ancient martial arts technique. You will become proficient in fleeing situations, \ - and dodging all ranged weapon fire, but you will refuse to use dishonorable ranged weaponry." - item = /obj/item/book/granter/martial/bass - cost = 18 - surplus = 0 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/stealthy_weapons/crossbow - name = "Miniature Energy Crossbow" - desc = "A short bow mounted across a tiller in miniature. Small enough to \ - fit into a pocket or slip into a bag unnoticed. It will synthesize \ - and fire bolts tipped with a paralyzing toxin that will briefly stun \ - targets and cause them to slur as if inebriated. It can produce an \ - infinite number of bolts, but takes time to automatically recharge \ - after each shot." - item = /obj/item/gun/energy/kinetic_accelerator/crossbow - cost = 12 - surplus = 50 - exclude_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/stealthy_weapons/traitor_chem_bottle - name = "Poison Kit" - desc = "An assortment of deadly chemicals packed into a compact box. Comes with a syringe for more precise application." - item = /obj/item/storage/box/syndie_kit/chemical - cost = 6 - surplus = 50 - -/datum/uplink_item/stealthy_weapons/romerol_kit - name = "Romerol" - desc = "A highly experimental bioterror agent which creates dormant nodules to be etched into the grey matter of the brain. \ - On death, these nodules take control of the dead body, causing limited revivification, \ - along with slurred speech, aggression, and the ability to infect others with this agent." - item = /obj/item/storage/box/syndie_kit/romerol - cost = 25 - cant_discount = TRUE - exclude_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/stealthy_weapons/sleepy_pen - name = "Sleepy Pen" - desc = "A syringe disguised as a functional pen, filled with a potent mix of drugs, including a \ - strong anesthetic and a chemical that prevents the target from speaking. \ - The pen holds one dose of the mixture, and can be refilled with any chemicals. Note that before the target \ - falls asleep, they will be able to move and act." - item = /obj/item/pen/sleepy - cost = 4 - exclude_modes = list(/datum/game_mode/nuclear) - -datum/uplink_item/stealthy_weapons/taeclowndo_shoes - name = "Tae-clown-do Shoes" - desc = "A pair of shoes for the most elite agents of the honkmotherland. They grant the mastery of taeclowndo with some honk-fu moves as long as they're worn." - cost = 12 - item = /obj/item/clothing/shoes/clown_shoes/taeclowndo - include_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/stealthy_weapons/suppressor - name = "Suppressor" - desc = "This suppressor will silence the shots of the weapon it is attached to for increased stealth and superior ambushing capability. \ - It is compatible with many small ballistic guns including the Stechkin and C-20r, but not revolvers or energy guns." - item = /obj/item/suppressor - cost = 1 - surplus = 10 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/stealthy_weapons/soap - name = "Syndicate Soap" - desc = "A sinister-looking surfactant used to clean blood stains to hide murders and prevent DNA analysis. \ - You can also drop it underfoot to slip people." - item = /obj/item/soap/syndie - cost = 1 - surplus = 50 - -/datum/uplink_item/stealthy_weapons/soap_clusterbang - name = "Slipocalypse Clusterbang" - desc = "A traditional clusterbang grenade with a payload consisting entirely of Syndicate soap. Useful in any scenario!" - item = /obj/item/grenade/clusterbuster/soap - cost = 6 - -// Ammunition - -/datum/uplink_item/ammo/pistol - name = "10mm Handgun Magazine" - desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. These rounds \ - are dirt cheap but are half as effective as .357 rounds." - item = /obj/item/ammo_box/magazine/m10mm - cost = 1 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/ammo/pistolap - name = "10mm Armour Piercing Magazine" - desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. \ - These rounds are less effective at injuring the target but penetrate protective gear." - item = /obj/item/ammo_box/magazine/m10mm/ap - cost = 2 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/ammo/pistolhp - name = "10mm Hollow Point Magazine" - desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. \ - These rounds are more damaging but ineffective against armour." - item = /obj/item/ammo_box/magazine/m10mm/hp - cost = 3 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/ammo/pistolfire - name = "10mm Incendiary Magazine" - desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. \ - Loaded with incendiary rounds which inflict little damage, but ignite the target." - item = /obj/item/ammo_box/magazine/m10mm/fire - cost = 2 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/ammo/pistolzzz - name = "10mm Soporific Magazine" - desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. Loaded with soporific rounds that put the target to sleep. \ - NOTE: Soporific is not instant acting due to the constraints of the round's scale. Will usually require three shots to take effect." - item = /obj/item/ammo_box/magazine/m10mm/soporific - cost = 2 - -/datum/uplink_item/ammo/shotgun - cost = 2 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/shotgun/bag - name = "12g Ammo Duffel Bag" - desc = "A duffel bag filled with enough 12g ammo to supply an entire team, at a discounted price." - item = /obj/item/storage/backpack/duffelbag/syndie/ammo/shotgun - cost = 12 - -/datum/uplink_item/ammo/shotgun/buck - name = "12g Buckshot Drum" - desc = "An additional 8-round buckshot magazine for use with the Bulldog shotgun. Front towards enemy." - item = /obj/item/ammo_box/magazine/m12g - -/datum/uplink_item/ammo/shotgun/dragon - name = "12g Dragon's Breath Drum" - desc = "An alternative 8-round dragon's breath magazine for use in the Bulldog shotgun. \ - 'I'm a fire starter, twisted fire starter!'" - item = /obj/item/ammo_box/magazine/m12g/dragon - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/shotgun/meteor - name = "12g Meteorslug Shells" - desc = "An alternative 8-round meteorslug magazine for use in the Bulldog shotgun. \ - Great for blasting airlocks off their frames and knocking down enemies." - item = /obj/item/ammo_box/magazine/m12g/meteor - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/shotgun/scatter - name = "12g Scatter Laser shot Slugs" - desc = "An alternative 8-round Scatter Laser Shot magazine for use in the Bulldog shotgun." - item = /obj/item/ammo_box/magazine/m12g/scatter - cost = 4 // most armor has less laser protection then bullet - -/datum/uplink_item/ammo/shotgun/slug - name = "12g Slug Drum" - desc = "An additional 8-round slug magazine for use with the Bulldog shotgun. \ - Now 8 times less likely to shoot your pals." - cost = 3 - item = /obj/item/ammo_box/magazine/m12g/slug - -/datum/uplink_item/ammo/shotgun/stun - name = "12g Stun Slug Drum" - desc = "An alternative 8-round stun slug magazine for use with the Bulldog shotgun. \ - Saying that they're completely non-lethal would be lying." - item = /obj/item/ammo_box/magazine/m12g/stun - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/revolver - name = ".357 Speed Loader" - desc = "A speed loader that contains seven additional .357 Magnum rounds, and can be further reloaded with individual bullets; usable with the Syndicate revolver. \ - For when you really need a lot of things dead." - item = /obj/item/ammo_box/a357 - cost = 3 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/ammo/revolver/ap - name = ".357 Armor Piercing Speed Loader" - desc = "A speed loader that contains seven additional .357 AP Magnum rounds; usable with the Syndicate revolver. \ - Cuts through like a hot knife through butter." - item = /obj/item/ammo_box/a357/ap - -/datum/uplink_item/ammo/a40mm - name = "40mm Grenade" - desc = "A 40mm HE grenade for use with the M-90gl's under-barrel grenade launcher. \ - Your teammates will ask you to not shoot these down small hallways." - item = /obj/item/ammo_casing/a40mm - cost = 2 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/smg/bag - name = ".45 Ammo Duffel Bag" - desc = "A duffel bag filled with enough .45 ammo to supply an entire team, at a discounted price." - item = /obj/item/storage/backpack/duffelbag/syndie/ammo/smg - cost = 20 //instead of 27 TC - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/smg - name = ".45 SMG Magazine" - desc = "An additional 24-round .45 magazine suitable for use with the C-20r submachine gun." - item = /obj/item/ammo_box/magazine/smgm45 - cost = 3 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/sniper - cost = 4 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/sniper/basic - name = ".50 Magazine" - desc = "An additional standard 6-round magazine for use with .50 sniper rifles." - item = /obj/item/ammo_box/magazine/sniper_rounds - -/datum/uplink_item/ammo/sniper/penetrator - name = ".50 Penetrator Magazine" - desc = "A 5-round magazine of penetrator ammo designed for use with .50 sniper rifles. \ - Can pierce walls and multiple enemies." - item = /obj/item/ammo_box/magazine/sniper_rounds/penetrator - cost = 5 - -/datum/uplink_item/ammo/sniper/soporific - name = ".50 Soporific Magazine" - desc = "A 3-round magazine of soporific ammo designed for use with .50 sniper rifles. Put your enemies to sleep today!" - item = /obj/item/ammo_box/magazine/sniper_rounds/soporific - cost = 6 - -/datum/uplink_item/ammo/carbine - name = "5.56mm Toploader Magazine" - desc = "An additional 30-round 5.56mm magazine; suitable for use with the M-90gl carbine. \ - These bullets pack less punch than 7.12x82mm rounds, but they still offer more power than .45 ammo." - item = /obj/item/ammo_box/magazine/m556 - cost = 4 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/machinegun - cost = 6 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/machinegun/basic - name = "1.95x129mm Box Magazine" - desc = "A 50-round magazine of 1.95x129mm ammunition for use with the L6 SAW. \ - By the time you need to use this, you'll already be standing on a pile of corpses" - item = /obj/item/ammo_box/magazine/mm195x129 - -/datum/uplink_item/ammo/machinegun/ap - name = "1.95x129mm (Armor Penetrating) Box Magazine" - desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with special properties \ - to puncture even the most durable armor." - item = /obj/item/ammo_box/magazine/mm195x129/ap - cost = 9 - -/datum/uplink_item/ammo/machinegun/hollow - name = "1.95x129mm (Hollow-Point) Box Magazine" - desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with hollow-point tips to help \ - with the unarmored masses of crew." - item = /obj/item/ammo_box/magazine/mm195x129/hollow - -/datum/uplink_item/ammo/machinegun/incen - name = "1.95x129mm (Incendiary) Box Magazine" - desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; tipped with a special flammable \ - mixture that'll ignite anyone struck by the bullet. Some men just want to watch the world burn." - item = /obj/item/ammo_box/magazine/mm195x129/incen - -/datum/uplink_item/ammo/rocket - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/rocket/basic - name = "84mm HE Rocket" - desc = "A low-yield anti-personnel HE rocket. Gonna take you out in style!" - item = /obj/item/ammo_casing/caseless/rocket - cost = 4 - -/datum/uplink_item/ammo/rocket/hedp - name = "84mm HEDP Rocket" - desc = "A high-yield HEDP rocket; extremely effective against armored targets, as well as surrounding personnel. \ - Strike fear into the hearts of your enemies." - item = /obj/item/ammo_casing/caseless/rocket/hedp - cost = 6 - -/datum/uplink_item/ammo/pistolaps - name = "9mm Handgun Magazine" - desc = "An additional 15-round 9mm magazine, compatible with the Stechkin APS pistol, found in the Spetsnaz Pyro bundle." - item = /obj/item/ammo_box/magazine/pistolm9mm - cost = 2 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/flechetteap - name = "Armor Piercing Flechette Magazine" - desc = "An additional 40-round flechette magazine; compatible with the Flechette Launcer. \ - Loaded with armor piercing flechettes that very nearly ignore armor, but are not very effective agaisnt flesh." - item = /obj/item/ammo_box/magazine/flechette - cost = 2 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/flechettes - name = "Serrated Flechette Magazine" - desc = "An additional 40-round flechette magazine; compatible with the Flechette Launcer. \ - Loaded with serrated flechettes that shreds flesh, but is stopped dead in its tracks by armor. \ - These flechettes are highly likely to sever arteries, and even limbs." - item = /obj/item/ammo_box/magazine/flechette/s - cost = 2 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/ammo/toydarts - name = "Box of Riot Darts" - desc = "A box of 40 Donksoft riot darts, for reloading any compatible foam dart magazine. Don't forget to share!" - item = /obj/item/ammo_box/foambox/riot - cost = 2 - surplus = 0 - illegal_tech = FALSE - -/datum/uplink_item/ammo/bioterror - name = "Box of Bioterror Syringes" - desc = "A box full of preloaded syringes, containing various chemicals that seize up the victim's motor \ - and broca systems, making it impossible for them to move or speak for some time." - item = /obj/item/storage/box/syndie_kit/bioterror - cost = 6 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/ammo/bolt_action - name = "Surplus Rifle Clip" - desc = "A stripper clip used to quickly load bolt action rifles. Contains 5 rounds." - item = /obj/item/ammo_box/a762 - cost = 1 - include_modes = list(/datum/game_mode/nuclear) - -//Grenades and Explosives - -/datum/uplink_item/explosives/bioterrorfoam - name = "Bioterror Foam Grenade" - desc = "A powerful chemical foam grenade which creates a deadly torrent of foam that will mute, blind, confuse, \ - mutate, and irritate carbon lifeforms. Specially brewed by Tiger Cooperative chemical weapons specialists \ - using additional spore toxin. Ensure suit is sealed before use." - item = /obj/item/grenade/chem_grenade/bioterrorfoam - cost = 5 - surplus = 35 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/explosives/bombanana - name = "Bombanana" - desc = "A banana with an explosive taste! discard the peel quickly, as it will explode with the force of a syndicate minibomb \ - a few seconds after the banana is eaten." - item = /obj/item/reagent_containers/food/snacks/grown/banana/bombanana - cost = 4 //it is a bit cheaper than a minibomb because you have to take off your helmet to eat it, which is how you arm it - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/explosives/buzzkill - name = "Buzzkill Grenade Box" - desc = "A box with three grenades that release a swarm of angry bees upon activation. These bees indiscriminately attack friend or foe \ - with random toxins. Courtesy of the BLF and Tiger Cooperative." - item = /obj/item/storage/box/syndie_kit/bee_grenades - cost = 15 - surplus = 35 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/explosives/c4 - name = "Composition C-4" - desc = "C-4 is plastic explosive of the common variety Composition C. You can use it to breach walls, sabotage equipment, or connect \ - an assembly to it in order to alter the way it detonates. It can be attached to almost all objects and has a modifiable timer with a \ - minimum setting of 10 seconds." - item = /obj/item/grenade/plastic/c4 - cost = 1 - -/datum/uplink_item/explosives/c4bag - name = "Bag of C-4 explosives" - desc = "Because sometimes quantity is quality. Contains 10 C-4 plastic explosives." - item = /obj/item/storage/backpack/duffelbag/syndie/c4 - cost = 9 //10% discount! - cant_discount = TRUE - -/datum/uplink_item/explosives/x4bag - name = "Bag of X-4 explosives" - desc = "Contains 3 X-4 shaped plastic explosives. Similar to C4, but with a stronger blast that is directional instead of circular. \ - X-4 can be placed on a solid surface, such as a wall or window, and it will blast through the wall, injuring anything on the opposite side, while being safer to the user. \ - For when you want a controlled explosion that leaves a wider, deeper, hole." - item = /obj/item/storage/backpack/duffelbag/syndie/x4 - cost = 4 // - cant_discount = TRUE - -/datum/uplink_item/explosives/clown_bomb_clownops - name = "Clown Bomb" - desc = "The Clown bomb is a hilarious device capable of massive pranks. It has an adjustable timer, \ - with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ - movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ - transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ - be defused, and some crew may attempt to do so." - item = /obj/item/sbeacondrop/clownbomb - cost = 15 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/explosives/detomatix - name = "Detomatix PDA Cartridge" - desc = "When inserted into a personal digital assistant, this cartridge gives you four opportunities to \ - detonate PDAs of crewmembers who have their message feature enabled. \ - The concussive effect from the explosion will knock the recipient out for a short period, and deafen them for longer." - item = /obj/item/cartridge/virus/syndicate - cost = 5 - restricted = TRUE - -/datum/uplink_item/explosives/emp - name = "EMP Grenades and Implanter Kit" - desc = "A box that contains five EMP grenades and an EMP implant with three uses. Useful to disrupt communications, \ - security's energy weapons and silicon lifeforms when you're in a tight spot." - item = /obj/item/storage/box/syndie_kit/emp - cost = 2 - -/datum/uplink_item/explosives/virus_grenade - name = "Fungal Tuberculosis Grenade" - desc = "A primed bio-grenade packed into a compact box. Comes with five Bio Virus Antidote Kit (BVAK) \ - autoinjectors for rapid application on up to two targets each, a syringe, and a bottle containing \ - the BVAK solution." - item = /obj/item/storage/box/syndie_kit/tuberculosisgrenade - cost = 8 - surplus = 35 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - restricted = TRUE - -/datum/uplink_item/explosives/grenadier - name = "Grenadier's belt" - desc = "A belt containing 26 lethally dangerous and destructive grenades. Comes with an extra multitool and screwdriver." - item = /obj/item/storage/belt/grenade/full - include_modes = list(/datum/game_mode/nuclear) - cost = 22 - surplus = 0 - -/datum/uplink_item/explosives/pizza_bomb - name = "Pizza Bomb" - desc = "A pizza box with a bomb cunningly attached to the lid. The timer needs to be set by opening the box; afterwards, \ - opening the box again will trigger the detonation after the timer has elapsed. Comes with free pizza, for you or your target!" - item = /obj/item/pizzabox/bomb - cost = 6 - surplus = 8 - -/datum/uplink_item/explosives/syndicate_bomb - name = "Syndicate Bomb" - desc = "The Syndicate bomb is a fearsome device capable of massive destruction. It has an adjustable timer, \ - with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ - movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ - transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ - be defused, and some crew may attempt to do so." - item = /obj/item/sbeacondrop/bomb - cost = 11 - -/datum/uplink_item/explosives/syndicate_detonator - name = "Syndicate Detonator" - desc = "The Syndicate detonator is a companion device to the Syndicate bomb. Simply press the included button \ - and an encrypted radio frequency will instruct all live Syndicate bombs to detonate. \ - Useful for when speed matters or you wish to synchronize multiple bomb blasts. Be sure to stand clear of \ - the blast radius before using the detonator." - item = /obj/item/syndicatedetonator - cost = 3 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/explosives/syndicate_minibomb - name = "Syndicate Minibomb" - desc = "The minibomb is a grenade with a five-second fuse. Upon detonation, it will create a small hull breach \ - in addition to dealing high amounts of damage to nearby personnel." - item = /obj/item/grenade/syndieminibomb - cost = 6 - exclude_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/explosives/tearstache - name = "Teachstache Grenade" - desc = "A teargas grenade that launches sticky moustaches onto the face of anyone not wearing a clown or mime mask. The moustaches will \ - remain attached to the face of all targets for one minute, preventing the use of breath masks and other such devices." - item = /obj/item/grenade/chem_grenade/teargas/moustache - cost = 3 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/explosives/viscerators - name = "Viscerator Delivery Grenade" - desc = "A unique grenade that deploys a swarm of viscerators upon activation, which will chase down and shred \ - any non-operatives in the area." - item = /obj/item/grenade/spawnergrenade/manhacks - cost = 5 - surplus = 35 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - - -//Support and Mechs - -/datum/uplink_item/support/clown_reinforcement - name = "Clown Reinforcements" - desc = "Call in an additional clown to share the fun, equipped with full starting gear, but no telecrystals." - item = /obj/item/antag_spawner/nuke_ops/clown - cost = 20 - include_modes = list(/datum/game_mode/nuclear/clown_ops) - restricted = TRUE - -/datum/uplink_item/support/reinforcement - name = "Reinforcements" - desc = "Call in an additional team member. They won't come with any gear, so you'll have to save some telecrystals \ - to arm them as well." - item = /obj/item/antag_spawner/nuke_ops - cost = 25 - refundable = TRUE - include_modes = list(/datum/game_mode/nuclear) - restricted = TRUE - -/datum/uplink_item/support/reinforcement/assault_borg - name = "Syndicate Assault Cyborg" - desc = "A cyborg designed and programmed for systematic extermination of non-Syndicate personnel. \ - Comes equipped with a self-resupplying LMG, a grenade launcher, energy sword, emag, pinpointer, flash and crowbar." - item = /obj/item/antag_spawner/nuke_ops/borg_tele/assault - refundable = TRUE - cost = 65 - restricted = TRUE - -/datum/uplink_item/support/reinforcement/medical_borg - name = "Syndicate Medical Cyborg" - desc = "A combat medical cyborg. Has limited offensive potential, but makes more than up for it with its support capabilities. \ - It comes equipped with a nanite hypospray, a medical beamgun, combat defibrillator, full surgical kit including an energy saw, an emag, pinpointer and flash. \ - Thanks to its organ storage bag, it can perform surgery as well as any humanoid." - item = /obj/item/antag_spawner/nuke_ops/borg_tele/medical - refundable = TRUE - cost = 35 - restricted = TRUE - -/datum/uplink_item/support/reinforcement/saboteur_borg - name = "Syndicate Saboteur Cyborg" - desc = "A streamlined engineering cyborg, equipped with covert modules. Also incapable of leaving the welder in the shuttle. \ - Aside from regular Engineering equipment, it comes with a special destination tagger that lets it traverse disposals networks. \ - Its chameleon projector lets it disguise itself as a Nanotrasen cyborg, on top it has thermal vision and a pinpointer." - item = /obj/item/antag_spawner/nuke_ops/borg_tele/saboteur - refundable = TRUE - cost = 35 - restricted = TRUE - -/datum/uplink_item/support/gygax - name = "Dark Gygax Exosuit" - desc = "A lightweight exosuit, painted in a dark scheme. Its speed and equipment selection make it excellent \ - for hit-and-run style attacks. Features an incendiary carbine, flash bang launcher, teleporter, ion thrusters and a Tesla energy array." - item = /obj/mecha/combat/gygax/dark/loaded - cost = 80 - -/datum/uplink_item/support/honker - name = "Dark H.O.N.K." - desc = "A clown combat mech equipped with bombanana peel and tearstache grenade launchers, as well as the ubiquitous HoNkER BlAsT 5000." - item = /obj/mecha/combat/honker/dark/loaded - cost = 80 - include_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/support/mauler - name = "Mauler Exosuit" - desc = "A massive and incredibly deadly military-grade exosuit. Features long-range targeting, thrust vectoring \ - and deployable smoke. Comes equipped with an LMG, scattershot carbine, missile rack, an antiprojectile armor booster and a Tesla energy array." - item = /obj/mecha/combat/marauder/mauler/loaded - cost = 140 - -// Stealth Items - -/datum/uplink_item/stealthy_tools/agent_card - name = "Agent Identification Card" - desc = "Agent cards prevent artificial intelligences from tracking the wearer, and can copy access \ - from other identification cards. The access is cumulative, so scanning one card does not erase the \ - access gained from another. In addition, they can be forged to display a new assignment and name. \ - This can be done an unlimited amount of times. Some Syndicate areas and devices can only be accessed \ - with these cards." - item = /obj/item/card/id/syndicate - cost = 2 - -/datum/uplink_item/stealthy_tools/ai_detector - name = "Artificial Intelligence Detector" - desc = "A functional multitool that turns red when it detects an artificial intelligence watching it, and can be \ - activated to display their exact viewing location and nearby security camera blind spots. Knowing when \ - an artificial intelligence is watching you is useful for knowing when to maintain cover, and finding nearby \ - blind spots can help you identify escape routes." - item = /obj/item/multitool/ai_detect - cost = 1 - -/datum/uplink_item/stealthy_tools/chameleon - name = "Chameleon Kit" - desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more! \ - Due to budget cuts, the shoes don't provide protection against slipping." - item = /obj/item/storage/box/syndie_kit/chameleon - cost = 2 - exclude_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/stealthy_tools/chameleon_proj - name = "Chameleon Projector" - desc = "Projects an image across a user, disguising them as an object scanned with it, as long as they don't \ - move the projector from their hand. Disguised users move slowly, and projectiles pass over them." - item = /obj/item/chameleon - cost = 7 - -/datum/uplink_item/stealthy_tools/codespeak_manual - name = "Codespeak Manual" - desc = "Syndicate agents can be trained to use a series of codewords to convey complex information, which sounds like random concepts and drinks to anyone listening. \ - This manual teaches you this Codespeak. You can also hit someone else with the manual in order to teach them. This is the deluxe edition, which has unlimited uses." - item = /obj/item/codespeak_manual/unlimited - cost = 3 - -/datum/uplink_item/stealthy_tools/combatbananashoes - name = "Combat Banana Shoes" - desc = "While making the wearer immune to most slipping attacks like regular combat clown shoes, these shoes \ - can generate a large number of synthetic banana peels as the wearer walks, slipping up would-be pursuers. They also \ - squeak significantly louder." - item = /obj/item/clothing/shoes/clown_shoes/banana_shoes/combat - cost = 6 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/stealthy_tools/emplight - name = "EMP Flashlight" - desc = "A small, self-recharging, short-ranged EMP device disguised as a working flashlight. \ - Useful for disrupting headsets, cameras, doors, lockers and borgs during stealth operations. \ - Attacking a target with this flashlight will direct an EM pulse at it and consumes a charge." - item = /obj/item/flashlight/emp - cost = 2 - surplus = 30 - -/datum/uplink_item/stealthy_tools/failsafe - name = "Failsafe Uplink Code" - desc = "When entered the uplink will self-destruct immidiately." - item = /obj/effect/gibspawner/generic - cost = 1 - surplus = 0 - restricted = TRUE - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/stealthy_tools/failsafe/spawn_item(spawn_path, mob/user, datum/component/uplink/U) - if(!U) - return - U.failsafe_code = U.generate_code() - to_chat(user, "The new failsafe code for this uplink is now : [U.failsafe_code].") - if(user.mind) - user.mind.store_memory("Failsafe code for [U.parent] : [U.failsafe_code]") - return U.parent //For log icon - -/datum/uplink_item/stealthy_tools/mulligan - name = "Mulligan" - desc = "Screwed up and have security on your tail? This handy syringe will give you a completely new identity \ - and appearance." - item = /obj/item/reagent_containers/syringe/mulligan - cost = 3 - surplus = 30 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/stealthy_tools/syndigaloshes - name = "No-Slip Chameleon Shoes" - desc = "These shoes will allow the wearer to run on wet floors and slippery objects without falling down. \ - They do not work on heavily lubricated surfaces." - item = /obj/item/clothing/shoes/chameleon/noslip - cost = 2 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - player_minimum = 20 - -/datum/uplink_item/stealthy_tools/syndigaloshes/nuke - item = /obj/item/clothing/shoes/chameleon/noslip - cost = 4 - exclude_modes = list() - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/stealthy_tools/jammer - name = "Radio Jammer" - desc = "This device will disrupt any nearby outgoing radio communication when activated. Does not affect binary chat." - item = /obj/item/jammer - cost = 5 - -/datum/uplink_item/stealthy_tools/smugglersatchel - name = "Smuggler's Satchel" - desc = "This satchel is thin enough to be hidden in the gap between plating and tiling; great for stashing \ - your stolen goods. Comes with a crowbar and a floor tile inside. Properly hidden satchels have been \ - known to survive intact even beyond the current shift. " - item = /obj/item/storage/backpack/satchel/flat - cost = 2 - surplus = 30 - -//Space Suits and Hardsuits - -/datum/uplink_item/suits/turtlenck - name = "Tactical Turtleneck" - desc = "A slightly armored suit that has no sensor on them, if someone sees you in this hope they think its a fake." - item = /obj/item/clothing/under/syndicate - cost = 1 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) //They already get these - -/datum/uplink_item/suits/turtlenck_skirt - name = "Tactical Skirtleneck" - desc = "A slightly armored suit that has no sensor on them, if someone sees you in this hope they think its a fake." - item = /obj/item/clothing/under/syndicate/skirt - cost = 1 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) //They already get these - -/datum/uplink_item/suits/padding - name = "Soft Padding" - desc = "Padding to add to a jumpsuit to help against melee and bullets." - item = /obj/item/clothing/accessory/padding - cost = 2 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/suits/kevlar - name = "Kevlar sheets" - desc = "Kevlar sheets to add to jumpsuit to help against bullets and melee." - item = /obj/item/clothing/accessory/kevlar - cost = 2 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/suits/plastic - name = "Plastic sheet" - desc = "Plastic body sheet to add to a jumpsuit to help against laser and energy harm." - item = /obj/item/clothing/accessory/plastics - cost = 2 - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/suits/space_suit - name = "Syndicate Space Suit" - desc = "This red and black Syndicate space suit is less encumbering than Nanotrasen variants, \ - fits inside bags, and has a weapon slot. Nanotrasen crew members are trained to report red space suit \ - sightings, however." - item = /obj/item/storage/box/syndie_kit/space - cost = 4 - -/datum/uplink_item/suits/hardsuit - name = "Syndicate Hardsuit" - desc = "The feared suit of a Syndicate nuclear agent. Features slightly better armoring and a built in jetpack \ - that runs off standard atmospheric tanks. Toggling the suit in and out of \ - combat mode will allow you all the mobility of a loose fitting uniform without sacrificing armoring. \ - Additionally the suit is collapsible, making it small enough to fit within a backpack. \ - Nanotrasen crew who spot these suits are known to panic." - item = /obj/item/clothing/suit/space/hardsuit/syndi - cost = 8 - exclude_modes = list(/datum/game_mode/nuclear) //you can't buy it in nuke, because the elite hardsuit costs the same while being better - -/datum/uplink_item/suits/hardsuit/elite - name = "Elite Syndicate Hardsuit" - desc = "An upgraded, elite version of the Syndicate hardsuit. It features fireproofing, and also \ - provides the user with superior armor and mobility compared to the standard Syndicate hardsuit." - item = /obj/item/clothing/suit/space/hardsuit/syndi/elite - cost = 8 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - exclude_modes = list() - -/datum/uplink_item/suits/hardsuit/shielded - name = "Shielded Syndicate Hardsuit" - desc = "An upgraded version of the standard Syndicate hardsuit. It features a built-in energy shielding system. \ - The shields can handle up to three impacts within a short duration and will rapidly recharge while not under fire." - item = /obj/item/clothing/suit/space/hardsuit/shielded/syndi - cost = 30 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - exclude_modes = list() - -// Devices and Tools - -/datum/uplink_item/device_tools/emag - name = "Cryptographic Sequencer" - desc = "The cryptographic sequencer, electromagnetic card, or emag, is a small card that unlocks hidden functions \ - in electronic devices, subverts intended functions, and easily breaks security mechanisms." - item = /obj/item/card/emag - cost = 6 - -/datum/uplink_item/device_tools/emagrecharge - name = "Electromagnet Charging Device" - desc = "A small device intended for recharging Cryptographic Sequencers. Using it will add five extra charges to the Cryptographic Sequencer." - item = /obj/item/emagrecharge - cost = 2 - -/datum/uplink_item/device_tools/phantomthief - name = "Syndicate Mask" - desc = "A cheap plastic mask fitted with an adrenaline autoinjector, which can be used by simply tensing your muscles" - item = /obj/item/clothing/glasses/phantomthief/syndicate - cost = 2 - -/datum/uplink_item/device_tools/cutouts - name = "Adaptive Cardboard Cutouts" - desc = "These cardboard cutouts are coated with a thin material that prevents discoloration and makes the images on them appear more lifelike. \ - This pack contains three as well as a crayon for changing their appearances." - item = /obj/item/storage/box/syndie_kit/cutouts - cost = 1 - surplus = 20 - -/datum/uplink_item/device_tools/assault_pod - name = "Assault Pod Targeting Device" - desc = "Use this to select the landing zone of your assault pod." - item = /obj/item/assault_pod - cost = 30 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - restricted = TRUE - -/datum/uplink_item/device_tools/binary - name = "Binary Translator Key" - desc = "A key that, when inserted into a radio headset, allows you to listen to and talk with silicon-based lifeforms, \ - such as AI units and cyborgs, over their private binary channel. Caution should \ - be taken while doing this, as unless they are allied with you, they are programmed to report such intrusions." - item = /obj/item/encryptionkey/binary - cost = 2 - surplus = 75 - restricted = TRUE - -/datum/uplink_item/device_tools/magboots - name = "Blood-Red Magboots" - desc = "A pair of magnetic boots with a Syndicate paintjob that assist with freer movement in space or on-station \ - during gravitational generator failures. These reverse-engineered knockoffs of Nanotrasen's \ - 'Advanced Magboots' slow you down in simulated-gravity environments much like the standard issue variety." - item = /obj/item/clothing/shoes/magboots/syndie - cost = 2 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/device_tools/compressionkit - name = "Bluespace Compression Kit" - desc = "A modified version of a BSRPED that can be used to reduce the size of most items while retaining their original functions! \ - Does not work on storage items. \ - Recharge using bluespace crystals. \ - Comes with 5 charges." - item = /obj/item/compressionkit - cost = 5 - -/datum/uplink_item/device_tools/briefcase_launchpad - name = "Briefcase Launchpad" - desc = "A briefcase containing a launchpad, a device able to teleport items and people to and from targets up to twenty tiles away from the briefcase. \ - Also includes a remote control, disguised as an ordinary folder. Touch the briefcase with the remote to link it." - surplus = 0 - item = /obj/item/storage/briefcase/launchpad - cost = 6 - -/datum/uplink_item/device_tools/camera_bug - name = "Camera Bug" - desc = "Enables you to view all cameras on the main network, set up motion alerts and track a target. \ - Bugging cameras allows you to disable them remotely." - item = /obj/item/camera_bug - cost = 1 - surplus = 90 - -/datum/uplink_item/device_tools/military_belt - name = "Chest Rig" - desc = "A robust seven-slot set of webbing that is capable of holding all manner of tactical equipment." - item = /obj/item/storage/belt/military - cost = 1 - exclude_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/device_tools/fakenucleardisk - name = "Decoy Nuclear Authentication Disk" - desc = "It's just a normal disk. Visually it's identical to the real deal, but it won't hold up under closer scrutiny by the Captain. \ - Don't try to give this to us to complete your objective, we know better!" - item = /obj/item/disk/nuclear/fake - cost = 1 - surplus = 1 - -/datum/uplink_item/device_tools/frame - name = "F.R.A.M.E. PDA Cartridge" - desc = "When inserted into a personal digital assistant, this cartridge gives you five PDA viruses which \ - when used cause the targeted PDA to become a new uplink with zero TCs, and immediately become unlocked. \ - You will receive the unlock code upon activating the virus, and the new uplink may be charged with \ - telecrystals normally." - item = /obj/item/cartridge/virus/frame - cost = 2 - restricted = TRUE - -/datum/uplink_item/device_tools/toolbox - name = "Full Syndicate Toolbox" - desc = "The Syndicate toolbox is a suspicious black and red. It comes loaded with a full tool set including a \ - multitool and combat gloves that are resistant to shocks and heat." - item = /obj/item/storage/toolbox/syndicate - cost = 1 - -/datum/uplink_item/device_tools/syndie_glue - name = "Glue" - desc = "A cheap bottle of one use syndicate brand super glue. \ - Use on any item to make it undroppable. \ - Be careful not to glue an item you're already holding!" - exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - item = /obj/item/syndie_glue - cost = 2 - -/datum/uplink_item/device_tools/hacked_module - name = "Hacked AI Law Upload Module" - desc = "When used with an upload console, this module allows you to upload priority laws to an artificial intelligence. \ - Be careful with wording, as artificial intelligences may look for loopholes to exploit." - item = /obj/item/aiModule/syndicate - cost = 9 - -/datum/uplink_item/device_tools/medgun - name = "Medbeam Gun" - desc = "A wonder of Syndicate engineering, the Medbeam gun, or Medi-Gun enables a medic to keep his fellow \ - operatives in the fight, even while under fire. Don't cross the streams!" - item = /obj/item/gun/medbeam - cost = 15 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/device_tools/nutcracker - name = "Nutcracker" - desc = "An oversized version of what you'd initially expect here. Big enough to crush skulls." - item = /obj/item/nutcracker - cost = 1 - -/datum/uplink_item/device_tools/singularity_beacon - name = "Power Beacon" - desc = "When screwed to wiring attached to an electric grid and activated, this large device pulls any \ - active gravitational singularities or tesla balls towards it (provided they are not safely \ - contained), as well as increasing the odds of incoming meteor waves. \ - Because of its size, it cannot be carried. Ordering this sends you a small beacon \ - that will teleport the larger beacon to your location upon activation." - item = /obj/item/sbeacondrop - cost = 14 - -/datum/uplink_item/device_tools/powersink - name = "Power Sink" - desc = "When screwed to wiring attached to a power grid and activated, this large device lights up and places excessive \ - load on the grid, causing a station-wide blackout. The sink is large and cannot be stored in most \ - traditional bags and boxes. Caution: Will explode if the powernet contains sufficient amounts of energy." - item = /obj/item/powersink - cost = 6 - -/datum/uplink_item/device_tools/rad_laser - name = "Radioactive Microlaser" - desc = "A radioactive microlaser disguised as a standard Nanotrasen health analyzer. When used, it emits a \ - powerful burst of radiation, which, after a short delay, can incapacitate all but the most protected \ - of humanoids. It has two settings: intensity, which controls the power of the radiation, \ - and wavelength, which controls the delay before the effect kicks in." - item = /obj/item/healthanalyzer/rad_laser - cost = 3 - -/datum/uplink_item/device_tools/stimpack - name = "Stimpack" - desc = "Stimpacks, the tool of many great heroes, make you nearly immune to stuns and knockdowns for about \ - 5 minutes after injection." - item = /obj/item/reagent_containers/syringe/stimulants - cost = 5 - surplus = 90 - -/datum/uplink_item/device_tools/medkit - name = "Syndicate Combat Medic Kit" - desc = "This first aid kit is a suspicious brown and red. Included is a combat stimulant injector \ - for rapid healing, a medical night vision HUD for quick identification of injured personnel, \ - and other supplies helpful for a field medic." - item = /obj/item/storage/firstaid/tactical/nukeop - cost = 4 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - -/datum/uplink_item/device_tools/surgerybag - name = "Syndicate Surgery Duffel Bag" - desc = "The Syndicate surgery duffel bag is a toolkit containing all surgery tools, surgical drapes, \ - a Syndicate brand MMI, a straitjacket, and a muzzle." - item = /obj/item/storage/backpack/duffelbag/syndie/surgery - cost = 3 - -/datum/uplink_item/device_tools/surgerybag_adv - name = "Advanced Syndicate Surgery Duffel Bag" - desc = "The Syndicate surgery duffel bag is a toolkit containing all advanced surgery tools, surgical drapes, \ - a Syndicate brand MMI, a straitjacket, a muzzle, and an outdated, yet still useful Combat Medic Kit." - item = /obj/item/storage/backpack/duffelbag/syndie/surgery_adv - cost = 10 - -/datum/uplink_item/device_tools/brainwash_disk - name = "Brainwashing Surgery Program" - desc = "A disk containing the procedure to perform a brainwashing surgery, allowing you to implant an objective onto a target. \ - Insert into an Operating Console to enable the procedure." - item = /obj/item/disk/surgery/brainwashing - cost = 3 - -/datum/uplink_item/device_tools/encryptionkey - name = "Syndicate Encryption Key" - desc = "A key that, when inserted into a radio headset, allows you to listen to all station department channels \ - as well as talk on an encrypted Syndicate channel with other agents that have the same key." - item = /obj/item/encryptionkey/syndicate - cost = 2 - surplus = 75 - restricted = TRUE - -/datum/uplink_item/device_tools/syndietome - name = "Syndicate Tome" - desc = "Using rare artifacts acquired at great cost, the Syndicate has reverse engineered \ - the seemingly magical books of a certain cult. Though lacking the esoteric abilities \ - of the originals, these inferior copies are still quite useful, being able to provide \ - both weal and woe on the battlefield, even if they do occasionally bite off a finger." - item = /obj/item/storage/book/bible/syndicate - cost = 9 - -/datum/uplink_item/device_tools/thermal - name = "Thermal Imaging Glasses" - desc = "These goggles can be turned to resemble common eyewear found throughout the station. \ - They allow you to see organisms through walls by capturing the upper portion of the infrared light spectrum, \ - emitted as heat and light by objects. Hotter objects, such as warm bodies, cybernetic organisms \ - and artificial intelligence cores emit more of this light than cooler objects like walls and airlocks." - item = /obj/item/clothing/glasses/thermal/syndi - cost = 4 - -/datum/uplink_item/device_tools/potion - name = "Syndicate Sentience Potion" - item = /obj/item/slimepotion/slime/sentience/nuclear - desc = "A potion recovered at great risk by undercover Syndicate operatives and then subsequently modified with Syndicate technology. \ - Using it will make any animal sentient, and bound to serve you, as well as implanting an internal radio for communication and an internal ID card for opening doors." - cost = 2 - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - restricted = TRUE - - -// Implants - -/datum/uplink_item/implants/adrenal - name = "Adrenal Implant" - desc = "An implant injected into the body, and later activated at the user's will. It will inject a chemical \ - cocktail which removes all incapacitating effects, lets the user run faster and has a mild healing effect." - item = /obj/item/storage/box/syndie_kit/imp_adrenal - cost = 8 - player_minimum = 25 - -/datum/uplink_item/implants/antistun - name = "CNS Rebooter Implant" - desc = "This implant will help you get back up on your feet faster after being stunned. Comes with an autosurgeon." - item = /obj/item/autosurgeon/anti_stun - cost = 12 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/implants/freedom - name = "Freedom Implant" - desc = "An implant injected into the body and later activated at the user's will. It will attempt to free the \ - user from common restraints such as handcuffs." - item = /obj/item/storage/box/syndie_kit/imp_freedom - cost = 5 - -/datum/uplink_item/implants/microbomb - name = "Microbomb Implant" - desc = "An implant injected into the body, and later activated either manually or automatically upon death. \ - The more implants inside of you, the higher the explosive power. \ - This will permanently destroy your body, however." - item = /obj/item/storage/box/syndie_kit/imp_microbomb - cost = 2 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/implants/macrobomb - name = "Macrobomb Implant" - desc = "An implant injected into the body, and later activated either manually or automatically upon death. \ - Upon death, releases a massive explosion that will wipe out everything nearby." - item = /obj/item/storage/box/syndie_kit/imp_macrobomb - cost = 20 - include_modes = list(/datum/game_mode/nuclear) - restricted = TRUE - -/datum/uplink_item/implants/radio - name = "Internal Syndicate Radio Implant" - desc = "An implant injected into the body, allowing the use of an internal Syndicate radio. \ - Used just like a regular headset, but can be disabled to use external headsets normally and to avoid detection." - item = /obj/item/storage/box/syndie_kit/imp_radio - cost = 4 - restricted = TRUE - -/datum/uplink_item/implants/reviver - name = "Reviver Implant" - desc = "This implant will attempt to revive and heal you if you lose consciousness. Comes with an autosurgeon." - item = /obj/item/autosurgeon/reviver - cost = 8 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/implants/stealthimplant - name = "Stealth Implant" - desc = "This one-of-a-kind implant will make you almost invisible as long as you don't don't excessively move around. \ - On activation, it will conceal you inside a chameleon cardboard box that is only revealed once someone bumps into it." - item = /obj/item/implanter/stealth - cost = 8 - -/datum/uplink_item/implants/storage - name = "Storage Implant" - desc = "An implant injected into the body, and later activated at the user's will. It will open a small bluespace \ - pocket capable of storing two regular-sized items." - item = /obj/item/storage/box/syndie_kit/imp_storage - cost = 8 - -/datum/uplink_item/implants/thermals - name = "Thermal Eyes" - desc = "These cybernetic eyes will give you thermal vision. Comes with a free autosurgeon." - item = /obj/item/autosurgeon/thermal_eyes - cost = 8 - include_modes = list(/datum/game_mode/nuclear) - -/datum/uplink_item/implants/uplink - name = "Uplink Implant" - desc = "An implant injected into the body, and later activated at the user's will. Has no telecrystals and must be charged by the use of physical telecrystals. \ - Undetectable (except via surgery), and excellent for escaping confinement." - item = /obj/item/storage/box/syndie_kit/imp_uplink - cost = 4 - // An empty uplink is kinda useless. - surplus = 0 - restricted = TRUE - -/datum/uplink_item/implants/xray - name = "X-ray Vision Implant" - desc = "These cybernetic eyes will give you X-ray vision. Comes with an autosurgeon." - item = /obj/item/autosurgeon/xray_eyes - cost = 10 - surplus = 0 - include_modes = list(/datum/game_mode/nuclear) - -// Role-specific items - -/datum/uplink_item/role_restricted/ancient_jumpsuit - name = "Ancient Jumpsuit" - desc = "A tattered old jumpsuit that will provide absolutely no benefit to you. It fills the wearer with a strange compulsion to blurt out 'glorf'." - item = /obj/item/clothing/under/color/grey/glorf - cost = 20 - restricted_roles = list("Assistant") - -/datum/uplink_item/role_restricted/pie_cannon - name = "Banana Cream Pie Cannon" - desc = "A special pie cannon for a special clown, this gadget can hold up to 20 pies and automatically fabricates one every two seconds!" - cost = 10 - item = /obj/item/pneumatic_cannon/pie/selfcharge - restricted_roles = list("Clown") - -/datum/uplink_item/role_restricted/blastcannon - name = "Blast Cannon" - desc = "A highly specialized weapon, the Blast Cannon is actually relatively simple. It contains an attachment for a tank transfer valve mounted to an angled pipe specially constructed \ - withstand extreme pressure and temperatures, and has a mechanical trigger for triggering the transfer valve. Essentially, it turns the explosive force of a bomb into a narrow-angle \ - blast wave \"projectile\". Aspiring scientists may find this highly useful, as forcing the pressure shockwave into a narrow angle seems to be able to bypass whatever quirk of physics \ - disallows explosive ranges above a certain distance, allowing for the device to use the theoretical yield of a transfer valve bomb, instead of the factual yield." - item = /obj/item/gun/blastcannon - cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled gas masked scientist. - restricted_roles = list("Research Director", "Scientist") - -/datum/uplink_item/role_restricted/alientech - name = "Alien Research Disk" - desc = "A technology disk holding a terabyte of highly confidential abductor technology. \ - Simply insert into research console of choice and import the files from the disk. Because of its foreign nature, it may require multiple uploads to work properly." - item = /obj/item/disk/tech_disk/abductor - cost = 12 - restricted_roles = list("Research Director", "Scientist", "Roboticist") - -/datum/uplink_item/role_restricted/clown_bomb - name = "Clown Bomb" - desc = "The Clown bomb is a hilarious device capable of massive pranks. It has an adjustable timer, \ - with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ - movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ - transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ - be defused, and some crew may attempt to do so. \ - The bomb core can be pried out and manually detonated with other explosives." - item = /obj/item/sbeacondrop/clownbomb - cost = 15 - restricted_roles = list("Clown") - -/* -/datum/uplink_item/role_restricted/clowncar - name = "Clown Car" - desc = "The Clown Car is the ultimate transportation method for any worthy clown! \ - Simply insert your bikehorn and get in, and get ready to have the funniest ride of your life! \ - You can ram any spacemen you come across and stuff them into your car, kidnapping them and locking them inside until \ - someone saves them or they manage to crawl out. Be sure not to ram into any walls or vending machines, as the springloaded seats \ - are very sensetive. Now with our included lube defense mechanism which will protect you against any angry shitcurity!" - item = /obj/vehicle/sealed/car/clowncar - cost = 15 - restricted_roles = list("Clown") -*/ - -/datum/uplink_item/role_restricted/clumsyDNA - name = "Clumsy Clown DNA" - desc = "A DNA injector that has been loaded with the clown gene that makes people clumsy.. \ - Making someone clumsy will allow them to use clown firing pins as well as Reverse Revolvers. For a laugh try using this on the HOS to see how many times they shoot themselves in the foot!" - cost = 1 - item = /obj/item/dnainjector/clumsymut - restricted_roles = list("Clown") - -/datum/uplink_item/role_restricted/haunted_magic_eightball - name = "Haunted Magic Eightball" - desc = "Most magic eightballs are toys with dice inside. Although identical in appearance to the harmless toys, this occult device reaches into the spirit world to find its answers. \ - Be warned, that spirits are often capricious or just little assholes. To use, simply speak your question aloud, then begin shaking." - item = /obj/item/toy/eightball/haunted - cost = 2 - restricted_roles = list("Curator") - limited_stock = 1 //please don't spam deadchat - -/datum/uplink_item/role_restricted/his_grace - name = "His Grace" - desc = "An incredibly dangerous weapon recovered from a station overcome by the grey tide. Once activated, He will thirst for blood and must be used to kill to sate that thirst. \ - His Grace grants gradual regeneration and complete stun immunity to His wielder, but be wary: if He gets too hungry, He will become impossible to drop and eventually kill you if not fed. \ - However, if left alone for long enough, He will fall back to slumber. \ - To activate His Grace, simply unlatch Him." - item = /obj/item/his_grace - cost = 20 - restricted_roles = list("Chaplain") - surplus = 5 //Very low chance to get it in a surplus crate even without being the chaplain - -/datum/uplink_item/role_restricted/explosive_hot_potato - name = "Exploding Hot Potato" - desc = "A potato rigged with explosives. On activation, a special mechanism is activated that prevents it from being dropped. \ - The only way to get rid of it if you are holding it is to attack someone else with it, causing it to latch to that person instead." - item = /obj/item/hot_potato/syndicate - cost = 4 - restricted_roles = list("Cook", "Botanist", "Clown", "Mime") - -/datum/uplink_item/role_restricted/strange_seeds - name = "Pack of strange seeds" - desc = "Mysterious seeds as strange as their name implies. Spooky." - item = /obj/item/seeds/random - cost = 2 - restricted_roles = list("Botanist") - illegal_tech = FALSE - -/datum/uplink_item/role_restricted/strange_seeds_10pack - name = "Pack of strange seeds x10" - desc = "Mysterious seeds as strange as their name implies. Spooky. These come in bulk" - item = /obj/item/storage/box/strange_seeds_10pack - cost = 20 - restricted_roles = list("Botanist") - -/datum/uplink_item/role_restricted/ez_clean_bundle - name = "EZ Clean Grenade Bundle" - desc = "A box with three cleaner grenades using the trademark Waffle Co. formula. Serves as a cleaner and causes acid damage to anyone standing nearby. \ - The acid only affects carbon-based creatures." - item = /obj/item/storage/box/syndie_kit/ez_clean - cost = 6 - surplus = 20 - restricted_roles = list("Janitor") - -/datum/uplink_item/role_restricted/goldenbox - name = "Gold Toolbox" - desc = "A gold planted plastitanium toolbox loaded with tools. Comes with a set of AI detection multi-tool and a pare of combat gloves." - item = /obj/item/storage/toolbox/gold_real - cost = 3 // Has syndie tools + gloves + a robust weapon - restricted_roles = list("Assistant", "Curator") //Curator due to this being made of gold - It fits the theme - -/datum/uplink_item/role_restricted/mimery - name = "Guide to Advanced Mimery Series" - desc = "The classical two part series on how to further hone your mime skills. Upon studying the series, the user should be able to make 3x1 invisible walls, and shoot bullets out of their fingers. \ - Obviously only works for Mimes." - cost = 12 - item = /obj/item/storage/box/syndie_kit/mimery - restricted_roles = list("Mime") - -/datum/uplink_item/role_restricted/ultrahonkpins - name = "Hilarious firing pin" - desc = "A single firing pin made for Clown agents, this firing pin makes any gun honk when fired if not a true clown! \ - This firing pin also helps you fire the gun correctly. May the HonkMother HONK you agent." - item = /obj/item/firing_pin/clown/ultra - cost = 2 - restricted_roles = list("Clown") - -/datum/uplink_item/role_restricted/pressure_mod - name = "Kinetic Accelerator Pressure Mod" - desc = "A modification kit which allows Kinetic Accelerators to do greatly increased damage while indoors. \ - Occupies 35% mod capacity." - item = /obj/item/borg/upgrade/modkit/indoors - cost = 5 //you need two for full damage, so total of 10 for maximum damage - limited_stock = 2 //you can't use more than two! - restricted_roles = list("Shaft Miner") - -/datum/uplink_item/role_restricted/kitchen_gun - name = "Kitchen Gun (TM)" - desc = "A revolutionary .45 caliber cleaning solution! Say goodbye to daily stains and dirty surfaces with Kitchen Gun (TM)! \ - Just five shots from Kitchen Gun (TM), and it'll sparkle like new! Includes two extra ammunition clips!" - cost = 10 - surplus = 40 - restricted_roles = list("Cook", "Janitor") - item = /obj/item/storage/box/syndie_kit/kitchen_gun - -/datum/uplink_item/role_restricted/kitchen_gun_ammo - name = "Kitchen Gun (TM) .45 Magazine" - desc = "An extra eight bullets for an extra eight uses of Kitchen Gun (TM)!" - cost = 1 - restricted_roles = list("Cook", "Janitor") - item = /obj/item/ammo_box/magazine/m45/kitchengun - -/datum/uplink_item/role_restricted/magillitis_serum - name = "Magillitis Serum Autoinjector" - desc = "A single-use autoinjector which contains an experimental serum that causes rapid muscular growth in Hominidae. \ - Side-affects may include hypertrichosis, violent outbursts, and an unending affinity for bananas." - item = /obj/item/reagent_containers/hypospray/magillitis - cost = 8 - restricted_roles = list("Geneticist", "Chief Medical Officer") - -/datum/uplink_item/role_restricted/modified_syringe_gun - name = "Modified Syringe Gun" - desc = "A syringe gun that fires DNA injectors instead of normal syringes." - item = /obj/item/gun/syringe/dna - cost = 14 - restricted_roles = list("Geneticist", "Chief Medical Officer") - -/datum/uplink_item/role_restricted/chemical_gun - name = "Reagent Dartgun" - desc = "A heavily modified syringe gun which is capable of synthesizing its own chemical darts using input reagents. Can hold 100u of reagents." - item = /obj/item/gun/chem - cost = 12 - restricted_roles = list("Chemist", "Chief Medical Officer") - -/datum/uplink_item/role_restricted/reverse_bear_trap - name = "Reverse Bear Trap" - desc = "An ingenious execution device worn on (or forced onto) the head. Arming it starts a 1-minute kitchen timer mounted on the bear trap. When it goes off, the trap's jaws will \ - violently open, instantly killing anyone wearing it by tearing their jaws in half. To arm, attack someone with it while they're not wearing headgear, and you will force it onto their \ - head after three seconds uninterrupted." - cost = 5 - item = /obj/item/reverse_bear_trap - restricted_roles = list("Clown") - -/datum/uplink_item/role_restricted/reverse_revolver - name = "Reverse Revolver" - desc = "A revolver that always fires at its user. \"Accidentally\" drop your weapon, then watch as the greedy corporate pigs blow their own brains all over the wall. \ - The revolver itself is actually real. Only clumsy people, and clowns, can fire it normally. Comes in a box of hugs. Honk." - cost = 14 - item = /obj/item/storage/box/hug/reverse_revolver - restricted_roles = list("Clown") - -/datum/uplink_item/role_restricted/taeclowndo_shoes - name = "Tae-clown-do Shoes" - desc = "A pair of shoes for the most elite agents of the honkmotherland. They grant the mastery of taeclowndo with some honk-fu moves as long as they're worn." - cost = 14 - item = /obj/item/clothing/shoes/clown_shoes/taeclowndo - restricted_roles = list("Clown") - -/datum/uplink_item/role_restricted/emitter_cannon - name = "Emitter Cannon" - desc = "A small emitter fitted into a gun case, do to size constraints and safety it can only shoot about ten times when fully charged." - cost = 5 //Low ammo, and deals same as 10mm but emp-able - item = /obj/item/gun/energy/emitter - restricted_roles = list("Chief Engineer", "Station Engineer", "Atmospheric Technician") - -// Pointless (Badassery) - -/datum/uplink_item/badass/costumes/obvious_chameleon - name = "Broken Chameleon Kit" - desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more! \ - Please note that this kit did NOT pass quality control." - item = /obj/item/storage/box/syndie_kit/chameleon/broken - -/datum/uplink_item/badass/costumes - include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) - cost = 4 - cant_discount = TRUE - -/datum/uplink_item/badass/costumes/centcom_official - name = "CentCom Official Costume" - desc = "Ask the crew to \"inspect\" their nuclear disk and weapons system, and then when they decline, pull out a fully automatic rifle and gun down the Captain. \ - Radio headset does not include encryption key. No gun included." - item = /obj/item/storage/box/syndie_kit/centcom_costume - -/datum/uplink_item/badass/claymore - name = "Claymore" - cost = 8 - player_minimum = 25 - desc = "A claymore. We don't know why you'd do this." - item = /obj/item/claymore - -/datum/uplink_item/badass/costumes/clown - name = "Clown Costume" - desc = "Nothing is more terrifying than clowns with fully automatic weaponry." - item = /obj/item/storage/backpack/duffelbag/clown/syndie - -/datum/uplink_item/badass/plastitanium_toolbox - name = "Plastitanium Toolbox" - desc = "A very high impact toolbox. Excels at destroying stationary structures." - item = /obj/item/storage/toolbox/plastitanium - cost = 2 //18 damage on mobs, 50 on objects, 4.5 stam/hit - -/datum/uplink_item/badass/balloon - name = "Syndicate Balloon" - desc = "For showing that you are THE BOSS: A useless red balloon with the Syndicate logo on it. \ - Can blow the deepest of covers." - item = /obj/item/toy/syndicateballoon - cost = 20 - cant_discount = TRUE - illegal_tech = FALSE - -/datum/uplink_item/badass/syndiecash - name = "Syndicate Briefcase Full of Cash" - desc = "A secure briefcase containing 5000 space credits. Useful for bribing personnel, or purchasing goods \ - and services at lucrative prices. The briefcase also feels a little heavier to hold; it has been \ - manufactured to pack a little bit more of a punch if your client needs some convincing." - item = /obj/item/storage/secure/briefcase/syndie - cost = 1 - -/datum/uplink_item/badass/syndiecards - name = "Syndicate Playing Cards" - desc = "A special deck of space-grade playing cards with a mono-molecular edge and metal reinforcement, \ - making them slightly more robust than a normal deck of cards. \ - You can also play card games with them or leave them on your victims." - item = /obj/item/toy/cards/deck/syndicate - cost = 1 - surplus = 40 - illegal_tech = FALSE - -/datum/uplink_item/badass/syndiecigs - name = "Syndicate Smokes" - desc = "Strong flavor, dense smoke, infused with omnizine." - item = /obj/item/storage/fancy/cigarettes/cigpack_syndicate - cost = 2 - illegal_tech = FALSE + category = "Discounted Gear" \ No newline at end of file diff --git a/code/modules/uplink/uplink_items/uplink_ammo.dm b/code/modules/uplink/uplink_items/uplink_ammo.dm new file mode 100644 index 0000000000..0db1bc96f0 --- /dev/null +++ b/code/modules/uplink/uplink_items/uplink_ammo.dm @@ -0,0 +1,255 @@ + +/* + Uplink Items: + Unlike categories, uplink item entries are automatically sorted alphabetically on server init in a global list, + When adding new entries to the file, please keep them sorted by category. +*/ + +// Ammunition + +/datum/uplink_item/ammo/pistol + name = "10mm Handgun Magazine" + desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. These rounds \ + are dirt cheap but are half as effective as .357 rounds." + item = /obj/item/ammo_box/magazine/m10mm + cost = 1 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/ammo/pistolap + name = "10mm Armour Piercing Magazine" + desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. \ + These rounds are less effective at injuring the target but penetrate protective gear." + item = /obj/item/ammo_box/magazine/m10mm/ap + cost = 2 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/ammo/pistolhp + name = "10mm Hollow Point Magazine" + desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. \ + These rounds are more damaging but ineffective against armour." + item = /obj/item/ammo_box/magazine/m10mm/hp + cost = 3 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/ammo/pistolfire + name = "10mm Incendiary Magazine" + desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. \ + Loaded with incendiary rounds which inflict little damage, but ignite the target." + item = /obj/item/ammo_box/magazine/m10mm/fire + cost = 2 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/ammo/pistolzzz + name = "10mm Soporific Magazine" + desc = "An additional 8-round 10mm magazine; compatible with the Stechkin Pistol. Loaded with soporific rounds that put the target to sleep. \ + NOTE: Soporific is not instant acting due to the constraints of the round's scale. Will usually require three shots to take effect." + item = /obj/item/ammo_box/magazine/m10mm/soporific + cost = 2 + +/datum/uplink_item/ammo/shotgun + cost = 2 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/shotgun/bag + name = "12g Ammo Duffel Bag" + desc = "A duffel bag filled with enough 12g ammo to supply an entire team, at a discounted price." + item = /obj/item/storage/backpack/duffelbag/syndie/ammo/shotgun + cost = 12 + +/datum/uplink_item/ammo/shotgun/buck + name = "12g Buckshot Drum" + desc = "An additional 8-round buckshot magazine for use with the Bulldog shotgun. Front towards enemy." + item = /obj/item/ammo_box/magazine/m12g + +/datum/uplink_item/ammo/shotgun/dragon + name = "12g Dragon's Breath Drum" + desc = "An alternative 8-round dragon's breath magazine for use in the Bulldog shotgun. \ + 'I'm a fire starter, twisted fire starter!'" + item = /obj/item/ammo_box/magazine/m12g/dragon + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/shotgun/meteor + name = "12g Meteorslug Shells" + desc = "An alternative 8-round meteorslug magazine for use in the Bulldog shotgun. \ + Great for blasting airlocks off their frames and knocking down enemies." + item = /obj/item/ammo_box/magazine/m12g/meteor + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/shotgun/scatter + name = "12g Scatter Laser shot Slugs" + desc = "An alternative 8-round Scatter Laser Shot magazine for use in the Bulldog shotgun." + item = /obj/item/ammo_box/magazine/m12g/scatter + cost = 4 // most armor has less laser protection then bullet + +/datum/uplink_item/ammo/shotgun/slug + name = "12g Slug Drum" + desc = "An additional 8-round slug magazine for use with the Bulldog shotgun. \ + Now 8 times less likely to shoot your pals." + cost = 3 + item = /obj/item/ammo_box/magazine/m12g/slug + +/datum/uplink_item/ammo/shotgun/stun + name = "12g Stun Slug Drum" + desc = "An alternative 8-round stun slug magazine for use with the Bulldog shotgun. \ + Saying that they're completely non-lethal would be lying." + item = /obj/item/ammo_box/magazine/m12g/stun + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/revolver + name = ".357 Speed Loader" + desc = "A speed loader that contains seven additional .357 Magnum rounds, and can be further reloaded with individual bullets; usable with the Syndicate revolver. \ + For when you really need a lot of things dead." + item = /obj/item/ammo_box/a357 + cost = 3 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/ammo/revolver/ap + name = ".357 Armor Piercing Speed Loader" + desc = "A speed loader that contains seven additional .357 AP Magnum rounds; usable with the Syndicate revolver. \ + Cuts through like a hot knife through butter." + item = /obj/item/ammo_box/a357/ap + +/datum/uplink_item/ammo/a40mm + name = "40mm Grenade" + desc = "A 40mm HE grenade for use with the M-90gl's under-barrel grenade launcher. \ + Your teammates will ask you to not shoot these down small hallways." + item = /obj/item/ammo_casing/a40mm + cost = 2 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/smg/bag + name = ".45 Ammo Duffel Bag" + desc = "A duffel bag filled with enough .45 ammo to supply an entire team, at a discounted price." + item = /obj/item/storage/backpack/duffelbag/syndie/ammo/smg + cost = 20 //instead of 27 TC + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/smg + name = ".45 SMG Magazine" + desc = "An additional 24-round .45 magazine suitable for use with the C-20r submachine gun." + item = /obj/item/ammo_box/magazine/smgm45 + cost = 3 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/sniper + cost = 4 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/sniper/basic + name = ".50 Magazine" + desc = "An additional standard 6-round magazine for use with .50 sniper rifles." + item = /obj/item/ammo_box/magazine/sniper_rounds + +/datum/uplink_item/ammo/sniper/penetrator + name = ".50 Penetrator Magazine" + desc = "A 5-round magazine of penetrator ammo designed for use with .50 sniper rifles. \ + Can pierce walls and multiple enemies." + item = /obj/item/ammo_box/magazine/sniper_rounds/penetrator + cost = 5 + +/datum/uplink_item/ammo/sniper/soporific + name = ".50 Soporific Magazine" + desc = "A 3-round magazine of soporific ammo designed for use with .50 sniper rifles. Put your enemies to sleep today!" + item = /obj/item/ammo_box/magazine/sniper_rounds/soporific + cost = 6 + +/datum/uplink_item/ammo/carbine + name = "5.56mm Toploader Magazine" + desc = "An additional 30-round 5.56mm magazine; suitable for use with the M-90gl carbine. \ + These bullets pack less punch than 7.12x82mm rounds, but they still offer more power than .45 ammo." + item = /obj/item/ammo_box/magazine/m556 + cost = 4 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/machinegun + cost = 6 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/machinegun/basic + name = "1.95x129mm Box Magazine" + desc = "A 50-round magazine of 1.95x129mm ammunition for use with the L6 SAW. \ + By the time you need to use this, you'll already be standing on a pile of corpses" + item = /obj/item/ammo_box/magazine/mm195x129 + +/datum/uplink_item/ammo/machinegun/ap + name = "1.95x129mm (Armor Penetrating) Box Magazine" + desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with special properties \ + to puncture even the most durable armor." + item = /obj/item/ammo_box/magazine/mm195x129/ap + cost = 9 + +/datum/uplink_item/ammo/machinegun/hollow + name = "1.95x129mm (Hollow-Point) Box Magazine" + desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; equipped with hollow-point tips to help \ + with the unarmored masses of crew." + item = /obj/item/ammo_box/magazine/mm195x129/hollow + +/datum/uplink_item/ammo/machinegun/incen + name = "1.95x129mm (Incendiary) Box Magazine" + desc = "A 50-round magazine of 1.95x129mm ammunition for use in the L6 SAW; tipped with a special flammable \ + mixture that'll ignite anyone struck by the bullet. Some men just want to watch the world burn." + item = /obj/item/ammo_box/magazine/mm195x129/incen + +/datum/uplink_item/ammo/rocket + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/rocket/basic + name = "84mm HE Rocket" + desc = "A low-yield anti-personnel HE rocket. Gonna take you out in style!" + item = /obj/item/ammo_casing/caseless/rocket + cost = 4 + +/datum/uplink_item/ammo/rocket/hedp + name = "84mm HEDP Rocket" + desc = "A high-yield HEDP rocket; extremely effective against armored targets, as well as surrounding personnel. \ + Strike fear into the hearts of your enemies." + item = /obj/item/ammo_casing/caseless/rocket/hedp + cost = 6 + +/datum/uplink_item/ammo/pistolaps + name = "9mm Handgun Magazine" + desc = "An additional 15-round 9mm magazine, compatible with the Stechkin APS pistol, found in the Spetsnaz Pyro bundle." + item = /obj/item/ammo_box/magazine/pistolm9mm + cost = 2 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/flechetteap + name = "Armor Piercing Flechette Magazine" + desc = "An additional 40-round flechette magazine; compatible with the Flechette Launcer. \ + Loaded with armor piercing flechettes that very nearly ignore armor, but are not very effective agaisnt flesh." + item = /obj/item/ammo_box/magazine/flechette + cost = 2 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/flechettes + name = "Serrated Flechette Magazine" + desc = "An additional 40-round flechette magazine; compatible with the Flechette Launcer. \ + Loaded with serrated flechettes that shreds flesh, but is stopped dead in its tracks by armor. \ + These flechettes are highly likely to sever arteries, and even limbs." + item = /obj/item/ammo_box/magazine/flechette/s + cost = 2 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/ammo/toydarts + name = "Box of Riot Darts" + desc = "A box of 40 Donksoft riot darts, for reloading any compatible foam dart magazine. Don't forget to share!" + item = /obj/item/ammo_box/foambox/riot + cost = 2 + surplus = 0 + illegal_tech = FALSE + +/datum/uplink_item/ammo/bioterror + name = "Box of Bioterror Syringes" + desc = "A box full of preloaded syringes, containing various chemicals that seize up the victim's motor \ + and broca systems, making it impossible for them to move or speak for some time." + item = /obj/item/storage/box/syndie_kit/bioterror + cost = 6 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/ammo/bolt_action + name = "Surplus Rifle Clip" + desc = "A stripper clip used to quickly load bolt action rifles. Contains 5 rounds." + item = /obj/item/ammo_box/a762 + cost = 1 + include_modes = list(/datum/game_mode/nuclear) diff --git a/code/modules/uplink/uplink_items/uplink_badass.dm b/code/modules/uplink/uplink_items/uplink_badass.dm new file mode 100644 index 0000000000..8dc5afbadd --- /dev/null +++ b/code/modules/uplink/uplink_items/uplink_badass.dm @@ -0,0 +1,77 @@ + +/* + Uplink Items: + Unlike categories, uplink item entries are automatically sorted alphabetically on server init in a global list, + When adding new entries to the file, please keep them sorted by category. +*/ + +// Pointless (Badassery) + +/datum/uplink_item/badass/costumes/obvious_chameleon + name = "Broken Chameleon Kit" + desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more! \ + Please note that this kit did NOT pass quality control." + item = /obj/item/storage/box/syndie_kit/chameleon/broken + +/datum/uplink_item/badass/costumes + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + cost = 4 + cant_discount = TRUE + +/datum/uplink_item/badass/costumes/centcom_official + name = "CentCom Official Costume" + desc = "Ask the crew to \"inspect\" their nuclear disk and weapons system, and then when they decline, pull out a fully automatic rifle and gun down the Captain. \ + Radio headset does not include encryption key. No gun included." + item = /obj/item/storage/box/syndie_kit/centcom_costume + +/datum/uplink_item/badass/claymore + name = "Claymore" + cost = 8 + player_minimum = 25 + desc = "A claymore. We don't know why you'd do this." + item = /obj/item/claymore + +/datum/uplink_item/badass/costumes/clown + name = "Clown Costume" + desc = "Nothing is more terrifying than clowns with fully automatic weaponry." + item = /obj/item/storage/backpack/duffelbag/clown/syndie + +/datum/uplink_item/badass/plastitanium_toolbox + name = "Plastitanium Toolbox" + desc = "A very high impact toolbox. Excels at destroying stationary structures." + item = /obj/item/storage/toolbox/plastitanium + cost = 2 //18 damage on mobs, 50 on objects, 4.5 stam/hit + +/datum/uplink_item/badass/balloon + name = "Syndicate Balloon" + desc = "For showing that you are THE BOSS: A useless red balloon with the Syndicate logo on it. \ + Can blow the deepest of covers." + item = /obj/item/toy/syndicateballoon + cost = 20 + cant_discount = TRUE + illegal_tech = FALSE + +/datum/uplink_item/badass/syndiecash + name = "Syndicate Briefcase Full of Cash" + desc = "A secure briefcase containing 5000 space credits. Useful for bribing personnel, or purchasing goods \ + and services at lucrative prices. The briefcase also feels a little heavier to hold; it has been \ + manufactured to pack a little bit more of a punch if your client needs some convincing." + item = /obj/item/storage/secure/briefcase/syndie + cost = 1 + +/datum/uplink_item/badass/syndiecards + name = "Syndicate Playing Cards" + desc = "A special deck of space-grade playing cards with a mono-molecular edge and metal reinforcement, \ + making them slightly more robust than a normal deck of cards. \ + You can also play card games with them or leave them on your victims." + item = /obj/item/toy/cards/deck/syndicate + cost = 1 + surplus = 40 + illegal_tech = FALSE + +/datum/uplink_item/badass/syndiecigs + name = "Syndicate Smokes" + desc = "Strong flavor, dense smoke, infused with omnizine." + item = /obj/item/storage/fancy/cigarettes/cigpack_syndicate + cost = 2 + illegal_tech = FALSE diff --git a/code/modules/uplink/uplink_items/uplink_bundles.dm b/code/modules/uplink/uplink_items/uplink_bundles.dm new file mode 100644 index 0000000000..23fb23f198 --- /dev/null +++ b/code/modules/uplink/uplink_items/uplink_bundles.dm @@ -0,0 +1,179 @@ + +//All bundles and telecrystals + +/* + Uplink Items: + Unlike categories, uplink item entries are automatically sorted alphabetically on server init in a global list, + When adding new entries to the file, please keep them sorted by category. +*/ + +/datum/uplink_item/bundles_TC/chemical + name = "Bioterror bundle" + desc = "For the madman: Contains a handheld Bioterror chem sprayer, a Bioterror foam grenade, a box of lethal chemicals, a dart pistol, \ + box of syringes, Donksoft assault rifle, and some riot darts. Remember: Seal suit and equip internals before use." + item = /obj/item/storage/backpack/duffelbag/syndie/med/bioterrorbundle + cost = 30 // normally 42 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/bulldog + name = "Bulldog bundle" + desc = "Lean and mean: Optimized for people that want to get up close and personal. Contains the popular \ + Bulldog shotgun, a 12g buckshot drum, a 12g taser slug drum and a pair of Thermal imaging goggles." + item = /obj/item/storage/backpack/duffelbag/syndie/bulldogbundle + cost = 13 // normally 16 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/c20r + name = "C-20r bundle" + desc = "Old Faithful: The classic C-20r, bundled with two magazines, and a (surplus) suppressor at discount price." + item = /obj/item/storage/backpack/duffelbag/syndie/c20rbundle + cost = 14 // normally 16 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/cybernetics_bundle + name = "Cybernetic Implants Bundle" + desc = "A random selection of cybernetic implants. Guaranteed 5 high quality implants. Comes with an autosurgeon." + item = /obj/item/storage/box/cyber_implants + cost = 40 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/medical + name = "Medical bundle" + desc = "The support specialist: Aid your fellow operatives with this medical bundle. Contains a tactical medkit, \ + a Donksoft LMG, a box of riot darts and a pair of magboots to rescue your friends in no-gravity environments." + item = /obj/item/storage/backpack/duffelbag/syndie/med/medicalbundle + cost = 15 // normally 20 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/modular + name = "Modular Pistol Kit" + desc = "A heavy briefcase containing one modular pistol (chambered in 10mm), one supressor, and spare ammunition, including a box of soporific ammo. \ + Includes a suit jacket that is padded with a robust liner." + item = /obj/item/storage/briefcase/modularbundle + cost = 12 + +/datum/uplink_item/bundles_TC/shredder + name = "Shredder bundle" + desc = "A truly horrific weapon designed simply to maim its victim, the CX Shredder is banned by several intergalactic treaties. \ + You'll get two of them with this. And spare ammo to boot. And we'll throw in an extra elite hardsuit and chest rig to hold them all!" + item = /obj/item/storage/backpack/duffelbag/syndie/shredderbundle + cost = 30 // normally 41 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/sniper + name = "Sniper bundle" + desc = "Elegant and refined: Contains a collapsed sniper rifle in an expensive carrying case, \ + two soporific knockout magazines, a free surplus supressor, and a sharp-looking tactical turtleneck suit. \ + We'll throw in a free red tie if you order NOW." + item = /obj/item/storage/briefcase/sniperbundle + cost = 20 // normally 26 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/firestarter + name = "Spetsnaz Pyro bundle" + desc = "For systematic suppression of carbon lifeforms in close quarters: Contains a lethal New Russian backpack spray, Elite hardsuit, \ + Stechkin APS pistol, two magazines, a minibomb and a stimulant syringe. \ + Order NOW and comrade Boris will throw in an extra tracksuit." + item = /obj/item/storage/backpack/duffelbag/syndie/firestarter + cost = 30 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/bundles_TC/bundle + name = "Syndicate Bundle" + desc = "Syndicate Bundles are specialized groups of items that arrive in a plain box. \ + These items are collectively worth more than 20 telecrystals, but you do not know which specialization \ + you will receive. May contain discontinued and/or exotic items." + item = /obj/item/storage/box/syndicate + cost = 20 + exclude_modes = list(/datum/game_mode/nuclear) + cant_discount = TRUE + +/datum/uplink_item/bundles_TC/surplus + name = "Syndicate Surplus Crate" + desc = "A dusty crate from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \ + but you never know. Contents are sorted to always be worth 50 TC." + item = /obj/structure/closet/crate + cost = 20 + player_minimum = 25 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + cant_discount = TRUE + var/starting_crate_value = 50 + +/datum/uplink_item/bundles_TC/surplus/super + name = "Super Surplus Crate" + desc = "A dusty SUPER-SIZED from the back of the Syndicate warehouse. Rumored to contain a valuable assortment of items, \ + but you never know. Contents are sorted to always be worth 125 TC." + cost = 40 + player_minimum = 40 + starting_crate_value = 125 + +/datum/uplink_item/bundles_TC/surplus/purchase(mob/user, datum/component/uplink/U) + var/list/uplink_items = get_uplink_items(SSticker && SSticker.mode? SSticker.mode : null, FALSE) + + var/crate_value = starting_crate_value + var/obj/structure/closet/crate/C = spawn_item(/obj/structure/closet/crate, user, U) + if(U.purchase_log) + U.purchase_log.LogPurchase(C, src, cost) + while(crate_value) + var/category = pick(uplink_items) + var/item = pick(uplink_items[category]) + var/datum/uplink_item/I = uplink_items[category][item] + + if(!I.surplus || prob(100 - I.surplus)) + continue + if(crate_value < I.cost) + continue + crate_value -= I.cost + var/obj/goods = new I.item(C) + if(U.purchase_log) + U.purchase_log.LogPurchase(goods, I, 0) + return C + +/datum/uplink_item/bundles_TC/random + name = "Random Item" + desc = "Picking this will purchase a random item. Useful if you have some TC to spare or if you haven't decided on a strategy yet." + item = /obj/effect/gibspawner/generic // non-tangible item because techwebs use this path to determine illegal tech + cost = 0 + cant_discount = TRUE + +/datum/uplink_item/bundles_TC/random/purchase(mob/user, datum/component/uplink/U) + var/list/uplink_items = U.uplink_items + var/list/possible_items = list() + for(var/category in uplink_items) + for(var/item in uplink_items[category]) + var/datum/uplink_item/I = uplink_items[category][item] + if(src == I || !I.item) + continue + if(U.telecrystals < I.cost) + continue + if(I.limited_stock == 0) + continue + possible_items += I + + if(possible_items.len) + var/datum/uplink_item/I = pick(possible_items) + SSblackbox.record_feedback("tally", "traitor_random_uplink_items_gotten", 1, initial(I.name)) + U.MakePurchase(user, I) + +/datum/uplink_item/bundles_TC/telecrystal + name = "1 Raw Telecrystal" + desc = "A telecrystal in its rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." + item = /obj/item/stack/telecrystal + cost = 1 + surplus = 0 + cant_discount = TRUE + // Don't add telecrystals to the purchase_log since + // it's just used to buy more items (including itself!) + purchase_log_vis = FALSE + +/datum/uplink_item/bundles_TC/telecrystal/five + name = "5 Raw Telecrystals" + desc = "Five telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." + item = /obj/item/stack/telecrystal/five + cost = 5 + +/datum/uplink_item/bundles_TC/telecrystal/twenty + name = "20 Raw Telecrystals" + desc = "Twenty telecrystals in their rawest and purest form; can be utilized on active uplinks to increase their telecrystal count." + item = /obj/item/stack/telecrystal/twenty + cost = 20 \ No newline at end of file diff --git a/code/modules/uplink/uplink_items/uplink_clothing.dm b/code/modules/uplink/uplink_items/uplink_clothing.dm new file mode 100644 index 0000000000..2881aa8dfd --- /dev/null +++ b/code/modules/uplink/uplink_items/uplink_clothing.dm @@ -0,0 +1,80 @@ + +/* + Uplink Items: + Unlike categories, uplink item entries are automatically sorted alphabetically on server init in a global list, + When adding new entries to the file, please keep them sorted by category. +*/ + +//Space Suits and Hardsuits + +/datum/uplink_item/suits/turtlenck + name = "Tactical Turtleneck" + desc = "A slightly armored suit that has no sensor on them, if someone sees you in this hope they think its a fake." + item = /obj/item/clothing/under/syndicate + cost = 1 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) //They already get these + +/datum/uplink_item/suits/turtlenck_skirt + name = "Tactical Skirtleneck" + desc = "A slightly armored suit that has no sensor on them, if someone sees you in this hope they think its a fake." + item = /obj/item/clothing/under/syndicate/skirt + cost = 1 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) //They already get these + +/datum/uplink_item/suits/padding + name = "Soft Padding" + desc = "Padding to add to a jumpsuit to help against melee and bullets." + item = /obj/item/clothing/accessory/padding + cost = 2 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/suits/kevlar + name = "Kevlar sheets" + desc = "Kevlar sheets to add to jumpsuit to help against bullets and melee." + item = /obj/item/clothing/accessory/kevlar + cost = 2 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/suits/plastic + name = "Plastic sheet" + desc = "Plastic body sheet to add to a jumpsuit to help against laser and energy harm." + item = /obj/item/clothing/accessory/plastics + cost = 2 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/suits/space_suit + name = "Syndicate Space Suit" + desc = "This red and black Syndicate space suit is less encumbering than Nanotrasen variants, \ + fits inside bags, and has a weapon slot. Nanotrasen crew members are trained to report red space suit \ + sightings, however." + item = /obj/item/storage/box/syndie_kit/space + cost = 4 + +/datum/uplink_item/suits/hardsuit + name = "Syndicate Hardsuit" + desc = "The feared suit of a Syndicate nuclear agent. Features slightly better armoring and a built in jetpack \ + that runs off standard atmospheric tanks. Toggling the suit in and out of \ + combat mode will allow you all the mobility of a loose fitting uniform without sacrificing armoring. \ + Additionally the suit is collapsible, making it small enough to fit within a backpack. \ + Nanotrasen crew who spot these suits are known to panic." + item = /obj/item/clothing/suit/space/hardsuit/syndi + cost = 8 + exclude_modes = list(/datum/game_mode/nuclear) //you can't buy it in nuke, because the elite hardsuit costs the same while being better + +/datum/uplink_item/suits/hardsuit/elite + name = "Elite Syndicate Hardsuit" + desc = "An upgraded, elite version of the Syndicate hardsuit. It features fireproofing, and also \ + provides the user with superior armor and mobility compared to the standard Syndicate hardsuit." + item = /obj/item/clothing/suit/space/hardsuit/syndi/elite + cost = 8 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + exclude_modes = list() + +/datum/uplink_item/suits/hardsuit/shielded + name = "Shielded Syndicate Hardsuit" + desc = "An upgraded version of the standard Syndicate hardsuit. It features a built-in energy shielding system. \ + The shields can handle up to three impacts within a short duration and will rapidly recharge while not under fire." + item = /obj/item/clothing/suit/space/hardsuit/shielded/syndi + cost = 30 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + exclude_modes = list() diff --git a/code/modules/uplink/uplink_items/uplink_dangerous.dm b/code/modules/uplink/uplink_items/uplink_dangerous.dm new file mode 100644 index 0000000000..a7f644ccbe --- /dev/null +++ b/code/modules/uplink/uplink_items/uplink_dangerous.dm @@ -0,0 +1,260 @@ + +// Dangerous Items + +/* + Uplink Items: + Unlike categories, uplink item entries are automatically sorted alphabetically on server init in a global list, + When adding new entries to the file, please keep them sorted by category. +*/ + +/datum/uplink_item/dangerous/pistol + name = "Stechkin Pistol" + desc = "A small, easily concealable handgun that uses 10mm auto rounds in 8-round magazines and is compatible \ + with suppressors." + item = /obj/item/gun/ballistic/automatic/pistol + cost = 7 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/revolver + name = "Syndicate Revolver Kit" + desc = "A sleek box containing a brutally simple Syndicate revolver that fires .357 Magnum rounds and has 7 chambers, and an extra speedloader." + item = /obj/item/storage/box/syndie_kit/revolver + cost = 13 + surplus = 50 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/rawketlawnchair + name = "84mm Rocket Propelled Grenade Launcher" + desc = "A reusable rocket propelled grenade launcher preloaded with a low-yield 84mm HE round. \ + Guaranteed to send your target out with a bang or your money back!" + item = /obj/item/gun/ballistic/rocketlauncher + cost = 8 + surplus = 30 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/antitank + name = "Anti Tank Pistol" + desc = "Essentially amounting to a sniper rifle with no stock and barrel (or indeed, any rifling at all), \ + this extremely dubious pistol is guaranteed to dislocate your wrists and hit the broad side of a barn! \ + Uses sniper ammo. \ + Bullets tend to veer off-course. We are not responsible for any unintentional damage or injury resulting from inaacuracy." + item = /obj/item/gun/ballistic/automatic/pistol/antitank/syndicate + cost = 14 + surplus = 25 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/pie_cannon + name = "Banana Cream Pie Cannon" + desc = "A special pie cannon for a special clown, this gadget can hold up to 20 pies and automatically fabricates one every two seconds!" + cost = 10 + item = /obj/item/pneumatic_cannon/pie/selfcharge + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/bananashield + name = "Bananium Energy Shield" + desc = "A clown's most powerful defensive weapon, this personal shield provides near immunity to ranged energy attacks \ + by bouncing them back at the ones who fired them. It can also be thrown to bounce off of people, slipping them, \ + and returning to you even if you miss. WARNING: DO NOT ATTEMPT TO STAND ON SHIELD WHILE DEPLOYED, EVEN IF WEARING ANTI-SLIP SHOES." + item = /obj/item/shield/energy/bananium + cost = 16 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/clownsword + name = "Bananium Energy Sword" + desc = "An energy sword that deals no damage, but will slip anyone it contacts, be it by melee attack, thrown \ + impact, or just stepping on it. Beware friendly fire, as even anti-slip shoes will not protect against it." + item = /obj/item/melee/transforming/energy/sword/bananium + cost = 3 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/bioterror + name = "Biohazardous Chemical Sprayer" + desc = "A handheld chemical sprayer that allows a wide dispersal of selected chemicals. Especially tailored by the Tiger \ + Cooperative, the deadly blend it comes stocked with will disorient, damage, and disable your foes... \ + Use with extreme caution, to prevent exposure to yourself and your fellow operatives." + item = /obj/item/reagent_containers/spray/chemsprayer/bioterror + cost = 20 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/throwingweapons + name = "Box of Throwing Weapons" + desc = "A box of shurikens and reinforced bolas from ancient Earth martial arts. They are highly effective \ + throwing weapons. The bolas can knock a target down and the shurikens will embed into limbs." + item = /obj/item/storage/box/syndie_kit/throwing_weapons + cost = 3 + +/datum/uplink_item/dangerous/shotgun + name = "Bulldog Shotgun" + desc = "A fully-loaded semi-automatic drum-fed shotgun. Compatible with all 12g rounds. Designed for close \ + quarter anti-personnel engagements." + item = /obj/item/gun/ballistic/automatic/shotgun/bulldog + cost = 8 + surplus = 40 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/smg + name = "C-20r Submachine Gun" + desc = "A fully-loaded Scarborough Arms bullpup submachine gun. The C-20r fires .45 rounds with a \ + 24-round magazine and is compatible with suppressors." + item = /obj/item/gun/ballistic/automatic/c20r + cost = 10 + surplus = 40 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/doublesword + name = "Double-Bladed Energy Sword" + desc = "The double-bladed energy sword does slightly more damage than a standard energy sword and will deflect \ + all energy projectiles, but requires two hands to wield." + item = /obj/item/twohanded/dualsaber + player_minimum = 25 + cost = 16 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/doublesword/get_discount() + return pick(4;0.8,2;0.65,1;0.5) + +/datum/uplink_item/dangerous/cxneb + name = "Dragon's Tooth Non-Eutactic Blade" + desc = "An illegal modification of a weapon that is functionally identical to the energy sword, \ + the Non-Eutactic Blade (NEB) forges a hardlight blade on-demand, \ + generating an extremely sharp, unbreakable edge that is guaranteed to satisfy your every need. \ + This particular model has a polychromic hardlight generator, allowing you to murder in style! \ + The illegal modifications bring this weapon up to par with the classic energy sword, and also gives it the energy sword's distinctive sounds." + item = /obj/item/melee/transforming/energy/sword/cx/traitor + cost = 8 + +/datum/uplink_item/dangerous/sword + name = "Energy Sword" + desc = "The energy sword is an edged weapon with a blade of pure energy. The sword is small enough to be \ + pocketed when inactive. Activating it produces a loud, distinctive noise." + item = /obj/item/melee/transforming/energy/sword/saber + cost = 8 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/shield + name = "Energy Shield" + desc = "An incredibly useful personal shield projector, capable of reflecting energy projectiles and defending \ + against other attacks. Pair with an Energy Sword for a killer combination." + item = /obj/item/shield/energy + cost = 16 + surplus = 20 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/rapier + name = "Rapier" + desc = "A fancy rapier with a diamond tip piercing anything that it comes into contack with. \ + The rapier comes with its own sheath, this is rather noticeable as only the captain is known to carry a sheath. \ + The sheath itself can be used to block melee attacks only. Its also jet black colours." + item = /obj/item/storage/belt/sabre/rapier + cost = 8 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/flamethrower + name = "Flamethrower" + desc = "A flamethrower, fueled by a portion of highly flammable biotoxins stolen previously from Nanotrasen \ + stations. Make a statement by roasting the filth in their own greed. Use with caution." + item = /obj/item/flamethrower/full/tank + cost = 4 + surplus = 40 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/flechettegun + name = "Flechette Launcher" + desc = "A compact bullpup that fires micro-flechettes.\ + Flechettes have very poor performance idividually, but can be very deadly in numbers. \ + Pre-loaded with armor piercing flechettes that are capable of puncturing most kinds of armor." + item = /obj/item/gun/ballistic/automatic/flechette + cost = 12 + surplus = 30 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/rapid + name = "Gloves of the North Star" + desc = "These gloves let the user punch people very fast. Does not improve weapon attack speed or the meaty fists of a hulk." + item = /obj/item/clothing/gloves/rapid + cost = 8 + +/datum/uplink_item/dangerous/guardian + name = "Holoparasites" + desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an \ + organic host as a home base and source of fuel. Holoparasites come in various types and share damage with their host." + item = /obj/item/storage/box/syndie_kit/guardian + cost = 15 + refundable = TRUE + cant_discount = TRUE + surplus = 0 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + player_minimum = 25 + restricted = TRUE + refund_path = /obj/item/guardiancreator/tech/choose/traitor + +/datum/uplink_item/dangerous/machinegun + name = "L6 Squad Automatic Weapon" + desc = "A fully-loaded Aussec Armoury belt-fed machine gun. \ + This deadly weapon has a massive 50-round magazine of devastating 1.95x129mm ammunition." + item = /obj/item/gun/ballistic/automatic/l6_saw + cost = 18 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/carbine + name = "M-90gl Carbine" + desc = "A fully-loaded, specialized three-round burst carbine that fires 5.56mm ammunition from a 30 round magazine \ + with a toggleable 40mm underbarrel grenade launcher." + item = /obj/item/gun/ballistic/automatic/m90 + cost = 18 + surplus = 50 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/powerfist + name = "Power Fist" + desc = "The power-fist is a metal gauntlet with a built-in piston-ram powered by an external gas supply.\ + Upon hitting a target, the piston-ram will extend forward to make contact for some serious damage. \ + Using a wrench on the piston valve will allow you to tweak the amount of gas used per punch to \ + deal extra damage and hit targets further. Use a screwdriver to take out any attached tanks." + item = /obj/item/melee/powerfist + cost = 8 + +/datum/uplink_item/dangerous/sniper + name = "Sniper Rifle" + desc = "Ranged fury, Syndicate style. Guaranteed to cause shock and awe or your TC back!" + item = /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate + cost = 16 + surplus = 25 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/bolt_action + name = "Surplus Rifle" + desc = "A horribly outdated bolt action weapon. You've got to be desperate to use this." + item = /obj/item/gun/ballistic/shotgun/boltaction + cost = 2 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/dangerous/foamsmg + name = "Toy Submachine Gun" + desc = "A fully-loaded Donksoft bullpup submachine gun that fires riot grade darts with a 20-round magazine." + item = /obj/item/gun/ballistic/automatic/c20r/toy + cost = 5 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/foammachinegun + name = "Toy Machine Gun" + desc = "A fully-loaded Donksoft belt-fed machine gun. This weapon has a massive 50-round magazine of devastating \ + riot grade darts, that can briefly incapacitate someone in just one volley." + item = /obj/item/gun/ballistic/automatic/l6_saw/toy + cost = 10 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/dangerous/foampistol + name = "Toy Pistol with Riot Darts" + desc = "An innocent-looking toy pistol designed to fire foam darts. Comes loaded with riot-grade \ + darts effective at incapacitating a target." + item = /obj/item/gun/ballistic/automatic/toy/pistol/riot + cost = 3 + surplus = 10 \ No newline at end of file diff --git a/code/modules/uplink/uplink_items/uplink_devices.dm b/code/modules/uplink/uplink_items/uplink_devices.dm new file mode 100644 index 0000000000..70c70a61b9 --- /dev/null +++ b/code/modules/uplink/uplink_items/uplink_devices.dm @@ -0,0 +1,251 @@ + +/* + Uplink Items: + Unlike categories, uplink item entries are automatically sorted alphabetically on server init in a global list, + When adding new entries to the file, please keep them sorted by category. +*/ + +// Devices and Tools + +/datum/uplink_item/device_tools/emag + name = "Cryptographic Sequencer" + desc = "The cryptographic sequencer, electromagnetic card, or emag, is a small card that unlocks hidden functions \ + in electronic devices, subverts intended functions, and easily breaks security mechanisms." + item = /obj/item/card/emag + cost = 6 + +/datum/uplink_item/device_tools/emagrecharge + name = "Electromagnet Charging Device" + desc = "A small device intended for recharging Cryptographic Sequencers. Using it will add five extra charges to the Cryptographic Sequencer." + item = /obj/item/emagrecharge + cost = 2 + +/datum/uplink_item/device_tools/phantomthief + name = "Syndicate Mask" + desc = "A cheap plastic mask fitted with an adrenaline autoinjector, which can be used by simply tensing your muscles" + item = /obj/item/clothing/glasses/phantomthief/syndicate + cost = 2 + +/datum/uplink_item/device_tools/cutouts + name = "Adaptive Cardboard Cutouts" + desc = "These cardboard cutouts are coated with a thin material that prevents discoloration and makes the images on them appear more lifelike. \ + This pack contains three as well as a crayon for changing their appearances." + item = /obj/item/storage/box/syndie_kit/cutouts + cost = 1 + surplus = 20 + +/datum/uplink_item/device_tools/assault_pod + name = "Assault Pod Targeting Device" + desc = "Use this to select the landing zone of your assault pod." + item = /obj/item/assault_pod + cost = 30 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + restricted = TRUE + +/datum/uplink_item/device_tools/binary + name = "Binary Translator Key" + desc = "A key that, when inserted into a radio headset, allows you to listen to and talk with silicon-based lifeforms, \ + such as AI units and cyborgs, over their private binary channel. Caution should \ + be taken while doing this, as unless they are allied with you, they are programmed to report such intrusions." + item = /obj/item/encryptionkey/binary + cost = 2 + surplus = 75 + restricted = TRUE + +/datum/uplink_item/device_tools/magboots + name = "Blood-Red Magboots" + desc = "A pair of magnetic boots with a Syndicate paintjob that assist with freer movement in space or on-station \ + during gravitational generator failures. These reverse-engineered knockoffs of Nanotrasen's \ + 'Advanced Magboots' slow you down in simulated-gravity environments much like the standard issue variety." + item = /obj/item/clothing/shoes/magboots/syndie + cost = 2 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/device_tools/compressionkit + name = "Bluespace Compression Kit" + desc = "A modified version of a BSRPED that can be used to reduce the size of most items while retaining their original functions! \ + Does not work on storage items. \ + Recharge using bluespace crystals. \ + Comes with 5 charges." + item = /obj/item/compressionkit + cost = 5 + +/datum/uplink_item/device_tools/briefcase_launchpad + name = "Briefcase Launchpad" + desc = "A briefcase containing a launchpad, a device able to teleport items and people to and from targets up to twenty tiles away from the briefcase. \ + Also includes a remote control, disguised as an ordinary folder. Touch the briefcase with the remote to link it." + surplus = 0 + item = /obj/item/storage/briefcase/launchpad + cost = 6 + +/datum/uplink_item/device_tools/camera_bug + name = "Camera Bug" + desc = "Enables you to view all cameras on the main network, set up motion alerts and track a target. \ + Bugging cameras allows you to disable them remotely." + item = /obj/item/camera_bug + cost = 1 + surplus = 90 + +/datum/uplink_item/device_tools/military_belt + name = "Chest Rig" + desc = "A robust seven-slot set of webbing that is capable of holding all manner of tactical equipment." + item = /obj/item/storage/belt/military + cost = 1 + exclude_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/device_tools/fakenucleardisk + name = "Decoy Nuclear Authentication Disk" + desc = "It's just a normal disk. Visually it's identical to the real deal, but it won't hold up under closer scrutiny by the Captain. \ + Don't try to give this to us to complete your objective, we know better!" + item = /obj/item/disk/nuclear/fake + cost = 1 + surplus = 1 + +/datum/uplink_item/device_tools/frame + name = "F.R.A.M.E. PDA Cartridge" + desc = "When inserted into a personal digital assistant, this cartridge gives you five PDA viruses which \ + when used cause the targeted PDA to become a new uplink with zero TCs, and immediately become unlocked. \ + You will receive the unlock code upon activating the virus, and the new uplink may be charged with \ + telecrystals normally." + item = /obj/item/cartridge/virus/frame + cost = 2 + restricted = TRUE + +/datum/uplink_item/device_tools/toolbox + name = "Full Syndicate Toolbox" + desc = "The Syndicate toolbox is a suspicious black and red. It comes loaded with a full tool set including a \ + multitool and combat gloves that are resistant to shocks and heat." + item = /obj/item/storage/toolbox/syndicate + cost = 1 + +/datum/uplink_item/device_tools/syndie_glue + name = "Glue" + desc = "A cheap bottle of one use syndicate brand super glue. \ + Use on any item to make it undroppable. \ + Be careful not to glue an item you're already holding!" + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + item = /obj/item/syndie_glue + cost = 2 + +/datum/uplink_item/device_tools/hacked_module + name = "Hacked AI Law Upload Module" + desc = "When used with an upload console, this module allows you to upload priority laws to an artificial intelligence. \ + Be careful with wording, as artificial intelligences may look for loopholes to exploit." + item = /obj/item/aiModule/syndicate + cost = 9 + +/datum/uplink_item/device_tools/medgun + name = "Medbeam Gun" + desc = "A wonder of Syndicate engineering, the Medbeam gun, or Medi-Gun enables a medic to keep his fellow \ + operatives in the fight, even while under fire. Don't cross the streams!" + item = /obj/item/gun/medbeam + cost = 15 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/device_tools/nutcracker + name = "Nutcracker" + desc = "An oversized version of what you'd initially expect here. Big enough to crush skulls." + item = /obj/item/nutcracker + cost = 1 + +/datum/uplink_item/device_tools/singularity_beacon + name = "Power Beacon" + desc = "When screwed to wiring attached to an electric grid and activated, this large device pulls any \ + active gravitational singularities or tesla balls towards it (provided they are not safely \ + contained), as well as increasing the odds of incoming meteor waves. \ + Because of its size, it cannot be carried. Ordering this sends you a small beacon \ + that will teleport the larger beacon to your location upon activation." + item = /obj/item/sbeacondrop + cost = 14 + +/datum/uplink_item/device_tools/powersink + name = "Power Sink" + desc = "When screwed to wiring attached to a power grid and activated, this large device lights up and places excessive \ + load on the grid, causing a station-wide blackout. The sink is large and cannot be stored in most \ + traditional bags and boxes. Caution: Will explode if the powernet contains sufficient amounts of energy." + item = /obj/item/powersink + cost = 6 + +/datum/uplink_item/device_tools/rad_laser + name = "Radioactive Microlaser" + desc = "A radioactive microlaser disguised as a standard Nanotrasen health analyzer. When used, it emits a \ + powerful burst of radiation, which, after a short delay, can incapacitate all but the most protected \ + of humanoids. It has two settings: intensity, which controls the power of the radiation, \ + and wavelength, which controls the delay before the effect kicks in." + item = /obj/item/healthanalyzer/rad_laser + cost = 3 + +/datum/uplink_item/device_tools/stimpack + name = "Stimpack" + desc = "Stimpacks, the tool of many great heroes, make you nearly immune to stuns and knockdowns for about \ + 5 minutes after injection." + item = /obj/item/reagent_containers/syringe/stimulants + cost = 5 + surplus = 90 + +/datum/uplink_item/device_tools/medkit + name = "Syndicate Combat Medic Kit" + desc = "This first aid kit is a suspicious brown and red. Included is a combat stimulant injector \ + for rapid healing, a medical night vision HUD for quick identification of injured personnel, \ + and other supplies helpful for a field medic." + item = /obj/item/storage/firstaid/tactical/nukeop + cost = 4 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/device_tools/surgerybag + name = "Syndicate Surgery Duffel Bag" + desc = "The Syndicate surgery duffel bag is a toolkit containing all surgery tools, surgical drapes, \ + a Syndicate brand MMI, a straitjacket, and a muzzle." + item = /obj/item/storage/backpack/duffelbag/syndie/surgery + cost = 3 + +/datum/uplink_item/device_tools/surgerybag_adv + name = "Advanced Syndicate Surgery Duffel Bag" + desc = "The Syndicate surgery duffel bag is a toolkit containing all advanced surgery tools, surgical drapes, \ + a Syndicate brand MMI, a straitjacket, a muzzle, and an outdated, yet still useful Combat Medic Kit." + item = /obj/item/storage/backpack/duffelbag/syndie/surgery_adv + cost = 10 + +/datum/uplink_item/device_tools/brainwash_disk + name = "Brainwashing Surgery Program" + desc = "A disk containing the procedure to perform a brainwashing surgery, allowing you to implant an objective onto a target. \ + Insert into an Operating Console to enable the procedure." + item = /obj/item/disk/surgery/brainwashing + cost = 3 + +/datum/uplink_item/device_tools/encryptionkey + name = "Syndicate Encryption Key" + desc = "A key that, when inserted into a radio headset, allows you to listen to all station department channels \ + as well as talk on an encrypted Syndicate channel with other agents that have the same key." + item = /obj/item/encryptionkey/syndicate + cost = 2 + surplus = 75 + restricted = TRUE + +/datum/uplink_item/device_tools/syndietome + name = "Syndicate Tome" + desc = "Using rare artifacts acquired at great cost, the Syndicate has reverse engineered \ + the seemingly magical books of a certain cult. Though lacking the esoteric abilities \ + of the originals, these inferior copies are still quite useful, being able to provide \ + both weal and woe on the battlefield, even if they do occasionally bite off a finger." + item = /obj/item/storage/book/bible/syndicate + cost = 9 + +/datum/uplink_item/device_tools/thermal + name = "Thermal Imaging Glasses" + desc = "These goggles can be turned to resemble common eyewear found throughout the station. \ + They allow you to see organisms through walls by capturing the upper portion of the infrared light spectrum, \ + emitted as heat and light by objects. Hotter objects, such as warm bodies, cybernetic organisms \ + and artificial intelligence cores emit more of this light than cooler objects like walls and airlocks." + item = /obj/item/clothing/glasses/thermal/syndi + cost = 4 + +/datum/uplink_item/device_tools/potion + name = "Syndicate Sentience Potion" + item = /obj/item/slimepotion/slime/sentience/nuclear + desc = "A potion recovered at great risk by undercover Syndicate operatives and then subsequently modified with Syndicate technology. \ + Using it will make any animal sentient, and bound to serve you, as well as implanting an internal radio for communication and an internal ID card for opening doors." + cost = 2 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + restricted = TRUE diff --git a/code/modules/uplink/uplink_items/uplink_explosives.dm b/code/modules/uplink/uplink_items/uplink_explosives.dm new file mode 100644 index 0000000000..4db8643a66 --- /dev/null +++ b/code/modules/uplink/uplink_items/uplink_explosives.dm @@ -0,0 +1,161 @@ + +/* + Uplink Items: + Unlike categories, uplink item entries are automatically sorted alphabetically on server init in a global list, + When adding new entries to the file, please keep them sorted by category. +*/ + +//Grenades and Explosives + +/datum/uplink_item/explosives/bioterrorfoam + name = "Bioterror Foam Grenade" + desc = "A powerful chemical foam grenade which creates a deadly torrent of foam that will mute, blind, confuse, \ + mutate, and irritate carbon lifeforms. Specially brewed by Tiger Cooperative chemical weapons specialists \ + using additional spore toxin. Ensure suit is sealed before use." + item = /obj/item/grenade/chem_grenade/bioterrorfoam + cost = 5 + surplus = 35 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/bombanana + name = "Bombanana" + desc = "A banana with an explosive taste! discard the peel quickly, as it will explode with the force of a syndicate minibomb \ + a few seconds after the banana is eaten." + item = /obj/item/reagent_containers/food/snacks/grown/banana/bombanana + cost = 4 //it is a bit cheaper than a minibomb because you have to take off your helmet to eat it, which is how you arm it + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/buzzkill + name = "Buzzkill Grenade Box" + desc = "A box with three grenades that release a swarm of angry bees upon activation. These bees indiscriminately attack friend or foe \ + with random toxins. Courtesy of the BLF and Tiger Cooperative." + item = /obj/item/storage/box/syndie_kit/bee_grenades + cost = 15 + surplus = 35 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/c4 + name = "Composition C-4" + desc = "C-4 is plastic explosive of the common variety Composition C. You can use it to breach walls, sabotage equipment, or connect \ + an assembly to it in order to alter the way it detonates. It can be attached to almost all objects and has a modifiable timer with a \ + minimum setting of 10 seconds." + item = /obj/item/grenade/plastic/c4 + cost = 1 + +/datum/uplink_item/explosives/c4bag + name = "Bag of C-4 explosives" + desc = "Because sometimes quantity is quality. Contains 10 C-4 plastic explosives." + item = /obj/item/storage/backpack/duffelbag/syndie/c4 + cost = 9 //10% discount! + cant_discount = TRUE + +/datum/uplink_item/explosives/x4bag + name = "Bag of X-4 explosives" + desc = "Contains 3 X-4 shaped plastic explosives. Similar to C4, but with a stronger blast that is directional instead of circular. \ + X-4 can be placed on a solid surface, such as a wall or window, and it will blast through the wall, injuring anything on the opposite side, while being safer to the user. \ + For when you want a controlled explosion that leaves a wider, deeper, hole." + item = /obj/item/storage/backpack/duffelbag/syndie/x4 + cost = 4 // + cant_discount = TRUE + +/datum/uplink_item/explosives/clown_bomb_clownops + name = "Clown Bomb" + desc = "The Clown bomb is a hilarious device capable of massive pranks. It has an adjustable timer, \ + with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ + movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ + transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ + be defused, and some crew may attempt to do so." + item = /obj/item/sbeacondrop/clownbomb + cost = 15 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/detomatix + name = "Detomatix PDA Cartridge" + desc = "When inserted into a personal digital assistant, this cartridge gives you four opportunities to \ + detonate PDAs of crewmembers who have their message feature enabled. \ + The concussive effect from the explosion will knock the recipient out for a short period, and deafen them for longer." + item = /obj/item/cartridge/virus/syndicate + cost = 5 + restricted = TRUE + +/datum/uplink_item/explosives/emp + name = "EMP Grenades and Implanter Kit" + desc = "A box that contains five EMP grenades and an EMP implant with three uses. Useful to disrupt communications, \ + security's energy weapons and silicon lifeforms when you're in a tight spot." + item = /obj/item/storage/box/syndie_kit/emp + cost = 2 + +/datum/uplink_item/explosives/virus_grenade + name = "Fungal Tuberculosis Grenade" + desc = "A primed bio-grenade packed into a compact box. Comes with five Bio Virus Antidote Kit (BVAK) \ + autoinjectors for rapid application on up to two targets each, a syringe, and a bottle containing \ + the BVAK solution." + item = /obj/item/storage/box/syndie_kit/tuberculosisgrenade + cost = 8 + surplus = 35 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + restricted = TRUE + +/datum/uplink_item/explosives/grenadier + name = "Grenadier's belt" + desc = "A belt containing 26 lethally dangerous and destructive grenades. Comes with an extra multitool and screwdriver." + item = /obj/item/storage/belt/grenade/full + include_modes = list(/datum/game_mode/nuclear) + cost = 22 + surplus = 0 + +/datum/uplink_item/explosives/pizza_bomb + name = "Pizza Bomb" + desc = "A pizza box with a bomb cunningly attached to the lid. The timer needs to be set by opening the box; afterwards, \ + opening the box again will trigger the detonation after the timer has elapsed. Comes with free pizza, for you or your target!" + item = /obj/item/pizzabox/bomb + cost = 6 + surplus = 8 + +/datum/uplink_item/explosives/syndicate_bomb + name = "Syndicate Bomb" + desc = "The Syndicate bomb is a fearsome device capable of massive destruction. It has an adjustable timer, \ + with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ + movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ + transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ + be defused, and some crew may attempt to do so." + item = /obj/item/sbeacondrop/bomb + cost = 11 + +/datum/uplink_item/explosives/syndicate_detonator + name = "Syndicate Detonator" + desc = "The Syndicate detonator is a companion device to the Syndicate bomb. Simply press the included button \ + and an encrypted radio frequency will instruct all live Syndicate bombs to detonate. \ + Useful for when speed matters or you wish to synchronize multiple bomb blasts. Be sure to stand clear of \ + the blast radius before using the detonator." + item = /obj/item/syndicatedetonator + cost = 3 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/syndicate_minibomb + name = "Syndicate Minibomb" + desc = "The minibomb is a grenade with a five-second fuse. Upon detonation, it will create a small hull breach \ + in addition to dealing high amounts of damage to nearby personnel." + item = /obj/item/grenade/syndieminibomb + cost = 6 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/tearstache + name = "Teachstache Grenade" + desc = "A teargas grenade that launches sticky moustaches onto the face of anyone not wearing a clown or mime mask. The moustaches will \ + remain attached to the face of all targets for one minute, preventing the use of breath masks and other such devices." + item = /obj/item/grenade/chem_grenade/teargas/moustache + cost = 3 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/explosives/viscerators + name = "Viscerator Delivery Grenade" + desc = "A unique grenade that deploys a swarm of viscerators upon activation, which will chase down and shred \ + any non-operatives in the area." + item = /obj/item/grenade/spawnergrenade/manhacks + cost = 5 + surplus = 35 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) diff --git a/code/modules/uplink/uplink_items/uplink_implants.dm b/code/modules/uplink/uplink_items/uplink_implants.dm new file mode 100644 index 0000000000..3262809cb5 --- /dev/null +++ b/code/modules/uplink/uplink_items/uplink_implants.dm @@ -0,0 +1,102 @@ + +/* + Uplink Items: + Unlike categories, uplink item entries are automatically sorted alphabetically on server init in a global list, + When adding new entries to the file, please keep them sorted by category. +*/ + +// Implants + +/datum/uplink_item/implants/adrenal + name = "Adrenal Implant" + desc = "An implant injected into the body, and later activated at the user's will. It will inject a chemical \ + cocktail which removes all incapacitating effects, lets the user run faster and has a mild healing effect." + item = /obj/item/storage/box/syndie_kit/imp_adrenal + cost = 8 + player_minimum = 25 + +/datum/uplink_item/implants/antistun + name = "CNS Rebooter Implant" + desc = "This implant will help you get back up on your feet faster after being stunned. Comes with an autosurgeon." + item = /obj/item/autosurgeon/anti_stun + cost = 12 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/implants/freedom + name = "Freedom Implant" + desc = "An implant injected into the body and later activated at the user's will. It will attempt to free the \ + user from common restraints such as handcuffs." + item = /obj/item/storage/box/syndie_kit/imp_freedom + cost = 5 + +/datum/uplink_item/implants/microbomb + name = "Microbomb Implant" + desc = "An implant injected into the body, and later activated either manually or automatically upon death. \ + The more implants inside of you, the higher the explosive power. \ + This will permanently destroy your body, however." + item = /obj/item/storage/box/syndie_kit/imp_microbomb + cost = 2 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/implants/macrobomb + name = "Macrobomb Implant" + desc = "An implant injected into the body, and later activated either manually or automatically upon death. \ + Upon death, releases a massive explosion that will wipe out everything nearby." + item = /obj/item/storage/box/syndie_kit/imp_macrobomb + cost = 20 + include_modes = list(/datum/game_mode/nuclear) + restricted = TRUE + +/datum/uplink_item/implants/radio + name = "Internal Syndicate Radio Implant" + desc = "An implant injected into the body, allowing the use of an internal Syndicate radio. \ + Used just like a regular headset, but can be disabled to use external headsets normally and to avoid detection." + item = /obj/item/storage/box/syndie_kit/imp_radio + cost = 4 + restricted = TRUE + +/datum/uplink_item/implants/reviver + name = "Reviver Implant" + desc = "This implant will attempt to revive and heal you if you lose consciousness. Comes with an autosurgeon." + item = /obj/item/autosurgeon/reviver + cost = 8 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/implants/stealthimplant + name = "Stealth Implant" + desc = "This one-of-a-kind implant will make you almost invisible as long as you don't don't excessively move around. \ + On activation, it will conceal you inside a chameleon cardboard box that is only revealed once someone bumps into it." + item = /obj/item/implanter/stealth + cost = 8 + +/datum/uplink_item/implants/storage + name = "Storage Implant" + desc = "An implant injected into the body, and later activated at the user's will. It will open a small bluespace \ + pocket capable of storing two regular-sized items." + item = /obj/item/storage/box/syndie_kit/imp_storage + cost = 8 + +/datum/uplink_item/implants/thermals + name = "Thermal Eyes" + desc = "These cybernetic eyes will give you thermal vision. Comes with a free autosurgeon." + item = /obj/item/autosurgeon/thermal_eyes + cost = 8 + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/implants/uplink + name = "Uplink Implant" + desc = "An implant injected into the body, and later activated at the user's will. Has no telecrystals and must be charged by the use of physical telecrystals. \ + Undetectable (except via surgery), and excellent for escaping confinement." + item = /obj/item/storage/box/syndie_kit/imp_uplink + cost = 4 + // An empty uplink is kinda useless. + surplus = 0 + restricted = TRUE + +/datum/uplink_item/implants/xray + name = "X-ray Vision Implant" + desc = "These cybernetic eyes will give you X-ray vision. Comes with an autosurgeon." + item = /obj/item/autosurgeon/xray_eyes + cost = 10 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear) diff --git a/code/modules/uplink/uplink_items/uplink_roles.dm b/code/modules/uplink/uplink_items/uplink_roles.dm new file mode 100644 index 0000000000..89d3c25700 --- /dev/null +++ b/code/modules/uplink/uplink_items/uplink_roles.dm @@ -0,0 +1,226 @@ + +/* + Uplink Items: + Unlike categories, uplink item entries are automatically sorted alphabetically on server init in a global list, + When adding new entries to the file, please keep them sorted by category. +*/ + +// Role-specific items + +/datum/uplink_item/role_restricted/ancient_jumpsuit + name = "Ancient Jumpsuit" + desc = "A tattered old jumpsuit that will provide absolutely no benefit to you. It fills the wearer with a strange compulsion to blurt out 'glorf'." + item = /obj/item/clothing/under/color/grey/glorf + cost = 20 + restricted_roles = list("Assistant") + +/datum/uplink_item/role_restricted/pie_cannon + name = "Banana Cream Pie Cannon" + desc = "A special pie cannon for a special clown, this gadget can hold up to 20 pies and automatically fabricates one every two seconds!" + cost = 10 + item = /obj/item/pneumatic_cannon/pie/selfcharge + restricted_roles = list("Clown") + +/datum/uplink_item/role_restricted/blastcannon + name = "Blast Cannon" + desc = "A highly specialized weapon, the Blast Cannon is actually relatively simple. It contains an attachment for a tank transfer valve mounted to an angled pipe specially constructed \ + withstand extreme pressure and temperatures, and has a mechanical trigger for triggering the transfer valve. Essentially, it turns the explosive force of a bomb into a narrow-angle \ + blast wave \"projectile\". Aspiring scientists may find this highly useful, as forcing the pressure shockwave into a narrow angle seems to be able to bypass whatever quirk of physics \ + disallows explosive ranges above a certain distance, allowing for the device to use the theoretical yield of a transfer valve bomb, instead of the factual yield." + item = /obj/item/gun/blastcannon + cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled gas masked scientist. + restricted_roles = list("Research Director", "Scientist") + +/datum/uplink_item/role_restricted/alientech + name = "Alien Research Disk" + desc = "A technology disk holding a terabyte of highly confidential abductor technology. \ + Simply insert into research console of choice and import the files from the disk. Because of its foreign nature, it may require multiple uploads to work properly." + item = /obj/item/disk/tech_disk/abductor + cost = 12 + restricted_roles = list("Research Director", "Scientist", "Roboticist") + +/datum/uplink_item/role_restricted/clown_bomb + name = "Clown Bomb" + desc = "The Clown bomb is a hilarious device capable of massive pranks. It has an adjustable timer, \ + with a minimum of 60 seconds, and can be bolted to the floor with a wrench to prevent \ + movement. The bomb is bulky and cannot be moved; upon ordering this item, a smaller beacon will be \ + transported to you that will teleport the actual bomb to it upon activation. Note that this bomb can \ + be defused, and some crew may attempt to do so. \ + The bomb core can be pried out and manually detonated with other explosives." + item = /obj/item/sbeacondrop/clownbomb + cost = 15 + restricted_roles = list("Clown") + +/* +/datum/uplink_item/role_restricted/clowncar + name = "Clown Car" + desc = "The Clown Car is the ultimate transportation method for any worthy clown! \ + Simply insert your bikehorn and get in, and get ready to have the funniest ride of your life! \ + You can ram any spacemen you come across and stuff them into your car, kidnapping them and locking them inside until \ + someone saves them or they manage to crawl out. Be sure not to ram into any walls or vending machines, as the springloaded seats \ + are very sensetive. Now with our included lube defense mechanism which will protect you against any angry shitcurity!" + item = /obj/vehicle/sealed/car/clowncar + cost = 15 + restricted_roles = list("Clown") +*/ + +/datum/uplink_item/role_restricted/clumsyDNA + name = "Clumsy Clown DNA" + desc = "A DNA injector that has been loaded with the clown gene that makes people clumsy.. \ + Making someone clumsy will allow them to use clown firing pins as well as Reverse Revolvers. For a laugh try using this on the HOS to see how many times they shoot themselves in the foot!" + cost = 1 + item = /obj/item/dnainjector/clumsymut + restricted_roles = list("Clown") + +/datum/uplink_item/role_restricted/haunted_magic_eightball + name = "Haunted Magic Eightball" + desc = "Most magic eightballs are toys with dice inside. Although identical in appearance to the harmless toys, this occult device reaches into the spirit world to find its answers. \ + Be warned, that spirits are often capricious or just little assholes. To use, simply speak your question aloud, then begin shaking." + item = /obj/item/toy/eightball/haunted + cost = 2 + restricted_roles = list("Curator") + limited_stock = 1 //please don't spam deadchat + +/datum/uplink_item/role_restricted/his_grace + name = "His Grace" + desc = "An incredibly dangerous weapon recovered from a station overcome by the grey tide. Once activated, He will thirst for blood and must be used to kill to sate that thirst. \ + His Grace grants gradual regeneration and complete stun immunity to His wielder, but be wary: if He gets too hungry, He will become impossible to drop and eventually kill you if not fed. \ + However, if left alone for long enough, He will fall back to slumber. \ + To activate His Grace, simply unlatch Him." + item = /obj/item/his_grace + cost = 20 + restricted_roles = list("Chaplain") + surplus = 5 //Very low chance to get it in a surplus crate even without being the chaplain + +/datum/uplink_item/role_restricted/explosive_hot_potato + name = "Exploding Hot Potato" + desc = "A potato rigged with explosives. On activation, a special mechanism is activated that prevents it from being dropped. \ + The only way to get rid of it if you are holding it is to attack someone else with it, causing it to latch to that person instead." + item = /obj/item/hot_potato/syndicate + cost = 4 + restricted_roles = list("Cook", "Botanist", "Clown", "Mime") + +/datum/uplink_item/role_restricted/strange_seeds + name = "Pack of strange seeds" + desc = "Mysterious seeds as strange as their name implies. Spooky." + item = /obj/item/seeds/random + cost = 2 + restricted_roles = list("Botanist") + illegal_tech = FALSE + +/datum/uplink_item/role_restricted/strange_seeds_10pack + name = "Pack of strange seeds x10" + desc = "Mysterious seeds as strange as their name implies. Spooky. These come in bulk" + item = /obj/item/storage/box/strange_seeds_10pack + cost = 20 + restricted_roles = list("Botanist") + +/datum/uplink_item/role_restricted/ez_clean_bundle + name = "EZ Clean Grenade Bundle" + desc = "A box with three cleaner grenades using the trademark Waffle Co. formula. Serves as a cleaner and causes acid damage to anyone standing nearby. \ + The acid only affects carbon-based creatures." + item = /obj/item/storage/box/syndie_kit/ez_clean + cost = 6 + surplus = 20 + restricted_roles = list("Janitor") + +/datum/uplink_item/role_restricted/goldenbox + name = "Gold Toolbox" + desc = "A gold planted plastitanium toolbox loaded with tools. Comes with a set of AI detection multi-tool and a pare of combat gloves." + item = /obj/item/storage/toolbox/gold_real + cost = 3 // Has syndie tools + gloves + a robust weapon + restricted_roles = list("Assistant", "Curator") //Curator due to this being made of gold - It fits the theme + +/datum/uplink_item/role_restricted/mimery + name = "Guide to Advanced Mimery Series" + desc = "The classical two part series on how to further hone your mime skills. Upon studying the series, the user should be able to make 3x1 invisible walls, and shoot bullets out of their fingers. \ + Obviously only works for Mimes." + cost = 12 + item = /obj/item/storage/box/syndie_kit/mimery + restricted_roles = list("Mime") + +/datum/uplink_item/role_restricted/ultrahonkpins + name = "Hilarious firing pin" + desc = "A single firing pin made for Clown agents, this firing pin makes any gun honk when fired if not a true clown! \ + This firing pin also helps you fire the gun correctly. May the HonkMother HONK you agent." + item = /obj/item/firing_pin/clown/ultra + cost = 2 + restricted_roles = list("Clown") + +/datum/uplink_item/role_restricted/pressure_mod + name = "Kinetic Accelerator Pressure Mod" + desc = "A modification kit which allows Kinetic Accelerators to do greatly increased damage while indoors. \ + Occupies 35% mod capacity." + item = /obj/item/borg/upgrade/modkit/indoors + cost = 5 //you need two for full damage, so total of 10 for maximum damage + limited_stock = 2 //you can't use more than two! + restricted_roles = list("Shaft Miner") + +/datum/uplink_item/role_restricted/kitchen_gun + name = "Kitchen Gun (TM)" + desc = "A revolutionary .45 caliber cleaning solution! Say goodbye to daily stains and dirty surfaces with Kitchen Gun (TM)! \ + Just five shots from Kitchen Gun (TM), and it'll sparkle like new! Includes two extra ammunition clips!" + cost = 10 + surplus = 40 + restricted_roles = list("Cook", "Janitor") + item = /obj/item/storage/box/syndie_kit/kitchen_gun + +/datum/uplink_item/role_restricted/kitchen_gun_ammo + name = "Kitchen Gun (TM) .45 Magazine" + desc = "An extra eight bullets for an extra eight uses of Kitchen Gun (TM)!" + cost = 1 + restricted_roles = list("Cook", "Janitor") + item = /obj/item/ammo_box/magazine/m45/kitchengun + +/datum/uplink_item/role_restricted/magillitis_serum + name = "Magillitis Serum Autoinjector" + desc = "A single-use autoinjector which contains an experimental serum that causes rapid muscular growth in Hominidae. \ + Side-affects may include hypertrichosis, violent outbursts, and an unending affinity for bananas." + item = /obj/item/reagent_containers/hypospray/magillitis + cost = 8 + restricted_roles = list("Geneticist", "Chief Medical Officer") + +/datum/uplink_item/role_restricted/modified_syringe_gun + name = "Modified Syringe Gun" + desc = "A syringe gun that fires DNA injectors instead of normal syringes." + item = /obj/item/gun/syringe/dna + cost = 14 + restricted_roles = list("Geneticist", "Chief Medical Officer") + +/datum/uplink_item/role_restricted/chemical_gun + name = "Reagent Dartgun" + desc = "A heavily modified syringe gun which is capable of synthesizing its own chemical darts using input reagents. Can hold 100u of reagents." + item = /obj/item/gun/chem + cost = 12 + restricted_roles = list("Chemist", "Chief Medical Officer") + +/datum/uplink_item/role_restricted/reverse_bear_trap + name = "Reverse Bear Trap" + desc = "An ingenious execution device worn on (or forced onto) the head. Arming it starts a 1-minute kitchen timer mounted on the bear trap. When it goes off, the trap's jaws will \ + violently open, instantly killing anyone wearing it by tearing their jaws in half. To arm, attack someone with it while they're not wearing headgear, and you will force it onto their \ + head after three seconds uninterrupted." + cost = 5 + item = /obj/item/reverse_bear_trap + restricted_roles = list("Clown") + +/datum/uplink_item/role_restricted/reverse_revolver + name = "Reverse Revolver" + desc = "A revolver that always fires at its user. \"Accidentally\" drop your weapon, then watch as the greedy corporate pigs blow their own brains all over the wall. \ + The revolver itself is actually real. Only clumsy people, and clowns, can fire it normally. Comes in a box of hugs. Honk." + cost = 14 + item = /obj/item/storage/box/hug/reverse_revolver + restricted_roles = list("Clown") + +/datum/uplink_item/role_restricted/taeclowndo_shoes + name = "Tae-clown-do Shoes" + desc = "A pair of shoes for the most elite agents of the honkmotherland. They grant the mastery of taeclowndo with some honk-fu moves as long as they're worn." + cost = 14 + item = /obj/item/clothing/shoes/clown_shoes/taeclowndo + restricted_roles = list("Clown") + +/datum/uplink_item/role_restricted/emitter_cannon + name = "Emitter Cannon" + desc = "A small emitter fitted into a gun case, do to size constraints and safety it can only shoot about ten times when fully charged." + cost = 5 //Low ammo, and deals same as 10mm but emp-able + item = /obj/item/gun/energy/emitter + restricted_roles = list("Chief Engineer", "Station Engineer", "Atmospheric Technician") diff --git a/code/modules/uplink/uplink_items/uplink_stealth.dm b/code/modules/uplink/uplink_items/uplink_stealth.dm new file mode 100644 index 0000000000..65a8ad4080 --- /dev/null +++ b/code/modules/uplink/uplink_items/uplink_stealth.dm @@ -0,0 +1,134 @@ + +// Stealthy Weapons + +/* + Uplink Items: + Unlike categories, uplink item entries are automatically sorted alphabetically on server init in a global list, + When adding new entries to the file, please keep them sorted by category. +*/ + +/datum/uplink_item/stealthy_weapons/combatglovesplus + name = "Combat Gloves Plus" + desc = "A pair of gloves that are fireproof and shock resistant, however unlike the regular Combat Gloves this one uses nanotechnology \ + to learn the abilities of krav maga to the wearer." + item = /obj/item/clothing/gloves/krav_maga/combatglovesplus + cost = 5 + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + surplus = 0 + +/datum/uplink_item/stealthy_weapons/cqc + name = "CQC Manual" + desc = "A manual that teaches a single user tactical Close-Quarters Combat before self-destructing." + item = /obj/item/book/granter/martial/cqc + include_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + cost = 13 + surplus = 0 + +/datum/uplink_item/stealthy_weapons/dart_pistol + name = "Dart Pistol" + desc = "A miniaturized version of a normal syringe gun. It is very quiet when fired and can fit into any \ + space a small item can." + item = /obj/item/gun/syringe/syndicate + cost = 4 + surplus = 50 + +/datum/uplink_item/stealthy_weapons/dehy_carp + name = "Dehydrated Space Carp" + desc = "Looks like a plush toy carp, but just add water and it becomes a real-life space carp! Activate in \ + your hand before use so it knows not to kill you." + item = /obj/item/toy/plush/carpplushie/dehy_carp + cost = 1 + +/datum/uplink_item/stealthy_weapons/edagger + name = "Energy Dagger" + desc = "A dagger made of energy that looks and functions as a pen when off." + item = /obj/item/pen/edagger + cost = 2 + +/datum/uplink_item/stealthy_weapons/martialarts + name = "Sleeping Carp Scroll" + desc = "This scroll contains the secrets of an ancient martial arts technique. You will master unarmed combat, \ + deflecting all ranged weapon fire, but you also refuse to use dishonorable ranged weaponry." + item = /obj/item/book/granter/martial/carp + cost = 17 + surplus = 0 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/stealthy_weapons/martialartstwo + name = "Rising Bass Scroll" + desc = "This scroll contains the secrets of an ancient martial arts technique. You will become proficient in fleeing situations, \ + and dodging all ranged weapon fire, but you will refuse to use dishonorable ranged weaponry." + item = /obj/item/book/granter/martial/bass + cost = 18 + surplus = 0 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/stealthy_weapons/crossbow + name = "Miniature Energy Crossbow" + desc = "A short bow mounted across a tiller in miniature. Small enough to \ + fit into a pocket or slip into a bag unnoticed. It will synthesize \ + and fire bolts tipped with a paralyzing toxin that will briefly stun \ + targets and cause them to slur as if inebriated. It can produce an \ + infinite number of bolts, but takes time to automatically recharge \ + after each shot." + item = /obj/item/gun/energy/kinetic_accelerator/crossbow + cost = 12 + surplus = 50 + exclude_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/stealthy_weapons/traitor_chem_bottle + name = "Poison Kit" + desc = "An assortment of deadly chemicals packed into a compact box. Comes with a syringe for more precise application." + item = /obj/item/storage/box/syndie_kit/chemical + cost = 6 + surplus = 50 + +/datum/uplink_item/stealthy_weapons/romerol_kit + name = "Romerol" + desc = "A highly experimental bioterror agent which creates dormant nodules to be etched into the grey matter of the brain. \ + On death, these nodules take control of the dead body, causing limited revivification, \ + along with slurred speech, aggression, and the ability to infect others with this agent." + item = /obj/item/storage/box/syndie_kit/romerol + cost = 25 + cant_discount = TRUE + exclude_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/stealthy_weapons/sleepy_pen + name = "Sleepy Pen" + desc = "A syringe disguised as a functional pen, filled with a potent mix of drugs, including a \ + strong anesthetic and a chemical that prevents the target from speaking. \ + The pen holds one dose of the mixture, and can be refilled with any chemicals. Note that before the target \ + falls asleep, they will be able to move and act." + item = /obj/item/pen/sleepy + cost = 4 + exclude_modes = list(/datum/game_mode/nuclear) + +datum/uplink_item/stealthy_weapons/taeclowndo_shoes + name = "Tae-clown-do Shoes" + desc = "A pair of shoes for the most elite agents of the honkmotherland. They grant the mastery of taeclowndo with some honk-fu moves as long as they're worn." + cost = 12 + item = /obj/item/clothing/shoes/clown_shoes/taeclowndo + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/stealthy_weapons/suppressor + name = "Suppressor" + desc = "This suppressor will silence the shots of the weapon it is attached to for increased stealth and superior ambushing capability. \ + It is compatible with many small ballistic guns including the Stechkin and C-20r, but not revolvers or energy guns." + item = /obj/item/suppressor + cost = 1 + surplus = 10 + exclude_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/stealthy_weapons/soap + name = "Syndicate Soap" + desc = "A sinister-looking surfactant used to clean blood stains to hide murders and prevent DNA analysis. \ + You can also drop it underfoot to slip people." + item = /obj/item/soap/syndie + cost = 1 + surplus = 50 + +/datum/uplink_item/stealthy_weapons/soap_clusterbang + name = "Slipocalypse Clusterbang" + desc = "A traditional clusterbang grenade with a payload consisting entirely of Syndicate soap. Useful in any scenario!" + item = /obj/item/grenade/clusterbuster/soap + cost = 6 diff --git a/code/modules/uplink/uplink_items/uplink_stealthdevices.dm b/code/modules/uplink/uplink_items/uplink_stealthdevices.dm new file mode 100644 index 0000000000..d98548612e --- /dev/null +++ b/code/modules/uplink/uplink_items/uplink_stealthdevices.dm @@ -0,0 +1,125 @@ + +/* + Uplink Items: + Unlike categories, uplink item entries are automatically sorted alphabetically on server init in a global list, + When adding new entries to the file, please keep them sorted by category. +*/ + +// Stealth Items + +/datum/uplink_item/stealthy_tools/agent_card + name = "Agent Identification Card" + desc = "Agent cards prevent artificial intelligences from tracking the wearer, and can copy access \ + from other identification cards. The access is cumulative, so scanning one card does not erase the \ + access gained from another. In addition, they can be forged to display a new assignment and name. \ + This can be done an unlimited amount of times. Some Syndicate areas and devices can only be accessed \ + with these cards." + item = /obj/item/card/id/syndicate + cost = 2 + +/datum/uplink_item/stealthy_tools/ai_detector + name = "Artificial Intelligence Detector" + desc = "A functional multitool that turns red when it detects an artificial intelligence watching it, and can be \ + activated to display their exact viewing location and nearby security camera blind spots. Knowing when \ + an artificial intelligence is watching you is useful for knowing when to maintain cover, and finding nearby \ + blind spots can help you identify escape routes." + item = /obj/item/multitool/ai_detect + cost = 1 + +/datum/uplink_item/stealthy_tools/chameleon + name = "Chameleon Kit" + desc = "A set of items that contain chameleon technology allowing you to disguise as pretty much anything on the station, and more! \ + Due to budget cuts, the shoes don't provide protection against slipping." + item = /obj/item/storage/box/syndie_kit/chameleon + cost = 2 + exclude_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/stealthy_tools/chameleon_proj + name = "Chameleon Projector" + desc = "Projects an image across a user, disguising them as an object scanned with it, as long as they don't \ + move the projector from their hand. Disguised users move slowly, and projectiles pass over them." + item = /obj/item/chameleon + cost = 7 + +/datum/uplink_item/stealthy_tools/codespeak_manual + name = "Codespeak Manual" + desc = "Syndicate agents can be trained to use a series of codewords to convey complex information, which sounds like random concepts and drinks to anyone listening. \ + This manual teaches you this Codespeak. You can also hit someone else with the manual in order to teach them. This is the deluxe edition, which has unlimited uses." + item = /obj/item/codespeak_manual/unlimited + cost = 3 + +/datum/uplink_item/stealthy_tools/combatbananashoes + name = "Combat Banana Shoes" + desc = "While making the wearer immune to most slipping attacks like regular combat clown shoes, these shoes \ + can generate a large number of synthetic banana peels as the wearer walks, slipping up would-be pursuers. They also \ + squeak significantly louder." + item = /obj/item/clothing/shoes/clown_shoes/banana_shoes/combat + cost = 6 + surplus = 0 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/stealthy_tools/emplight + name = "EMP Flashlight" + desc = "A small, self-recharging, short-ranged EMP device disguised as a working flashlight. \ + Useful for disrupting headsets, cameras, doors, lockers and borgs during stealth operations. \ + Attacking a target with this flashlight will direct an EM pulse at it and consumes a charge." + item = /obj/item/flashlight/emp + cost = 2 + surplus = 30 + +/datum/uplink_item/stealthy_tools/failsafe + name = "Failsafe Uplink Code" + desc = "When entered the uplink will self-destruct immidiately." + item = /obj/effect/gibspawner/generic + cost = 1 + surplus = 0 + restricted = TRUE + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/stealthy_tools/failsafe/spawn_item(spawn_path, mob/user, datum/component/uplink/U) + if(!U) + return + U.failsafe_code = U.generate_code() + to_chat(user, "The new failsafe code for this uplink is now : [U.failsafe_code].") + if(user.mind) + user.mind.store_memory("Failsafe code for [U.parent] : [U.failsafe_code]") + return U.parent //For log icon + +/datum/uplink_item/stealthy_tools/mulligan + name = "Mulligan" + desc = "Screwed up and have security on your tail? This handy syringe will give you a completely new identity \ + and appearance." + item = /obj/item/reagent_containers/syringe/mulligan + cost = 3 + surplus = 30 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/stealthy_tools/syndigaloshes + name = "No-Slip Chameleon Shoes" + desc = "These shoes will allow the wearer to run on wet floors and slippery objects without falling down. \ + They do not work on heavily lubricated surfaces." + item = /obj/item/clothing/shoes/chameleon/noslip + cost = 2 + exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops) + player_minimum = 20 + +/datum/uplink_item/stealthy_tools/syndigaloshes/nuke + item = /obj/item/clothing/shoes/chameleon/noslip + cost = 4 + exclude_modes = list() + include_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/stealthy_tools/jammer + name = "Radio Jammer" + desc = "This device will disrupt any nearby outgoing radio communication when activated. Does not affect binary chat." + item = /obj/item/jammer + cost = 5 + +/datum/uplink_item/stealthy_tools/smugglersatchel + name = "Smuggler's Satchel" + desc = "This satchel is thin enough to be hidden in the gap between plating and tiling; great for stashing \ + your stolen goods. Comes with a crowbar and a floor tile inside. Properly hidden satchels have been \ + known to survive intact even beyond the current shift. " + item = /obj/item/storage/backpack/satchel/flat + cost = 2 + surplus = 30 diff --git a/code/modules/uplink/uplink_items/uplink_support.dm b/code/modules/uplink/uplink_items/uplink_support.dm new file mode 100644 index 0000000000..fe1415adc8 --- /dev/null +++ b/code/modules/uplink/uplink_items/uplink_support.dm @@ -0,0 +1,76 @@ + +/* + Uplink Items: + Unlike categories, uplink item entries are automatically sorted alphabetically on server init in a global list, + When adding new entries to the file, please keep them sorted by category. +*/ + +//Support and Mechs + +/datum/uplink_item/support/clown_reinforcement + name = "Clown Reinforcements" + desc = "Call in an additional clown to share the fun, equipped with full starting gear, but no telecrystals." + item = /obj/item/antag_spawner/nuke_ops/clown + cost = 20 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + restricted = TRUE + +/datum/uplink_item/support/reinforcement + name = "Reinforcements" + desc = "Call in an additional team member. They won't come with any gear, so you'll have to save some telecrystals \ + to arm them as well." + item = /obj/item/antag_spawner/nuke_ops + cost = 25 + refundable = TRUE + include_modes = list(/datum/game_mode/nuclear) + restricted = TRUE + +/datum/uplink_item/support/reinforcement/assault_borg + name = "Syndicate Assault Cyborg" + desc = "A cyborg designed and programmed for systematic extermination of non-Syndicate personnel. \ + Comes equipped with a self-resupplying LMG, a grenade launcher, energy sword, emag, pinpointer, flash and crowbar." + item = /obj/item/antag_spawner/nuke_ops/borg_tele/assault + refundable = TRUE + cost = 65 + restricted = TRUE + +/datum/uplink_item/support/reinforcement/medical_borg + name = "Syndicate Medical Cyborg" + desc = "A combat medical cyborg. Has limited offensive potential, but makes more than up for it with its support capabilities. \ + It comes equipped with a nanite hypospray, a medical beamgun, combat defibrillator, full surgical kit including an energy saw, an emag, pinpointer and flash. \ + Thanks to its organ storage bag, it can perform surgery as well as any humanoid." + item = /obj/item/antag_spawner/nuke_ops/borg_tele/medical + refundable = TRUE + cost = 35 + restricted = TRUE + +/datum/uplink_item/support/reinforcement/saboteur_borg + name = "Syndicate Saboteur Cyborg" + desc = "A streamlined engineering cyborg, equipped with covert modules. Also incapable of leaving the welder in the shuttle. \ + Aside from regular Engineering equipment, it comes with a special destination tagger that lets it traverse disposals networks. \ + Its chameleon projector lets it disguise itself as a Nanotrasen cyborg, on top it has thermal vision and a pinpointer." + item = /obj/item/antag_spawner/nuke_ops/borg_tele/saboteur + refundable = TRUE + cost = 35 + restricted = TRUE + +/datum/uplink_item/support/gygax + name = "Dark Gygax Exosuit" + desc = "A lightweight exosuit, painted in a dark scheme. Its speed and equipment selection make it excellent \ + for hit-and-run style attacks. Features an incendiary carbine, flash bang launcher, teleporter, ion thrusters and a Tesla energy array." + item = /obj/mecha/combat/gygax/dark/loaded + cost = 80 + +/datum/uplink_item/support/honker + name = "Dark H.O.N.K." + desc = "A clown combat mech equipped with bombanana peel and tearstache grenade launchers, as well as the ubiquitous HoNkER BlAsT 5000." + item = /obj/mecha/combat/honker/dark/loaded + cost = 80 + include_modes = list(/datum/game_mode/nuclear/clown_ops) + +/datum/uplink_item/support/mauler + name = "Mauler Exosuit" + desc = "A massive and incredibly deadly military-grade exosuit. Features long-range targeting, thrust vectoring \ + and deployable smoke. Comes equipped with an LMG, scattershot carbine, missile rack, an antiprojectile armor booster and a Tesla energy array." + item = /obj/mecha/combat/marauder/mauler/loaded + cost = 140 diff --git a/tgstation.dme b/tgstation.dme index f52892fce3..3bf9a936d4 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -2994,6 +2994,18 @@ #include "code\modules\uplink\uplink_devices.dm" #include "code\modules\uplink\uplink_items.dm" #include "code\modules\uplink\uplink_purchase_log.dm" +#include "code\modules\uplink\uplink_items\uplink_ammo.dm" +#include "code\modules\uplink\uplink_items\uplink_badass.dm" +#include "code\modules\uplink\uplink_items\uplink_bundles.dm" +#include "code\modules\uplink\uplink_items\uplink_clothing.dm" +#include "code\modules\uplink\uplink_items\uplink_dangerous.dm" +#include "code\modules\uplink\uplink_items\uplink_devices.dm" +#include "code\modules\uplink\uplink_items\uplink_explosives.dm" +#include "code\modules\uplink\uplink_items\uplink_implants.dm" +#include "code\modules\uplink\uplink_items\uplink_roles.dm" +#include "code\modules\uplink\uplink_items\uplink_stealth.dm" +#include "code\modules\uplink\uplink_items\uplink_stealthdevices.dm" +#include "code\modules\uplink\uplink_items\uplink_support.dm" #include "code\modules\vehicles\_vehicle.dm" #include "code\modules\vehicles\atv.dm" #include "code\modules\vehicles\bicycle.dm" From 9ba5f353983270970df84c5753f70cc6b4e7cfbb Mon Sep 17 00:00:00 2001 From: Trilbyspaceclone <30435998+Trilbyspaceclone@users.noreply.github.com> Date: Thu, 9 Jan 2020 16:02:53 -0500 Subject: [PATCH 054/203] Update uplink_items.dm --- code/modules/uplink/uplink_items.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index 3acdf6c827..ea52b8fe11 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -108,7 +108,7 @@ Uplink Categories: Due to how the typesof() in-built byond proc works, it should be kept in mind the order categories are displayed in the uplink UI is same to the order they are loaded in the code. - I trust no extra filter is needed as long as they are all contained within the following lines. + I trust no extra filter is needed as long as they are all contained within the following lines. When adding new uplink categories, please keep them separate from their sub paths here and without set item. Failure to comply may result in the new categories being listed at the bottom of the UI. */ @@ -164,4 +164,4 @@ //Discounts (dynamically filled above) /datum/uplink_item/discounts - category = "Discounted Gear" \ No newline at end of file + category = "Discounted Gear" From 05d86b7072a4c9b342d755c399ee19e570208eea Mon Sep 17 00:00:00 2001 From: Trilbyspaceclone <30435998+Trilbyspaceclone@users.noreply.github.com> Date: Thu, 9 Jan 2020 16:03:27 -0500 Subject: [PATCH 055/203] Update uplink_items.dm --- code/modules/uplink/uplink_items.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm index ea52b8fe11..18dc34e34b 100644 --- a/code/modules/uplink/uplink_items.dm +++ b/code/modules/uplink/uplink_items.dm @@ -108,7 +108,7 @@ Uplink Categories: Due to how the typesof() in-built byond proc works, it should be kept in mind the order categories are displayed in the uplink UI is same to the order they are loaded in the code. - I trust no extra filter is needed as long as they are all contained within the following lines. + I trust no extra filter is needed as long as they are all contained within the following lines. When adding new uplink categories, please keep them separate from their sub paths here and without set item. Failure to comply may result in the new categories being listed at the bottom of the UI. */ From e008388176e03f8ed8654d2f099eb1a48b9748ab Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 9 Jan 2020 16:13:23 -0700 Subject: [PATCH 056/203] Bee models --- .../living/simple_animal/friendly/bumbles.dm | 48 ++++++++++++++++++ icons/mob/animal.dmi | Bin 228532 -> 224694 bytes icons/mob/bees.dmi | Bin 2932 -> 11655 bytes icons/mob/pets.dmi | Bin 67276 -> 69733 bytes 4 files changed, 48 insertions(+) create mode 100644 code/modules/mob/living/simple_animal/friendly/bumbles.dm diff --git a/code/modules/mob/living/simple_animal/friendly/bumbles.dm b/code/modules/mob/living/simple_animal/friendly/bumbles.dm new file mode 100644 index 0000000000..63e9fbf852 --- /dev/null +++ b/code/modules/mob/living/simple_animal/friendly/bumbles.dm @@ -0,0 +1,48 @@ +/mob/living/simple_animal/pet/bumbles + name = "Bumbles" + desc = "Bumbles, the very humble bumblebee." + icon_state = "bumbles" + icon_living = "bumbles" + icon_dead = "bumbles_dead" + turns_per_move = 1 + response_help = "shoos" + response_disarm = "brushes aside" + response_harm = "squashes" + speak_emote = list("bzzzs") + maxHealth = 100 + health = 100 + harm_intent_damage = 1 + friendly = "bzzs" + density = FALSE + movement_type = FLYING + pass_flags = PASSTABLE | PASSGRILLE | PASSMOB + ventcrawler = VENTCRAWLER_ALWAYS + mob_size = MOB_SIZE_TINY + mob_biotypes = list(MOB_ORGANIC, MOB_BEAST) + gold_core_spawnable = FRIENDLY_SPAWN + verb_say = "bzzs" + verb_ask = "bzzs inquisitively" + verb_exclaim = "bzzs intensely" + verb_yell = "bzzs intensely" + +/mob/living/simple_animal/pet/bumbles/Initialize() + . = ..() + verbs += /mob/living/proc/lay_down + +/mob/living/simple_animal/pet/bumbles/ComponentInitialize() + . = ..() + AddElement(/datum/element/wuv, "bzzs!") + +/mob/living/simple_animal/pet/bumbles/update_canmove() + ..() + if(client && stat != DEAD) + if (resting) + icon_state = "[icon_living]_rest" + collar_type = "[initial(collar_type)]_rest" + else + icon_state = "[icon_living]" + collar_type = "[initial(collar_type)]" + regenerate_icons() + +/mob/living/simple_animal/pet/bumbles/bee_friendly() + return TRUE //treaty signed at the Beeneeva convention diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index a46ad8364061e3ce49e1a330205bcafec4fb881a..d3ffdb62e46245282f5879105d3330afbc20a1ee 100644 GIT binary patch literal 224694 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%0AQ!m|x;(&+r%vy<)zCyQgyMZ~kJr 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

e8BD3H-KkiZQY8alwa2(e}XilgdsqS97K|k8l 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%0A%W)&ab2Ds&O9 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 z%0D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 JQ!;=5{{V7~kxu{s literal 228532 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 R>%9y>;OXk;vd$@?2>_GuHktqc diff --git a/icons/mob/bees.dmi b/icons/mob/bees.dmi index 5d9bfea48b6e7c2ebced4097eac6743127692637..0a8e25c76330ff546211f890c6317d4aefc137ce 100644 GIT binary patch literal 11655 zcmch72UHX5+Vw;b6cw-?nh?B#jU(8=!hyt!0R%+>so@+{O6V;Lq}Yz4B1#cOASfVB z2pl??1W`amKx*g_5P<{;Ero<6{~Nvkt>0bi{&(H)Ukl!>Av43wy!+Yj-us!TGgfA6 z6x0vB4`zTNa~2Dh}&z1FDz#7fz~ z($e|8#Eo?h94%8@A6K4ZU&RdGqewHt*a&>Z-?IeDS!ZCjIOA`E|Ox zXLfv;`Q+sG#jz#)(!9EpOW9gm{m?J0HAQU?23o7$7zruo}((24dFzZX=j9Hkhayn1p)@XLvd}&vZ4=G7`D-2u|+`B=2 zKki*X5(H^OsN+Y@UrC-CAoz4(@nf^}F`viNQM1>NTt0v>SZ?6A?$oLGogWpsc5&iI zD^8pZ`(PV&v)6WA5hf}1CND-@F5)R>JRWw556Dy4;ahcndt$+7PRCgv_ssoRhwJNu zn$`R)F8I6Y?{WS8-sqQwV8TJt5bM|a)Y(W6Q^wPl`OVMOG=xHYi^n%19!Fyoy;-fK zv}>jQpoBU(!O$r-M13MpdHWB#-9gvn2>D&6X*2B&d|N_O`~v)nZAU zT(&T9vrp5Uz{!hb>#}Srf^XQzo59>Fj&at{8lMThL0>a`FkuzRS>L{lW|xch7Diu? z_!wdS=y|mRe`JlKqNDw`aHp8DL5G6Nv#?YB#yK$pDxKy~faFgX+mfM0yy!%yyCiQr zB!nOK^#Anw44+^BX;rweNi+5*r6H3DZg+T!2(@Zx#QXT$v8e;t>a>`DWV<|VGRy4`Vv%t4ZPQH?pll#r- z=Cx}uV`F2dIkvMBe1My4mygQ~py38kndQ^bnerq~T%j1X(oK=*=SPy!RwSyIicwcZ z(u?G;8-Lki>J-B0&Z%u^Rk@~f+S2lTRnOgx{`(x;yK|fbm{I|?3$YUR38pNMTqlog zojTwxiklJSjfw5gLd~O9h6K(^HRH_1JZn!ebGd;@(fRS&dm3?iJDz5L zzoOoS9*?TEl?d7=XmVmAr}XQtzWWNZ(0jU|d`^s>B_H{D_0TGCVjUE-H}XhZ?F~IG zDo3!kXPkQvb5eL$FEaK#V@y!pOI=oRxa18~;VXL_BW4wnb$1u!6bfA~c8CLY zn)eh8I-q=d-@G}(npPncXg$uG2yeW&w~I3{$%!iwXHNE4wx9HOD!m-b+*YcxpOm|7 z_X4aN)Mgobh_2ArG8&}5X;X>3;-=lxM!nX_{YL4fa`N)N`iXjdXuVE@Qqjo*!l5jy zl)c8->5}QPLC%X(tCYhVSum@89R^+F9D{n;Lv$(ECJ_4lmwztK@`XZ=meiw49OeAA zF2Zs~|MOw70Df3iIR7ONZ_`CfKDp*s#?VML{*dXhhcenUZx=~!GjwbdaUws$S6CG% z7%#KeMdfu-Z7N7OT<8b()0C9Xni`}}48hH4IwBMOFM zFs7l{E|G^GtBiD2qf1<#8Ehys`N1M*TcP{u_>$ZGi>G5V3Yt_D4DVv-nDLY4Xy<*s z_Q@Dhya07UViUO<&5&VWMH!s7_gaw%R|dx-Co}8rvd=58LRIRc(`E>J|4i@4)r_4| z$P(Ye&IH3D+l@p;8D;46q}>K01noB#?>Yk^AFe?D*M?r)0SG!pjWqSw-H~AaG?Ut_ z>OO$OOvR$BlfBDqy$EMzwIMguV&ve%va;>Y{GdsKengqwB`Y zeEW1z7&$Yrhtw3J(+{TeT-G8HYf*Qz~PZ^l2= zsvJ^ZUtfY3h37jIpS0n;84Fmsq2}(?-_XMI#EA*7eI_Qprjn)LIP=U;00*lG!>bWq zL$}fO4GkOfAAvuPkqCayaJ>N|*qx-^kZ5k8G3Q*?r{)yn{OWux#WVk0mQ|h6ML>~7 zC&>ie;nlQozjJptLuy3);`A-pxcxdgxAgEC3YW@CjJruk7Uv$4ey2NB*8(l*tt7+J z)ars(#>2){z@+CkL=YkG$1P(j14fu=9Xi@PHo{`>GUXySNHAJl4uJfbDx9vaALz=n zDyhGrWZFHWrwLBnp3U(;QM6oJ=CgsEn`p5B{h$TbJ>E+t$uKzg*5XT}MpcG17Ipae zT2KVK8L;uZAGDa()3J%T8Y!m@?cXBau^&K;zghLa2DI;(?M)OebH5+T%P+MM$BY0_ zncM74$ZeEZx=wKOCe$G1m%1{aRo#UGfdV|{!Gm6#Ys1%fq*z(Rg4y%w-~6Oy%r``6 zGok&e!~;ThKc>hY{thfPlnok<-aNTU#Zo`{2d>seq-$zwCXq;qCCVieAypR*^p{@X z8tPQtqxY0m_*IhcrABo*23Puy&M$U*Z_UByxT;rzsuMH#g3R!!U=cv&%pWJpefzee z9IM0fbtc9Tl1iJL_zz?AW##4eu?w>eaEsWNSy`;`vd*3!FWm_Z2LE@RiG_*wTdrZ> zG5bXWV0LO<_MZB|2sXvr-ya>+H@$lQ1FgGsd`L)%&uL!h{QSJ&%MGR9uJ%(|Ds;~U zfsCS%fSHyw%BA&XM-ZF4yPtHC(PTqR*Qs2>%*Nm&S44tPoM0mB*1j`YS~prc<9}LK z!H?2+U9w2jpI~<88BRg0uKe~C?BI@^g?pbVyZd2xHZX#Rs=p($$eiKyVBW+NZWwnS zfua;j$_K^hvrtv^fyPH6l<;W3@`FU<<^Em(uf{>?`JG-pIpGRfX1^RQhQ|i@TG81|xKLIY&jY0)++W+(fWy=4f?G zoG=pdLFjB{bF-CG%uwHW@nl8^*{+{uFi<52h?$g-@!`XVTE*?C)*-zekD>UI?KgEc z%ALVt%XKFDD}!&nQN}`o-0$a;m={TewoQWdMC8WD#yKQnqUSeuhU0VOS(i@tAz|5)_P5quVf24z02@JN|FugkoGCS zaQ}aXsm{niQ&M?sJYW(Vw8#CTX=-WM2eONmVP9?u?Q$+HcB-LLte3;S#}>!VEy-kC z*1@EhKb-PdCptPhVPGu)FPTi9nH?X`c9~Ev2yyb;eO!3Y{S?0d?VR4qLOV+yHANT( zj@km+btgoY2AObtBAdlA^JeOUXbNi^PIT?^`B~l14<0BswX|3`sxE-q*v(IgG)1dY z_wC!4^z>;?<(u&^fk0s16(Ty-wzTy6@ZrPW1<&H8au%!A^V&Y#lG(#|{?l#pD!2*v z5_y*$VkL`FJbMUpzo?E}t@D0tzDw0T!pL+iv;1U-^_<{9-d&l`ju=3a9{Mg-833qW zc)TlxLboPj`*QMbtfKJ>*wM^pZU=wLHW<32c~#vJ0a6(VD`fa)IFi! zHv!6#03=11buH|n@haaC(ddR|YThrqlk{ zN~*M6d5`rO;=b4o!jZfL);#N+#Ek8XD+ze`Iop(Fi`c3mpzBKhMj>%Y;yuLwrZ z41p)=$4f3zxXllazE=WXRi&cU2}=V~`w+Mb*9ec>(r5CVeVNRT5XFTo|80jJW!YOc z>^BFIl4i+)%dXoaBi+9(r-;5OqVCS%kk{TCnlU7gzzR9-9GY_3iF*EG9_ARhx+CIR3TSU(4@m+=@IZ{AoJR7IG|oSm-DcZgB3Ya*y{%I!^!wb6_I#ZjY6}Nj zid!BqYm_dp-B#;>q$na|&qytBV});CmH%S({Mfd~Q_mlpn)_yT^!g7*V!Eqj9*#Cc zE0O2lQD#04#NZ3g{)5AnN6KmwFD)v5v7rP&?_g)XPccxnRGEtN27#N1KfEkZTSRTC ze*A9?$Xj!ZubTiBV&S9wY4RWkhcGSCTBe+h1Pefn&tM*)r`Urx=NDg}&b0XkNP9G$ z7EZSo2+|L&CEAYn@RJSeb>_D3C$%`a-=6}TiG%8A!DB%Dah1H#eN-vu{Kx%O;vgVM zCcu}S?r3iBZ=5))*wd;=-i-o&%3RJ)HDv5^Y1tWN?6xyuFJQ%8tE24l05lm_0?jq5 zvtCmb8>I&ibem*Gt7JKr;bZCWrX6L_&znSa;7N*!73JtC9X4@wjo>{1K-`B5sH%~; zd*0}QmwjwnfA-wQYLU26x@l}$x!o&}(d0~X==y$&{x;4lbwj8e5OBGAUD74_i%^%@ z-?50|8d~cPl+5@#*Ktl;UIM3_|5+Y%$&Xqad-J!SGKn z&v)F1;*3n{mO&RGeX+9%e-jZ9hL?!e$oYLruVrf=;S*J&4=(@PNy!-BP`5LMnO)_XSFS##bk?>M}^d;pg&CeMRPC0hN21Gh*ka34?RFP7ik|}hRrgyP_js&>h zA_iJ-AW^{8-zg6H07_ilIMjlWZ^z&X48}et=-u;sR(dj)WpF8zQffbU!eUL_IOOvW zY+|^)wH8Y5SW-d1|Hk{lx`3JOzU5RpQ5)9OJb(VYyIHQcuQ%j-w4hm-m9?#)?UwJ! zjY?_Uva%DD`X(%n#6l#p?D}&3K3I8y-0zY!_q%Mpe*O9&whMV7pJ>B=ZiYF&Q6TuE z!NAY5Amic-rZKe(o=<)O#jAqHSx?7CD%SkV%Bo0bRuk9 z0FK`FwpQ`Vn?A)0ubXUIj!@*ztoxC?Rn9-tK}jj?*HUkJIQ+`$hdBAQpV_@zWg6e-t4Lmgg0Nz5D^@{I7g)GZEoBa&y{ ze)+|@T`uxxD*GC{8s8S~by0~5C$j~aH}^xhPD>k62Dk0Lw<7XpH0(Vjo3!zJO9CM) z^B;F7{->sfO*LCC3H4|9@OX(-9=)e)puDSVffiz4oNq3~ycFp5;FDQOX`yS08$XWC z8-e&lUh7KD17I99-_@)3f#8LIB_yPyAY_Go)h?CQ6CsWumNYD&Cv<>&7*>yVB|!Pn z7HJ!U-f}?-wl&2{FU3kljwVfT-eNCbJ_-DRAwAkJ3pkLAr|B&qAURz^Kgcg&^BpC> z)vG!=mv_)B5P=AwPQmpL`HYxU4yVx2d}rlzj# zx(6}&YH&EZq{*c^Y*%hiUtiwh;^I;MyAN1V5NIi6Uci7b$*yvU*^C5^{H1SSS%Rp_ zT-E(mpA{O-h&61V2$_uO#ENWyhxf#RG_M=0bULTFxZS)BsC&*t7HMaSm4QHb@HScF z_*r*%cSjnY()G$=3o0o!wV-ci)`b=i%<2xQ8x;XR{!?ebTl(^uOpC-24zqJ3@7Mc9 z|JPN2PXkVxnfd2jWm9-e;7^MXb_`Bp+Z~QUgKF{DOQCRtOrf)NlOsX5G}l40ak(2P z1x+=zJ=0~(HSe~gCN=)fIs1%7F3bK`Z8m~fc328n8MXK0R{ z1q55zmC=t0C(2Q=(!oT*(bP)rU?*8T6rqrX_%m~+`F zflIgK*#99qNJpSJL-u;65?}ygf$s*gN$HmvqNaw1UiB7LcOMWk4UK@zvbrrLtDtCj zWM(~Lu`5)B(n13820wxD#YpPRFzM;j)=!@-n?lq3CRi*zhjvadchX_~l%XP(1=c#o z)r<446MMX-=R|X7(Xru1rXDzoIId=F#JYAKtz;_?G(bkXSAvr>R<_W$&j^%D{v_SD z79_h;WB>ToQ>!d@!~pjP=nwr(WlqY1Om4cj)FM{FU}<)CHmU2KBL;+@D!#$=0+)N< zTrSrekEbe|2F|&FwnaXn2nffLq6qWgM7Di8iwCj><{mE#dhr}bzy{K?9C^BSgtxdv zzo(|9<=T2+5X-=EK~i~P0U8*tUS1J05nJF&sTw}9yS_V=)iu#<%#PQ|cd51m(QYQ!758dgiAKSW3|^A8X3I=m5ymjGW;F{ zSLM?HKkxSz?R$DZAtQ%JE4WRkWHy#d%5)|^J>BPh9GB%W5*+5vi`SX>_;t#=Z>B(f zQGkVI5aLZgi8!%+uNorUs9FS@R7to)AoLTP2-3v6icuA=k#(DOcKtkEilM9TCH^Q< z+PeBD-DDx%{fDg{Hw0n9(1F9cCrv9H`eQAg@}MM8#%Iv@up1svU(;Hv5-!>UwX-G{E!OtVP1a zV%F62^lhJJpX2Oe!<04|O$SehW%d;`vSC)%*3S;AFdQ+FzsG=p>~4f;Z5e1EOVWRX zL(pnl>AL_w{Z7&ucyjfKKdtguY<%OW!do_D0Q<+xVmRN9fnCU_vNxDM=n5;3U7)aW z24zE}rpu>+>IXvJK`Q9=Z)y>i0!_sH5#~U+C4uWfc$uOkisrHzWRMEgY2hElG#D)6 z#OXs=<|pzhQq1oRixvcBn0ILL#1-fg=sEvIBbNj$u%|uHXx#j&DW9RRKdWTX%!z%= zXLwYei3=s%uxn<1k&i=2T8pbw`uz2hMRi5KK>M7zcAA7M8>beXliG#;7vvNmdGiZ2 zYPNyEsdG#70j~%mXDRzdhOK2gS&#@pyy_Qu-3k5yjzwb(yM>cg@OHk*|ovRW| zAW)8~*PmL}SMff3cLHlZjz0zac`;(iW^bxwK<2i}EobLM2;_cMA3wMZU zvEu-7gqcpsKYid&yfOckX+j0KwWVctR#sM5>~d2$VO^>ud%P#L8r`Vo=7Lw)fW$bc zUSD<0%I4S4mCsc)@qtRF_I(YI73lwiPR*G|-%a)A2d0sx;$f}GUnCsR)4gB^UXSoA zOsIm3oK0@3*VLKt6|@;G1PZXr>solwR-)s2AaxqGe|)Z3N0Wp7S0&Fs$RMc#f*?I? zq$k4*OW@TExsoXRHJYKKSBa^FUh_5pX)gb>sfH-Idil|!U*F2a0l>NM%mT8G1HH^F;7tWy?4hvsiTNZmcnR@c0a zQbW#cS=l1_eT~NC`}cPy*zEExTej45I<|w;IjDrUw)po9@@|~uK9ZeAYKL!i&bbRZ z%ln8AWyU|ZuCE_pREmtIv<~*q)accXLFTm(cgM;Y27R6eu1@%28)*YKDtN5f@P!X* z#9uV|d{>_kuPkcM?nO7(ZoFl6-=rf_?zImj(5fkrkAmhjkp*G1?lIg8{@}Wv%Lin` zzIvPa-;40R3D6bI<_Vq0`73HGnu&>PkPMk8P}K(y2>kcg*}s!5(x~ze*|1GhH=sEc zWM;SmDn#q}jlxGJ?*iqVJ0pmua=T$6#bFEXXxIkat7-g}7RbWuD>P?9T$wg!^1SG- zOx7dB&GmG(LO|pNOpO;Zv`3o*B0Wi`YjqEzW8m8xunoRip-O12dHKRLsaK_-8inJHvz*?n5hC^I81 zo>-W7D&vXLV5RvPgvaVCRU$O5%{-Q@YH@)f)v%WEgN(e1**<&dBO7NzIT(sNDIF)7ReC^Mts%Yt>V& z9{Aazr>*b?hYcaSkU2+g`10Ua8W|k zbYcE^2B!vwtbi#G&&SjaD}L$5D|9SJZ(-a%cBTJI)F6nCY*}znyn1Ri({34^OylRK zlI)n5V#5{M`>FDUYymR)d-pMk%L9naUjCoGGWKtP?;m!NVv*>m3Gc=B4lqmtD(D^t z5HnqpXWjd#=YZwx7^X)e?R~G#heeOM^82)K-&B4OiVQ+?@eK^wee|kWNE2iv=%`!| zoCKmYNy>5GQJBG>k5-_K9233*uw7cCsR;daa~)I%4nPA0MvRZIoF6sK+6Kp={a=UD z#9w%{9GZ#mLa8CT)rGgzY@NY`3-9V*^Xo2rgP;4b?In%IcyRxIe~|fI!JKr4jHQ6w zOp<9?qjlhpde16(C{yOk+kNQ>zfx$sZu}TR9iP>_@;C36On7odrGMeRCOK0q3J5WuTr!_pHz!1upLhRM8l z=Wmdk;X5HBP7On8kB&x&(>(}?P0S90c)A47#~$!MFwpvZ6|HJ33Si@S-F!9^3VAD$ z;v8tcdYp6TN$;-_knq*_0<&PO{|}L^zV1*>WyAP$~UnO@peTM=XP;_4#|8KMkCyCPQMebM4c`R-_PTd`gCR*8GY1fUje2jq`QsWi5v1A3SdzJ@p~ zi2f-Yx+z#n?34VD5Hps*wU3thKqs-(a~}A7sR)}SZY@0_c}{1J(iwDrT;^%Xl6a%$ z;qX6kht9OX&R77}Rp0V;jF2N@_ezA$e}z^0F%^7hK2sC}9e@8=wE4-n;%FEZt{BSv zaGGrqt1n`-a7xMkwsaRI<~4u6&p{Ytp}fP*81zctxc$?v;L@HDaMm4R0Q9`&v@z zgyoh`Ja`bEAm?aP2djwqGV{VhPbyIiOe7_u=~RS~^v+5`Su%)9Rw`rh1D3ZGIG`W1 zs0D3;ZfZiNsS?kr@diJMF(B2zL{rIEGr}e2>`$_vb9V|hKhX&^#x39%f~icU)k_Uk z6nS0LpG)QRtUDe6!*@SqH)ncg7e_MPjdoOlrpr?0j{u70)J70jIJ7T!8(#svivrWK n0;%mLt9`Wo->r)_iTtrur%}sbKbL?vt0B}0tK$Vn-LC&1&wRfD%iqqJM;jnU-iPPs1I2~wv9X*)#2qRZ|dRe z^E3WRwq50sleYd8Etf~t=U2@}b-J<_WM)p3=_TxTyr8!`Z+E}F30|{qkIUkrm26aU zh+%Eqy`Mga9KJ;Rj4|%LztwyT^&zpLvzPORJ7c#@bUPT9)+eCNXl>G3%$YWv)GPmi zHCOCj%4ul>Kqld^owZwh5o_E!Q+y*3viY(k+&^ zI2wE|?nsTcHtIZMKCeGJdA2V|X}7-C4cB1l(bRGuLWGj5zHyo9*}9#&)u{UBsynAg zEzB+EwlaPln!fdv&Fg(iWlNp=%_W{bRxn!_M?beju0Guw1dJ2+Eh7Lb9e`&ju=Cgd zSKiUr=CX~99?5Zw;|r4= zSuY(lYa07rOAodnPy+E35@J2TAOM+0he)iME)A>Bs@$Hy#|;e)_4LU}|1(FZ5o)30 z+CwIgf-`nbd8g_^bGB+kJpTO1jxxH~S|6Hv;hIg}Yq`O+zqj{?Cf`C2O5{Zsi-Q5K z8@JR&bJWGUR0>=N*JLdRjvcRYKYg(1N*aN$U2#no8-m9wNh3fCCm9PFhym0t@GT@k ze;HA_G=du`6i!Xl-AmRaOLQA3mm;|?$4LfvsC~Ts{7yCtU69FO3}Yg+*a6nK{m2mO zgZTEwisv&2Zf_Vs7v?PWt?Gseoh*@GUIOiKEcF^%O8vZfW5F0}tcPby`B;(_N)6l| zHvBL~GCEke-fXUQb95?P2jJTyR1KEn&(~b?jzE#7xLG%YQST-;X=imYUYh{XB-vqS zhvX@yDRad)=BVbVN9@Mpwb@I>IcqiTn$Fzeczy=5UDEDgC|x|ro2F^XTRXws3se=# zxLKtQ+$rxwK2cRcq0?DR>>m;KKUsABPVQazu*>zkc-82v@M=j_XbT}xX`n(fIi*M* z?Qez;d|zs0B-<$c{%oR{r=C7lBHmOzW^c#LDt~>&dnJgkxBJ4>ZQK6dDndoi{oodl zag3$ebib2Yl-I*?Ic66ZmAWNTpk?{>*lFYwi-b!_&W!eqwUP!oyak8zhNEzY(hp~# zu&6lWOXK}kLs7&hVfW{Pm!k1;DKcxm!*CW8m@~TCSZSvy6Q9VE`=eDeB*LF6bi z;O&@n%J`p_@%Zu9$H9%!wJWw#+RN)@$Qvu`>S(Z!`FJPiv0BhROT_hIqoI2lnJ#<@ zpF1l8LxpyKiEPftpF6^zu61#ES6fIFj~G?yZ1Tm*DrW$RU)_#{dDiVU0iatEU{zqq zzm4pX!47?YTkOl05=06;rHqC#(#`LIOYVA4{6O9y^Y(sIB}j|x5H_;7SdTN_;d1ww zO61=aAmvo4Lcfz8obI36+ge^;o_heFnVIReZ_I<4AYQA2IE4X+(Bz^U3}U&f&ef#i z{6S{A-0`^;%J1R^Lnhz_cfnIX8nUTDn_)w1O5)8ThB|j4U#ZB;p{ArRgR|m5!5(}o zsY$hjwC>XGV+38#15QZUYRG1bCtI8T5zgOmdQD)Fi2UK1nv05fZImLkeFW!Ddv6ul z#uYv_O@eI*itW++P_YYgj)??51lf;LN*+IMqlFkpmUJr<64_tpKM6ETBB&g`tieEl zCWMn(=;yCQ-BN1L>j$qs)wjm6i*p^zcNQ8fud^mMK5+(?HvPtc5EzCd6gF^%9&QhO za`pq^12$Y_-CRePr6-eBsb{F;#t!XAXO)UTm?d-ysg0t3=VnTE042CRkT^)if|4VP z3o|sw<=os3P==k4azyE&2aWT=C|VhChT7t!BI?3a?*-H{AC!_C}L8tuXu+ zre~&(iWi{S{86DG@LZ25!N2nRy+Lh;C_j$a+emQrCyh%MoW8gKVVU}u_l@-kv}iTs zG=ZJN;`wF9u<2oOX!9mG$ZjR2Cm*6I^Z=^a-2Ag#3Em&0`mwkPmoH2VI{7<*th|w=U zHMSLu<@;LHsaw6ng+~kCd}ZlWwvnQs$-Sq%YRM!HhBrMtFuyNJDByUro==5VQ|Rlf zRA%F961ORr^khW1FmW;eYXBLYT;R2GG~az7dhGF1`e~RacH5&_>@s2CGS8RTw)o_c z%tvpgXo^gYrSe$3Kj%B@^3ZWT2o;UOt2S*6v__%#mXkv7v0{g=nD0`V3&ileF<^BfHmIACT>_{6}fyasPdV3Z9GD+H`;H6 zyKre~C^Jcoy6??;KmfISen-mKFwP0ilFL$n23kFm1A;E9&$%;`h@W@OBIm-d6BV_O z0?1rRA0|~{bchB3UhY5jERO1Bv4h05h&fxxp#L9bp3i`!Q;Owe@94V#n{X)hraamz z4IaAm0xId+XS+G2jDd~!3W^I`J>db;+l#Li)n<~r+C(pArRvqlo6iN>B2W~>nI@9P z(nMk9BMlh1#W>|^y|?A78e?tpO`fZNQqf6f%GW??R8@jv?c7ujZ7ab{FS|SjsX#!c z6w9NP3FfBRO?C{)O%#MpZ#ua~U1V;#ZIqm1X>!r<70yvFJFR2*a;B-q0b`PmwvE4e myq`GG)E7Mgwz?@!z_N+KL{VA!Qn$rcGWh1SN;N9V;Q~x diff --git a/icons/mob/pets.dmi b/icons/mob/pets.dmi index 10f29f51e4bd210f1ad794a16c17a159e4108107..9751e9d964465250f71b4e7f3c27a3ec0f11ba77 100644 GIT binary patch literal 69733 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 QH~@Yr$|=99lr{SLKUSr+lK=n! From 04aa0eda5afd21aca5035dabca988afb69211196 Mon Sep 17 00:00:00 2001 From: Hatterhat Date: Thu, 9 Jan 2020 18:35:13 -0600 Subject: [PATCH 057/203] tg 40046, 41695, 46726 - hope i didnt forget smth --- code/game/objects/items/robot/ai_upgrades.dm | 16 +- .../reagents/reagent_containers/spray.dm | 3 + .../autolathe_designs_electronics.dm | 6 +- ...utolathe_designs_medical_and_dinnerware.dm | 55 +++-- .../autolathe_designs_tcomms_and_misc.dm | 41 ++-- .../autolathe_designs_tools.dm | 37 +-- .../research/designs/bluespace_designs.dm | 2 +- .../research/designs/electronics_designs.dm | 10 + .../research/designs/medical_designs.dm | 156 +++---------- code/modules/research/designs/misc_designs.dm | 212 ++++++++--------- .../research/designs/smelting_designs.dm | 2 +- code/modules/research/designs/tool_designs.dm | 216 ++++++++++++++++++ code/modules/research/machinery/protolathe.dm | 3 +- code/modules/research/machinery/techfab.dm | 3 +- code/modules/research/techweb/all_nodes.dm | 30 ++- tgstation.dme | 1 + 16 files changed, 490 insertions(+), 303 deletions(-) create mode 100644 code/modules/research/designs/tool_designs.dm diff --git a/code/game/objects/items/robot/ai_upgrades.dm b/code/game/objects/items/robot/ai_upgrades.dm index 7f7780d3a4..acfc1353b9 100644 --- a/code/game/objects/items/robot/ai_upgrades.dm +++ b/code/game/objects/items/robot/ai_upgrades.dm @@ -9,8 +9,10 @@ icon_state = "datadisk3" -/obj/item/malf_upgrade/afterattack(mob/living/silicon/ai/AI, mob/user) +/obj/item/malf_upgrade/afterattack(mob/living/silicon/ai/AI, mob/user, proximity) . = ..() + if(!proximity) + return if(!istype(AI)) return if(AI.malf_picker) @@ -18,7 +20,11 @@ to_chat(AI, "[user] has attempted to upgrade you with combat software that you already possess. You gain 50 points to spend on Malfunction Modules instead.") else to_chat(AI, "[user] has upgraded you with combat software!") + to_chat(AI, "Your current laws and objectives remain unchanged.") //this unlocks malf powers, but does not give the license to plasma flood AI.add_malf_picker() + AI.hack_software = TRUE + log_game("[key_name(user)] has upgraded [key_name(AI)] with a [src].") + message_admins("[ADMIN_LOOKUPFLW(user)] has upgraded [ADMIN_LOOKUPFLW(AI)] with a [src].") to_chat(user, "You upgrade [AI]. [src] is consumed in the process.") qdel(src) @@ -26,12 +32,14 @@ //Lipreading /obj/item/surveillance_upgrade name = "surveillance software upgrade" - desc = "A software package that will allow an artificial intelligence to 'hear' from its cameras via lip reading." + desc = "An illegal software package that will allow an artificial intelligence to 'hear' from its cameras via lip reading and hidden microphones." icon = 'icons/obj/module.dmi' icon_state = "datadisk3" -/obj/item/surveillance_upgrade/afterattack(mob/living/silicon/ai/AI, mob/user) +/obj/item/surveillance_upgrade/afterattack(mob/living/silicon/ai/AI, mob/user, proximity) . = ..() + if(!proximity) + return if(!istype(AI)) return if(AI.eyeobj) @@ -39,4 +47,6 @@ to_chat(AI, "[user] has upgraded you with surveillance software!") to_chat(AI, "Via a combination of hidden microphones and lip reading software, you are able to use your cameras to listen in on conversations.") to_chat(user, "You upgrade [AI]. [src] is consumed in the process.") + log_game("[key_name(user)] has upgraded [key_name(AI)] with a [src].") + message_admins("[ADMIN_LOOKUPFLW(user)] has upgraded [ADMIN_LOOKUPFLW(AI)] with a [src].") qdel(src) diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index ddbc6cf92b..2be6401cf3 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -199,6 +199,9 @@ amount_per_transfer_from_this = 5 list_reagents = list("condensedcapsaicin" = 40) +/obj/item/reagent_containers/spray/pepper/empty // for techfab printing + list_reagents = null + /obj/item/reagent_containers/spray/pepper/suicide_act(mob/living/carbon/user) user.visible_message("[user] begins huffing \the [src]! It looks like [user.p_theyre()] getting a dirty high!") return OXYLOSS diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_electronics.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_electronics.dm index 5b247efe74..4ca780620d 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_electronics.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_electronics.dm @@ -54,7 +54,7 @@ /datum/design/desttagger name = "Destination Tagger" id = "desttagger" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 250, MAT_GLASS = 125) build_path = /obj/item/destTagger category = list("initial", "Electronics") @@ -62,7 +62,7 @@ /datum/design/handlabeler name = "Hand Labeler" id = "handlabel" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 150, MAT_GLASS = 125) build_path = /obj/item/hand_labeler category = list("initial", "Electronics") @@ -73,4 +73,4 @@ build_type = AUTOLATHE materials = list(MAT_GLASS = 20) build_path = /obj/item/stock_parts/cell/emergency_light - category = list("initial", "Electronics") \ No newline at end of file + category = list("initial", "Electronics") diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm index 27852b2798..0d303c3968 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_medical_and_dinnerware.dm @@ -68,66 +68,74 @@ /datum/design/scalpel name = "Scalpel" id = "scalpel" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 4000, MAT_GLASS = 1000) build_path = /obj/item/scalpel - category = list("initial", "Medical") + category = list("initial", "Medical","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE /datum/design/circular_saw name = "Circular Saw" id = "circular_saw" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 10000, MAT_GLASS = 6000) build_path = /obj/item/circular_saw - category = list("initial", "Medical") + category = list("initial", "Medical","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE /datum/design/surgicaldrill name = "Surgical Drill" id = "surgicaldrill" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 10000, MAT_GLASS = 6000) build_path = /obj/item/surgicaldrill - category = list("initial", "Medical") + category = list("initial", "Medical","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE /datum/design/retractor name = "Retractor" id = "retractor" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 6000, MAT_GLASS = 3000) build_path = /obj/item/retractor - category = list("initial", "Medical") + category = list("initial", "Medical","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE /datum/design/cautery name = "Cautery" id = "cautery" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 2500, MAT_GLASS = 750) build_path = /obj/item/cautery - category = list("initial", "Medical") + category = list("initial", "Medical","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE /datum/design/hemostat name = "Hemostat" id = "hemostat" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 5000, MAT_GLASS = 2500) build_path = /obj/item/hemostat - category = list("initial", "Medical") + category = list("initial", "Medical","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE /datum/design/beaker name = "Beaker" id = "beaker" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_GLASS = 500) build_path = /obj/item/reagent_containers/glass/beaker - category = list("initial", "Medical") + category = list("initial", "Medical","Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SERVICE | DEPARTMENTAL_FLAG_SCIENCE /datum/design/large_beaker name = "Large Beaker" id = "large_beaker" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_GLASS = 2500) build_path = /obj/item/reagent_containers/glass/beaker/large - category = list("initial", "Medical") + category = list("initial", "Medical","Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SERVICE | DEPARTMENTAL_FLAG_SCIENCE /datum/design/healthanalyzer name = "Health Analyzer" @@ -141,10 +149,11 @@ /datum/design/pillbottle name = "Pill Bottle" id = "pillbottle" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 20, MAT_GLASS = 100) build_path = /obj/item/storage/pill_bottle - category = list("initial", "Medical") + category = list("initial", "Medical","Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/syringe name = "Syringe" @@ -165,15 +174,17 @@ /datum/design/hypovialsmall name = "Hypovial" id = "hypovial" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 500) build_path = /obj/item/reagent_containers/glass/bottle/vial/small - category = list("initial","Medical") + category = list("initial","Medical","Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /datum/design/hypoviallarge name = "Large Hypovial" id = "large_hypovial" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 2500) build_path = /obj/item/reagent_containers/glass/bottle/vial/large - category = list("initial","Medical") + category = list("initial","Medical","Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm index 29d28b7132..a0af3d8b1e 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_tcomms_and_misc.dm @@ -68,58 +68,65 @@ /datum/design/pipe_painter name = "Pipe Painter" id = "pipe_painter" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 5000, MAT_GLASS = 2000) build_path = /obj/item/pipe_painter - category = list("initial", "Misc") + category = list("initial", "Misc","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING /datum/design/airlock_painter name = "Airlock Painter" id = "airlock_painter" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 50, MAT_GLASS = 50) build_path = /obj/item/airlock_painter - category = list("initial", "Misc") + category = list("initial", "Misc","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING /datum/design/cultivator name = "Cultivator" id = "cultivator" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL=50) build_path = /obj/item/cultivator - category = list("initial","Misc") + category = list("initial","Misc","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE /datum/design/plant_analyzer name = "Plant Analyzer" id = "plant_analyzer" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 30, MAT_GLASS = 20) build_path = /obj/item/plant_analyzer - category = list("initial","Misc") + category = list("initial","Misc","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE /datum/design/shovel name = "Shovel" id = "shovel" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 50) build_path = /obj/item/shovel - category = list("initial","Misc") + category = list("initial","Misc","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE | DEPARTMENTAL_FLAG_CARGO /datum/design/spade name = "Spade" id = "spade" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 50) build_path = /obj/item/shovel/spade - category = list("initial","Misc") + category = list("initial","Misc","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE /datum/design/hatchet name = "Hatchet" id = "hatchet" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 15000) build_path = /obj/item/hatchet - category = list("initial","Misc") + category = list("initial","Misc","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE /datum/design/recorder name = "Universal Recorder" @@ -220,10 +227,10 @@ /datum/design/packageWrap name = "Package Wrapping" id = "packagewrap" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 200, MAT_GLASS = 200) build_path = /obj/item/stack/packageWrap - category = list("initial", "Misc") + category = list("initial", "Misc","Equipment") maxstack = 30 /datum/design/holodisk @@ -248,4 +255,4 @@ build_type = AUTOLATHE materials = list(MAT_METAL = 300, MAT_GLASS = 150) build_path = /obj/item/key/collar - category = list("initial", "Misc") \ No newline at end of file + category = list("initial", "Misc") diff --git a/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm b/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm index 0300658a84..c413f546f0 100644 --- a/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm +++ b/code/modules/research/designs/autolathe_desings/autolathe_designs_tools.dm @@ -7,18 +7,20 @@ /datum/design/bucket name = "Bucket" id = "bucket" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 200) build_path = /obj/item/reagent_containers/glass/bucket - category = list("initial","Tools") + category = list("initial","Tools","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE /datum/design/crowbar name = "Pocket Crowbar" id = "crowbar" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 50) build_path = /obj/item/crowbar - category = list("initial","Tools") + category = list("initial","Tools","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/flashlight name = "Flashlight" @@ -63,10 +65,11 @@ /datum/design/tscanner name = "T-Ray Scanner" id = "tscanner" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 150) build_path = /obj/item/t_scanner - category = list("initial","Tools") + category = list("initial","Tools","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING /datum/design/weldingtool name = "Welding Tool" @@ -74,7 +77,8 @@ build_type = AUTOLATHE materials = list(MAT_METAL = 70, MAT_GLASS = 20) build_path = /obj/item/weldingtool - category = list("initial","Tools") + category = list("initial","Tools","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/mini_weldingtool name = "Emergency Welding Tool" @@ -87,26 +91,28 @@ /datum/design/screwdriver name = "Screwdriver" id = "screwdriver" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 75) build_path = /obj/item/screwdriver - category = list("initial","Tools") - + category = list("initial","Tools","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/wirecutters name = "Wirecutters" id = "wirecutters" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 80) build_path = /obj/item/wirecutters - category = list("initial","Tools") + category = list("initial","Tools","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/wrench name = "Wrench" id = "wrench" - build_type = AUTOLATHE + build_type = AUTOLATHE | PROTOLATHE materials = list(MAT_METAL = 150) build_path = /obj/item/wrench - category = list("initial","Tools") + category = list("initial","Tools","Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/welding_helmet name = "Welding Helmet" @@ -122,8 +128,9 @@ build_type = AUTOLATHE materials = list(MAT_METAL = 10, MAT_GLASS = 5) build_path = /obj/item/stack/cable_coil/random - category = list("initial","Tools") + category = list("initial","Tools","Tool Designs") maxstack = 30 + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE /datum/design/toolbox name = "Toolbox" diff --git a/code/modules/research/designs/bluespace_designs.dm b/code/modules/research/designs/bluespace_designs.dm index ec4309b69e..baed378ba1 100644 --- a/code/modules/research/designs/bluespace_designs.dm +++ b/code/modules/research/designs/bluespace_designs.dm @@ -53,7 +53,7 @@ materials = list(MAT_DIAMOND = 1500, MAT_PLASMA = 1500) build_path = /obj/item/stack/ore/bluespace_crystal/artificial category = list("Bluespace Designs") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING /datum/design/telesci_gps name = "GPS Device" diff --git a/code/modules/research/designs/electronics_designs.dm b/code/modules/research/designs/electronics_designs.dm index 818e80beea..c7f9ac044c 100644 --- a/code/modules/research/designs/electronics_designs.dm +++ b/code/modules/research/designs/electronics_designs.dm @@ -23,6 +23,16 @@ category = list("Electronics") departmental_flags = DEPARTMENTAL_FLAG_ALL +/datum/design/ai_cam_upgrade + name = "AI Surveillance Software Update" + desc = "A software package that will allow an artificial intelligence to 'hear' from its cameras via lip reading." + id = "ai_cam_upgrade" + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_GLASS = 5000, MAT_GOLD = 15000, MAT_SILVER = 15000, MAT_DIAMOND = 20000, MAT_PLASMA = 10000) + build_path = /obj/item/surveillance_upgrade + category = list("Electronics") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE + /////////////////////////////////// //////////Nanite Devices/////////// /////////////////////////////////// diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index f2ded3a57b..99cb5bf8ab 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -162,16 +162,6 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL -/datum/design/holobarrier_med - name = "PENLITE holobarrier projector" - desc = "PENLITE holobarriers, a device that halts individuals with malicious diseases." - build_type = PROTOLATHE - build_path = /obj/item/holosign_creator/medical - materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 100) //a hint of silver since it can troll 2 antags (bad viros and sentient disease) - id = "holobarrier_med" - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - /datum/design/healthanalyzer_advanced name = "Advanced Health Analyzer" desc = "A hand-held body scanner able to distinguish vital signs of the subject with high accuracy." @@ -182,6 +172,16 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL +/datum/design/medspray + name = "Medical Spray" + desc = "A medical spray bottle, designed for precision application, with an unscrewable cap." + id = "medspray" + build_path = /obj/item/reagent_containers/medspray + build_type = PROTOLATHE + materials = list(MAT_METAL = 2500, MAT_GLASS = 500) + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + /datum/design/medicalkit name = "Empty Medkit" desc = "A plastic medical kit for storging medical items." @@ -217,7 +217,7 @@ desc = "Produce additional disks for storing genetic data." id = "cloning_disk" build_type = PROTOLATHE - materials = list(MAT_METAL = 300, MAT_GLASS = 100, MAT_SILVER=50) + materials = list(MAT_METAL = 300, MAT_GLASS = 100, MAT_SILVER = 50) build_path = /obj/item/disk/data category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE @@ -238,6 +238,7 @@ /datum/design/defibrillator name = "Defibrillator" + desc = "A portable defibrillator, used for resuscitating recently deceased crew." id = "defibrillator" build_type = PROTOLATHE build_path = /obj/item/defibrillator @@ -257,10 +258,10 @@ /datum/design/defib_heal name = "Defibrillator Healing disk" - desc = "An upgrade which increases the healing power of the defibrillator" + desc = "An upgrade which increases the healing power of the defibrillator." id = "defib_heal" build_type = PROTOLATHE - materials = list(MAT_METAL=16000, MAT_GLASS = 18000, MAT_GOLD = 6000, MAT_SILVER = 6000) + materials = list(MAT_METAL = 16000, MAT_GLASS = 18000, MAT_GOLD = 6000, MAT_SILVER = 6000) build_path = /obj/item/disk/medical/defib_heal construction_time = 10 category = list("Misc") @@ -268,10 +269,10 @@ /datum/design/defib_shock name = "Defibrillator Anti-Shock Disk" - desc = "A safety upgrade that guarantees only the patient will get shocked" + desc = "A safety upgrade that guarantees only the patient will get shocked." id = "defib_shock" build_type = PROTOLATHE - materials = list(MAT_METAL=16000, MAT_GLASS = 18000, MAT_GOLD = 6000, MAT_SILVER = 6000) + materials = list(MAT_METAL = 16000, MAT_GLASS = 18000, MAT_GOLD = 6000, MAT_SILVER = 6000) build_path = /obj/item/disk/medical/defib_shock construction_time = 10 category = list("Misc") @@ -279,10 +280,10 @@ /datum/design/defib_decay name = "Defibrillator Body-Decay Extender Disk" - desc = "An upgrade allowing the defibrillator to work on more decayed bodies" + desc = "An upgrade allowing the defibrillator to work on more decayed bodies." id = "defib_decay" build_type = PROTOLATHE - materials = list(MAT_METAL=16000, MAT_GLASS = 18000, MAT_GOLD = 16000, MAT_SILVER = 6000, MAT_TITANIUM = 2000) + materials = list(MAT_METAL = 16000, MAT_GLASS = 18000, MAT_GOLD = 16000, MAT_SILVER = 6000, MAT_TITANIUM = 2000) build_path = /obj/item/disk/medical/defib_decay construction_time = 10 category = list("Misc") @@ -290,15 +291,23 @@ /datum/design/defib_speed name = "Defibrillator Fast Charge Disk" - desc = "An upgrade to the defibrillator capacitors, which let it charge faster" + desc = "An upgrade to the defibrillator's capacitors, which lets it charge faster." id = "defib_speed" build_type = PROTOLATHE build_path = /obj/item/disk/medical/defib_speed - materials = list(MAT_METAL=16000, MAT_GLASS = 8000, MAT_GOLD = 26000, MAT_SILVER = 26000) + materials = list(MAT_METAL = 16000, MAT_GLASS = 8000, MAT_GOLD = 26000, MAT_SILVER = 26000) construction_time = 10 category = list("Misc") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL +/datum/design/defibrillator_compact + name = "Compact Defibrillator" + desc = "A compact defibrillator that can be worn on a belt." + id = "defibrillator_compact" + build_type = PROTOLATHE + build_path = /obj/item/defibrillator/compact + materials = list(MAT_METAL = 16000, MAT_GLASS = 8000, MAT_SILVER = 6000, MAT_GOLD = 3000) + ///////////////////////////////////////// //////////Cybernetic Implants//////////// ///////////////////////////////////////// @@ -595,115 +604,6 @@ category = list("Medical Designs") departmental_flags = DEPARTMENTAL_FLAG_MEDICAL -///////////////////// -//Adv Surgery Tools// -///////////////////// - -/datum/design/drapes - name = "Plastic Drapes" - desc = "A large surgery drape made of plastic." - id = "drapes" - build_type = PROTOLATHE - materials = list(MAT_PLASTIC = 2500) - build_path = /obj/item/surgical_drapes - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/retractor_adv - name = "Advanced Retractor" - desc = "An almagation of rods and gears, able to function as both a surgical clamp and retractor. " - id = "retractor_adv" - build_type = PROTOLATHE - materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 1500, MAT_GOLD = 1000) - build_path = /obj/item/retractor/advanced - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/surgicaldrill_adv - name = "Surgical Laser Drill" - desc = "It projects a high power laser used for medical applications." - id = "surgicaldrill_adv" - build_type = PROTOLATHE - materials = list(MAT_METAL = 2500, MAT_GLASS = 2500, MAT_SILVER = 6000, MAT_GOLD = 5500, MAT_DIAMOND = 3500) - build_path = /obj/item/surgicaldrill/advanced - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE - -/datum/design/scalpel_adv - name = "Laser Scalpel" - desc = "An advanced scalpel which uses laser technology to cut." - id = "scalpel_adv" - build_type = PROTOLATHE - materials = list(MAT_METAL = 1500, MAT_GLASS = 1500, MAT_SILVER = 4000, MAT_GOLD = 2500) - build_path = /obj/item/scalpel/advanced - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE - - -///////////////////////////////////////// -//////////Alien Surgery Tools//////////// -///////////////////////////////////////// - -/datum/design/alienscalpel - name = "Alien Scalpel" - desc = "An advanced scalpel obtained through Abductor technology." - id = "alien_scalpel" - build_path = /obj/item/scalpel/alien - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/alienhemostat - name = "Alien Hemostat" - desc = "An advanced hemostat obtained through Abductor technology." - id = "alien_hemostat" - build_path = /obj/item/hemostat/alien - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/alienretractor - name = "Alien Retractor" - desc = "An advanced retractor obtained through Abductor technology." - id = "alien_retractor" - build_path = /obj/item/retractor/alien - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/aliensaw - name = "Alien Circular Saw" - desc = "An advanced surgical saw obtained through Abductor technology." - id = "alien_saw" - build_path = /obj/item/circular_saw/alien - build_type = PROTOLATHE - materials = list(MAT_METAL = 10000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 1500) - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/aliendrill - name = "Alien Drill" - desc = "An advanced drill obtained through Abductor technology." - id = "alien_drill" - build_path = /obj/item/surgicaldrill/alien - build_type = PROTOLATHE - materials = list(MAT_METAL = 10000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 1500) - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - -/datum/design/aliencautery - name = "Alien Cautery" - desc = "An advanced cautery obtained through Abductor technology." - id = "alien_cautery" - build_path = /obj/item/cautery/alien - build_type = PROTOLATHE - materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) - category = list("Medical Designs") - departmental_flags = DEPARTMENTAL_FLAG_MEDICAL - /datum/design/cybernetic_ears name = "Cybernetic Ears" desc = "A pair of cybernetic ears." diff --git a/code/modules/research/designs/misc_designs.dm b/code/modules/research/designs/misc_designs.dm index 5f7648b245..6cd343503d 100644 --- a/code/modules/research/designs/misc_designs.dm +++ b/code/modules/research/designs/misc_designs.dm @@ -257,7 +257,7 @@ departmental_flags = DEPARTMENTAL_FLAG_SERVICE /datum/design/roastingstick - name = "Advanced roasting stick" + name = "Advanced Roasting Stick" desc = "A roasting stick for cooking sausages in exotic ovens." id = "roastingstick" build_type = PROTOLATHE @@ -267,7 +267,7 @@ departmental_flags = DEPARTMENTAL_FLAG_SERVICE /datum/design/locator - name = "Bluespace locator" + name = "Bluespace Locator" desc = "Used to track portable teleportation beacons and targets with embedded tracking implants." id = "locator" build_type = PROTOLATHE @@ -276,6 +276,15 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_SECURITY +/datum/design/donksoft_refill + name = "Donksoft Toy Vendor Refill" + desc = "A refill canister for Donksoft Toy Vendors." + id = "donksoft_refill" + build_type = PROTOLATHE + materials = list(MAT_METAL = 25000, MAT_GLASS = 15000, MAT_PLASMA = 20000, MAT_GOLD = 10000, MAT_SILVER = 10000) + build_path = /obj/item/vending_refill/donksoft + category = list("Equipment") + ///////////////////////////////////////// ////////////Janitor Designs////////////// ///////////////////////////////////////// @@ -320,8 +329,28 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_SERVICE +/datum/design/spraybottle + name = "Spray Bottle" + desc = "A spray bottle, with an unscrewable top." + id = "spraybottle" + build_type = PROTOLATHE + materials = list(MAT_METAL = 3000, MAT_GLASS = 200) + build_path = /obj/item/reagent_containers/spray + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + +/datum/design/beartrap + name = "Bear Trap" + desc = "A trap used to catch space bears and other legged creatures." + id = "beartrap" + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_TITANIUM = 1000) + build_path = /obj/item/restraints/legcuffs/beartrap + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SERVICE + ///////////////////////////////////////// -////////////Holosign Designs////////////// +////////////Holosign Designs///////////// ///////////////////////////////////////// /datum/design/holosign @@ -374,111 +403,20 @@ category = list("Equipment") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING +/datum/design/holobarrier_med + name = "PENLITE holobarrier projector" + desc = "PENLITE holobarriers, a device that halts individuals with malicious diseases." + build_type = PROTOLATHE + build_path = /obj/item/holosign_creator/medical + materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 100) //a hint of silver since it can troll 2 antags (bad viros and sentient disease) + id = "holobarrier_med" + category = list("Medical Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL /////////////////////////////// ////////////Tools////////////// /////////////////////////////// -/datum/design/rcd_upgrade - name = "Advanced RCD designs upgrade" - desc = "Adds the computer frame and machine frame to the RCD." - id = "rcd_upgrade" - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_GLASS = 2500, MAT_SILVER = 1500, MAT_TITANIUM = 2000) - build_path = /obj/item/rcd_upgrade - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/exwelder - name = "Experimental Welding Tool" - desc = "An experimental welder capable of self-fuel generation." - id = "exwelder" - build_type = PROTOLATHE - materials = list(MAT_METAL = 1000, MAT_GLASS = 500, MAT_PLASMA = 1500, MAT_URANIUM = 200) - build_path = /obj/item/weldingtool/experimental - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/handdrill - name = "Hand Drill" - desc = "A small electric hand drill with an interchangeable screwdriver and bolt bit" - id = "handdrill" - build_type = PROTOLATHE - materials = list(MAT_METAL = 3500, MAT_SILVER = 1500, MAT_TITANIUM = 2500) - build_path = /obj/item/screwdriver/power - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/jawsoflife - name = "Jaws of Life" - desc = "A small, compact Jaws of Life with an interchangeable pry jaws and cutting jaws" - id = "jawsoflife" // added one more requirment since the Jaws of Life are a bit OP - build_path = /obj/item/crowbar/power - build_type = PROTOLATHE - materials = list(MAT_METAL = 4500, MAT_SILVER = 2500, MAT_TITANIUM = 3500) - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/alienwrench - name = "Alien Wrench" - desc = "An advanced wrench obtained through Abductor technology." - id = "alien_wrench" - build_path = /obj/item/wrench/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/alienwirecutters - name = "Alien Wirecutters" - desc = "Advanced wirecutters obtained through Abductor technology." - id = "alien_wirecutters" - build_path = /obj/item/wirecutters/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/alienscrewdriver - name = "Alien Screwdriver" - desc = "An advanced screwdriver obtained through Abductor technology." - id = "alien_screwdriver" - build_path = /obj/item/screwdriver/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/aliencrowbar - name = "Alien Crowbar" - desc = "An advanced crowbar obtained through Abductor technology." - id = "alien_crowbar" - build_path = /obj/item/crowbar/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/alienwelder - name = "Alien Welding Tool" - desc = "An advanced welding tool obtained through Abductor technology." - id = "alien_welder" - build_path = /obj/item/weldingtool/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 5000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - -/datum/design/alienmultitool - name = "Alien Multitool" - desc = "An advanced multitool obtained through Abductor technology." - id = "alien_multitool" - build_path = /obj/item/multitool/abductor - build_type = PROTOLATHE - materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 5000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) - category = list("Equipment") - departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING - /datum/design/quantum_keycard name = "Quantum Keycard" desc = "Allows for the construction of a quantum keycard." @@ -510,7 +448,7 @@ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE ///////////////////////////////////////// -////////////Armour/////////////////////// +/////////////////Armour////////////////// ///////////////////////////////////////// /datum/design/reactive_armour @@ -524,7 +462,71 @@ departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING ///////////////////////////////////////// -////////////Meteor/////////////////////// +/////////////Security//////////////////// +///////////////////////////////////////// + +/datum/design/seclite + name = "Seclite" + desc = "A robust flashlight used by security." + id = "seclite" + build_type = PROTOLATHE + materials = list(MAT_METAL = 2500) + build_path = /obj/item/flashlight/seclite + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/detective_scanner + name = "Forensic Scanner" + desc = "Used to remotely scan objects and biomass for DNA and fingerprints. Can print a report of the findings." + id = "detective_scanner" + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_GLASS = 1000, MAT_GOLD = 2500, MAT_SILVER = 2000) + build_path = /obj/item/detective_scanner + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/pepperspray + name = "Pepper Spray" + desc = "Manufactured by UhangInc, used to blind and down an opponent quickly. Printed pepper sprays do not contain reagents." + id = "pepperspray" + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_GLASS = 1000) + build_path = /obj/item/reagent_containers/spray/pepper/empty + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/bola_energy + name = "Energy Bola" + desc = "A specialized hard-light bola designed to ensnare fleeing criminals and aid in arrests." + id = "bola_energy" + build_type = PROTOLATHE + materials = list(MAT_SILVER = 500, MAT_PLASMA = 500, MAT_TITANIUM = 500) + build_path = /obj/item/restraints/legcuffs/bola/energy + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/zipties + name = "Zipties" + desc = "Plastic, disposable zipties that can be used to restrain temporarily but are destroyed after use." + id = "zipties" + build_type = PROTOLATHE + materials = list(MAT_PLASTIC = 250) + build_path = /obj/item/restraints/handcuffs/cable/zipties + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +/datum/design/evidencebag + name = "Evidence Bag" + desc = "An empty evidence bag." + id = "evidencebag" + build_type = PROTOLATHE + materials = list(MAT_PLASTIC = 100) + build_path = /obj/item/evidencebag + category = list("Equipment") + departmental_flags = DEPARTMENTAL_FLAG_SECURITY + +///////////////////////////////////////// +/////////////////Meteors///////////////// ///////////////////////////////////////// /datum/design/meteor_defence diff --git a/code/modules/research/designs/smelting_designs.dm b/code/modules/research/designs/smelting_designs.dm index c2cbb5685e..64dcb5f754 100644 --- a/code/modules/research/designs/smelting_designs.dm +++ b/code/modules/research/designs/smelting_designs.dm @@ -68,4 +68,4 @@ materials = list(MAT_METAL = 4000, MAT_PLASMA = 4000) build_path = /obj/item/stack/sheet/mineral/abductor category = list("Stock Parts") - departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SCIENCE + departmental_flags = DEPARTMENTAL_FLAG_CARGO | DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING diff --git a/code/modules/research/designs/tool_designs.dm b/code/modules/research/designs/tool_designs.dm new file mode 100644 index 0000000000..2e40f06537 --- /dev/null +++ b/code/modules/research/designs/tool_designs.dm @@ -0,0 +1,216 @@ +///////////////////////////////////////// +/////////////////Tools/////////////////// +///////////////////////////////////////// + +/datum/design/rcd_upgrade + name = "Advanced RCD designs upgrade" + desc = "Adds the computer frame and machine frame designs to the RCD." + id = "rcd_upgrade" + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_GLASS = 2500, MAT_SILVER = 1500, MAT_TITANIUM = 2000) + build_path = /obj/item/rcd_upgrade + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/handdrill + name = "Hand Drill" + desc = "A small electric hand drill with an interchangeable screwdriver and bolt bit" + id = "handdrill" + build_type = PROTOLATHE + materials = list(MAT_METAL = 3500, MAT_SILVER = 1500, MAT_TITANIUM = 2500) + build_path = /obj/item/screwdriver/power + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/jawsoflife + name = "Jaws of Life" + desc = "A small, compact Jaws of Life with an interchangeable pry jaws and cutting jaws" + id = "jawsoflife" // added one more requirment since the Jaws of Life are a bit OP + build_path = /obj/item/crowbar/power + build_type = PROTOLATHE + materials = list(MAT_METAL = 4500, MAT_SILVER = 2500, MAT_TITANIUM = 3500) + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/exwelder + name = "Experimental Welding Tool" + desc = "An experimental welder capable of self-fuel generation." + id = "exwelder" + build_type = PROTOLATHE + materials = list(MAT_METAL = 1000, MAT_GLASS = 500, MAT_PLASMA = 1500, MAT_URANIUM = 200) + build_path = /obj/item/weldingtool/experimental + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_SCIENCE | DEPARTMENTAL_FLAG_ENGINEERING + +///////////////////////////////////////// +//////////////Alien Tools//////////////// +///////////////////////////////////////// + +/datum/design/alienwrench + name = "Alien Wrench" + desc = "An advanced wrench obtained through Abductor technology." + id = "alien_wrench" + build_path = /obj/item/wrench/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienwirecutters + name = "Alien Wirecutters" + desc = "Advanced wirecutters obtained through Abductor technology." + id = "alien_wirecutters" + build_path = /obj/item/wirecutters/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienscrewdriver + name = "Alien Screwdriver" + desc = "An advanced screwdriver obtained through Abductor technology." + id = "alien_screwdriver" + build_path = /obj/item/screwdriver/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/aliencrowbar + name = "Alien Crowbar" + desc = "An advanced crowbar obtained through Abductor technology." + id = "alien_crowbar" + build_path = /obj/item/crowbar/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienwelder + name = "Alien Welding Tool" + desc = "An advanced welding tool obtained through Abductor technology." + id = "alien_welder" + build_path = /obj/item/weldingtool/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 5000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/alienmultitool + name = "Alien Multitool" + desc = "An advanced multitool obtained through Abductor technology." + id = "alien_multitool" + build_path = /obj/item/multitool/abductor + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_SILVER = 2500, MAT_PLASMA = 5000, MAT_TITANIUM = 2000, MAT_DIAMOND = 2000) + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +///////////////////////////////////////// +/////////Alien Surgical Tools//////////// +///////////////////////////////////////// + +/datum/design/alienscalpel + name = "Alien Scalpel" + desc = "An advanced scalpel obtained through Abductor technology." + id = "alien_scalpel" + build_path = /obj/item/scalpel/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/alienhemostat + name = "Alien Hemostat" + desc = "An advanced hemostat obtained through Abductor technology." + id = "alien_hemostat" + build_path = /obj/item/hemostat/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/alienretractor + name = "Alien Retractor" + desc = "An advanced retractor obtained through Abductor technology." + id = "alien_retractor" + build_path = /obj/item/retractor/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/aliensaw + name = "Alien Circular Saw" + desc = "An advanced surgical saw obtained through Abductor technology." + id = "alien_saw" + build_path = /obj/item/circular_saw/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 10000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 1500) + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/aliendrill + name = "Alien Drill" + desc = "An advanced drill obtained through Abductor technology." + id = "alien_drill" + build_path = /obj/item/surgicaldrill/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 10000, MAT_SILVER = 2500, MAT_PLASMA = 1000, MAT_TITANIUM = 1500) + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + +/datum/design/aliencautery + name = "Alien Cautery" + desc = "An advanced cautery obtained through Abductor technology." + id = "alien_cautery" + build_path = /obj/item/cautery/alien + build_type = PROTOLATHE + materials = list(MAT_METAL = 2000, MAT_SILVER = 1500, MAT_PLASMA = 500, MAT_TITANIUM = 1500) + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL + + +////////////////////// +//Adv. Surgery Tools// +////////////////////// + +/datum/design/drapes + name = "Plastic Drapes" + desc = "A large surgery drape made of plastic." + id = "drapes" + build_type = PROTOLATHE + materials = list(MAT_PLASTIC = 2500) + build_path = /obj/item/surgical_drapes + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/retractor_adv + name = "Advanced Retractor" + desc = "An almagation of rods and gears, able to function as both a surgical clamp and retractor. " + id = "retractor_adv" + build_type = PROTOLATHE + materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 1500, MAT_GOLD = 1000) + build_path = /obj/item/retractor/advanced + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/surgicaldrill_adv + name = "Surgical Laser Drill" + desc = "It projects a high power laser used for medical applications." + id = "surgicaldrill_adv" + build_type = PROTOLATHE + materials = list(MAT_METAL = 2500, MAT_GLASS = 2500, MAT_SILVER = 6000, MAT_GOLD = 5500, MAT_DIAMOND = 3500) + build_path = /obj/item/surgicaldrill/advanced + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + +/datum/design/scalpel_adv + name = "Laser Scalpel" + desc = "An advanced scalpel which uses laser technology to cut." + id = "scalpel_adv" + build_type = PROTOLATHE + materials = list(MAT_METAL = 1500, MAT_GLASS = 1500, MAT_SILVER = 4000, MAT_GOLD = 2500) + build_path = /obj/item/scalpel/advanced + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE diff --git a/code/modules/research/machinery/protolathe.dm b/code/modules/research/machinery/protolathe.dm index 6acfc9ec42..e04261c961 100644 --- a/code/modules/research/machinery/protolathe.dm +++ b/code/modules/research/machinery/protolathe.dm @@ -9,6 +9,7 @@ "Bluespace Designs", "Stock Parts", "Equipment", + "Tool Designs", "Mining Designs", "Electronics", "Weapons", @@ -21,4 +22,4 @@ /obj/machinery/rnd/production/protolathe/disconnect_console() linked_console.linked_lathe = null - ..() \ No newline at end of file + ..() diff --git a/code/modules/research/machinery/techfab.dm b/code/modules/research/machinery/techfab.dm index 332a1ccf88..5525066f2a 100644 --- a/code/modules/research/machinery/techfab.dm +++ b/code/modules/research/machinery/techfab.dm @@ -9,6 +9,7 @@ "Bluespace Designs", "Stock Parts", "Equipment", + "Tool Designs", "Mining Designs", "Electronics", "Weapons", @@ -31,4 +32,4 @@ production_animation = "protolathe_n" requires_console = FALSE consoleless_interface = TRUE - allowed_buildtypes = PROTOLATHE | IMPRINTER \ No newline at end of file + allowed_buildtypes = PROTOLATHE | IMPRINTER diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index a44495fccb..41f42c9599 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -8,9 +8,9 @@ display_name = "Basic Research Technology" description = "NT default research technologies." // Default research tech, prevents bricking - design_ids = list("basic_matter_bin", "basic_cell", "basic_scanning", "basic_capacitor", "basic_micro_laser", "micro_mani", + design_ids = list("basic_matter_bin", "basic_cell", "basic_scanning", "basic_capacitor", "basic_micro_laser", "micro_mani", "desttagger", "handlabel", "packagewrap", "destructive_analyzer", "circuit_imprinter", "experimentor", "rdconsole", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab", - "space_heater", "xlarge_beaker", "sec_beanbag", "sec_rshot", "sec_bshot", "sec_slug", "sec_Islug", "sec_dart", "sec_38", "sec_38lethal", + "space_heater", "beaker", "large_beaker", "bucket", "xlarge_beaker", "sec_beanbag", "sec_rshot", "sec_bshot", "sec_slug", "sec_Islug", "sec_dart", "sec_38", "sec_38lethal", "rglass","plasteel","plastitanium","plasmaglass","plasmareinforcedglass","titaniumglass","plastitaniumglass") /datum/techweb_node/mmi @@ -71,7 +71,7 @@ display_name = "Biological Technology" description = "What makes us tick." //the MC, silly! prereq_ids = list("base") - design_ids = list("medicalkit", "chem_heater", "chem_master", "chem_dispenser", "sleeper", "vr_sleeper", "pandemic", "defibmount", "operating", "soda_dispenser", "beer_dispenser", "healthanalyzer", "blood_bag", "bloodbankgen", "telescopiciv") + design_ids = list("medicalkit", "chem_heater", "chem_master", "chem_dispenser", "sleeper", "vr_sleeper", "pandemic", "defibrillator", "defibmount", "operating", "soda_dispenser", "beer_dispenser", "healthanalyzer", "blood_bag", "bloodbankgen", "telescopiciv", "medspray") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 @@ -80,7 +80,7 @@ display_name = "Advanced Biotechnology" description = "Advanced Biotechnology" prereq_ids = list("biotech") - design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "defibrillator", "meta_beaker", "healthanalyzer_advanced","harvester","holobarrier_med","smartdartgun","medicinalsmartdart", "pHmeter") + design_ids = list("piercesyringe", "crewpinpointer", "smoke_machine", "plasmarefiller", "limbgrower", "meta_beaker", "healthanalyzer_advanced", "harvester", "holobarrier_med", "detective_scanner", "defibrillator_compact", "smartdartgun", "medicinalsmartdart", "pHmeter") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) export_price = 5000 @@ -595,6 +595,15 @@ export_price = 5000 ////////////////////////Tools//////////////////////// +/datum/techweb_node/basic_tools + id = "basic_tools" + display_name = "Basic Tools" + description = "Basic mechanical, electronic, surgical and botanical tools." + prereq_ids = list("base") + design_ids = list("screwdriver", "wrench", "wirecutters", "crowbar", "multitool", "welding_tool", "tscanner", "analyzer", "cable_coil", "pipe_painter", "airlock_painter", "scalpel", "circular_saw", "surgicaldrill", "retractor", "cautery", "hemostat", "cultivator", "plant_analyzer", "shovel", "spade", "hatchet") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500) + export_price = 5000 + /datum/techweb_node/basic_mining id = "basic_mining" display_name = "Mining Technology" @@ -618,7 +627,7 @@ display_name = "Advanced Sanitation Technology" description = "Clean things better, faster, stronger, and harder!" prereq_ids = list("adv_engi") - design_ids = list("advmop", "buffer", "light_replacer") + design_ids = list("advmop", "buffer", "light_replacer", "spraybottle", "beartrap") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1750) // No longer has its bag export_price = 5000 @@ -640,6 +649,15 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2750) export_price = 5000 +/datum/techweb_node/sec_basic + id = "sec_basic" + display_name = "Basic Security Equipment" + description = "Standard equipment used by security." + design_ids = list("seclite", "pepperspray", "bola_energy", "zipties", "evidencebag") + prereq_ids = list("base") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000) + export_price = 5000 + /////////////////////////weaponry tech///////////////////////// /datum/techweb_node/weaponry id = "weaponry" @@ -1081,7 +1099,7 @@ display_name = "Illegal Technology" description = "Dangerous research used to create dangerous objects." prereq_ids = list("adv_engi", "adv_weaponry", "explosive_weapons") - design_ids = list("decloner", "borg_syndicate_module", "suppressor", "largecrossbow", "donksofttoyvendor") + design_ids = list("decloner", "borg_syndicate_module", "ai_cam_upgrade", "suppressor", "largecrossbow", "donksofttoyvendor", "donksoft_refill") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000) export_price = 5000 hidden = TRUE diff --git a/tgstation.dme b/tgstation.dme index f52892fce3..26b10e5af0 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -2746,6 +2746,7 @@ #include "code\modules\research\designs\smelting_designs.dm" #include "code\modules\research\designs\stock_parts_designs.dm" #include "code\modules\research\designs\telecomms_designs.dm" +#include "code\modules\research\designs\tool_designs.dm" #include "code\modules\research\designs\weapon_designs.dm" #include "code\modules\research\designs\autolathe_desings\autolathe_designs_construction.dm" #include "code\modules\research\designs\autolathe_desings\autolathe_designs_electronics.dm" From 102e973737555be232d890b53af6faba3c54efab Mon Sep 17 00:00:00 2001 From: Hatterhat Date: Thu, 9 Jan 2020 18:39:31 -0600 Subject: [PATCH 058/203] considering these are basic nodes --- code/modules/research/techweb/all_nodes.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 41f42c9599..63619fe262 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -601,7 +601,7 @@ description = "Basic mechanical, electronic, surgical and botanical tools." prereq_ids = list("base") design_ids = list("screwdriver", "wrench", "wirecutters", "crowbar", "multitool", "welding_tool", "tscanner", "analyzer", "cable_coil", "pipe_painter", "airlock_painter", "scalpel", "circular_saw", "surgicaldrill", "retractor", "cautery", "hemostat", "cultivator", "plant_analyzer", "shovel", "spade", "hatchet") - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 500) export_price = 5000 /datum/techweb_node/basic_mining @@ -655,7 +655,7 @@ description = "Standard equipment used by security." design_ids = list("seclite", "pepperspray", "bola_energy", "zipties", "evidencebag") prereq_ids = list("base") - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 750) export_price = 5000 /////////////////////////weaponry tech///////////////////////// From 530d710f57a729410403a2097308a5e41bc6d579 Mon Sep 17 00:00:00 2001 From: Trilbyspaceclone <30435998+Trilbyspaceclone@users.noreply.github.com> Date: Thu, 9 Jan 2020 20:42:07 -0500 Subject: [PATCH 059/203] Update mineral.dm --- code/game/objects/items/stacks/sheets/mineral.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index caf43eff1f..53b78b2ecf 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -372,7 +372,7 @@ GLOBAL_LIST_INIT(adamantine_recipes, list( singular_name = "snow block" force = 1 throwforce = 2 - grind_results = list("ice" = 20) + grind_results = list(/datum/reagent/consumable/ice = 20) merge_type = /obj/item/stack/sheet/mineral/snow GLOBAL_LIST_INIT(snow_recipes, list ( \ @@ -441,4 +441,4 @@ GLOBAL_LIST_INIT(abductor_recipes, list ( \ amount = 5 /obj/item/stack/sheet/mineral/coal/ten - amount = 10 \ No newline at end of file + amount = 10 From 3c877c96f51301cd8317f7ccaf98c3aba157a736 Mon Sep 17 00:00:00 2001 From: Trilbyspaceclone <30435998+Trilbyspaceclone@users.noreply.github.com> Date: Thu, 9 Jan 2020 20:42:56 -0500 Subject: [PATCH 060/203] Update sheet_types.dm --- code/game/objects/items/stacks/sheets/sheet_types.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index e3b2861b2d..a80f0d5a3b 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -717,7 +717,7 @@ GLOBAL_LIST_INIT(plastic_recipes, list( item_state = "sheet-plastic" materials = list(MAT_PLASTIC=MINERAL_MATERIAL_AMOUNT) throwforce = 7 - grind_results = list("white_glitter" = 60) + grind_results = list(/datum/reagent/glitter/white = 60) merge_type = /obj/item/stack/sheet/plastic /obj/item/stack/sheet/plastic/fifty From d463ba8eddf52fd2dc78c3b6dc837a606c229994 Mon Sep 17 00:00:00 2001 From: Trilbyspaceclone <30435998+Trilbyspaceclone@users.noreply.github.com> Date: Thu, 9 Jan 2020 20:43:31 -0500 Subject: [PATCH 061/203] Update others.dm --- code/modules/reagents/chemistry/recipes/others.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index c3e09d6bb9..d4c71ebb44 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -734,7 +734,7 @@ name = "pink glitter from white" id = "pink_glitter_white" results = list(/datum/reagent/glitter/pink = 2) - required_reagents = list("white_glitter" = 1, /datum/reagent/colorful_reagent/crayonpowder/red = 1) + required_reagents = list(/datum/reagent/glitter/white = 1, /datum/reagent/colorful_reagent/crayonpowder/red = 1) /datum/chemical_reaction/blue_glitter/pink name = "blue glitter from pink" From e1f524fc03f5728493e1bef0ab36496765bd5c4c Mon Sep 17 00:00:00 2001 From: rosko <57355448+rossark@users.noreply.github.com> Date: Fri, 10 Jan 2020 03:53:27 +0200 Subject: [PATCH 062/203] ports fast augmentation pr from /tg/ https://github.com/tgstation/tgstation/pull/47721 --- code/modules/surgery/limb_augmentation.dm | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/code/modules/surgery/limb_augmentation.dm b/code/modules/surgery/limb_augmentation.dm index b1d8990b48..684996a0f5 100644 --- a/code/modules/surgery/limb_augmentation.dm +++ b/code/modules/surgery/limb_augmentation.dm @@ -1,15 +1,5 @@ /////AUGMENTATION SURGERIES////// //SURGERY STEPS -/datum/surgery_step/replace - name = "sever muscles" - implements = list(TOOL_SCALPEL = 100, TOOL_WIRECUTTER = 55) - time = 32 - - -/datum/surgery_step/replace/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - display_results(user, target, "You begin to sever the muscles on [target]'s [parse_zone(user.zone_selected)]...", - "[user] begins to sever the muscles on [target]'s [parse_zone(user.zone_selected)].", - "[user] begins an incision on [target]'s [parse_zone(user.zone_selected)].") /datum/surgery_step/replace_limb name = "replace limb" @@ -37,7 +27,7 @@ //ACTUAL SURGERIES /datum/surgery/augmentation name = "Augmentation" - steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/replace, /datum/surgery_step/saw, /datum/surgery_step/replace_limb) + steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/replace_limb) target_mobtypes = list(/mob/living/carbon/human) possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD) requires_real_bodypart = TRUE From 8d70181ecf4dd63bb3727defbf394514333fb225 Mon Sep 17 00:00:00 2001 From: Linzolle Date: Thu, 9 Jan 2020 22:41:50 -0600 Subject: [PATCH 063/203] uh oh stinky --- code/modules/admin/admin_verbs.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index c3ffd10174..c1aa50ff3a 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -437,6 +437,8 @@ GLOBAL_PROTECT(admin_verbs_hideable) /client/proc/stealth() set category = "Admin" set name = "Stealth Mode" + if(!check_rights(R_STEALTH, 0)) + return if(holder) if(holder.fakekey) holder.fakekey = null From dc0fdebc2164318cd1706289e9e850025a5ccdd1 Mon Sep 17 00:00:00 2001 From: Linzolle Date: Thu, 9 Jan 2020 22:46:43 -0600 Subject: [PATCH 064/203] hrmngh colonel --- code/modules/admin/admin_verbs.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index c1aa50ff3a..8a7269ccad 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -437,9 +437,9 @@ GLOBAL_PROTECT(admin_verbs_hideable) /client/proc/stealth() set category = "Admin" set name = "Stealth Mode" - if(!check_rights(R_STEALTH, 0)) - return if(holder) + if(!check_rights(R_STEALTH, 0)) + return if(holder.fakekey) holder.fakekey = null if(isobserver(mob)) From 6ec3fde836b10d9985158ed28f6bdf76899a2027 Mon Sep 17 00:00:00 2001 From: Letter N <24603524+LetterN@users.noreply.github.com> Date: Fri, 10 Jan 2020 18:06:55 +0800 Subject: [PATCH 065/203] better-signalers --- code/controllers/subsystem/pai.dm | 2 +- .../items/devices/radio/electropack.dm | 108 +++++++++--------- .../items/devices/radio/shockcollar.dm | 62 +++++----- 3 files changed, 84 insertions(+), 88 deletions(-) diff --git a/code/controllers/subsystem/pai.dm b/code/controllers/subsystem/pai.dm index 18667053d4..5aa109b63a 100644 --- a/code/controllers/subsystem/pai.dm +++ b/code/controllers/subsystem/pai.dm @@ -8,7 +8,7 @@ SUBSYSTEM_DEF(pai) var/spam_delay = 100 var/list/pai_card_list = list() -/datum/controller/subsystem/pai/Topic(href, href_list[]) +/datum/controller/subsystem/pai/Topic(href, href_list) if(href_list["download"]) var/datum/paiCandidate/candidate = locate(href_list["candidate"]) in candidates var/obj/item/paicard/card = locate(href_list["device"]) in pai_card_list diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index b74b0fa3d4..f468121048 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -10,22 +10,23 @@ slot_flags = ITEM_SLOT_BACK w_class = WEIGHT_CLASS_HUGE materials = list(MAT_METAL=10000, MAT_GLASS=2500) - var/on = TRUE + var/code = 2 var/frequency = FREQ_ELECTROPACK - var/shock_cooldown = 0 + var/on = TRUE + var/shock_cooldown = FALSE -/obj/item/electropack/suicide_act(mob/user) +/obj/item/electropack/suicide_act(mob/living/carbon/user) user.visible_message("[user] hooks [user.p_them()]self to the electropack and spams the trigger! It looks like [user.p_theyre()] trying to commit suicide!") return (FIRELOSS) /obj/item/electropack/Initialize() . = ..() - SSradio.add_object(src, frequency, RADIO_SIGNALER) + set_frequency(frequency) /obj/item/electropack/Destroy() SSradio.remove_object(src, frequency) - return ..() + . = ..() //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/electropack/attack_hand(mob/user) @@ -36,7 +37,7 @@ return return ..() -/obj/item/electropack/attackby(obj/item/W, mob/user, params) +/obj/item/electropack/attackby(obj/item/W, mob/living/user, params) if(istype(W, /obj/item/clothing/head/helmet)) var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit(user) A.icon = 'icons/obj/assemblies.dmi' @@ -57,43 +58,47 @@ return ..() /obj/item/electropack/Topic(href, href_list) - //..() var/mob/living/carbon/C = usr if(usr.stat || usr.restrained() || C.back == src) return - if((ishuman(usr) && usr.contents.Find(src)) || usr.contents.Find(master) || (in_range(src, usr) && isturf(loc))) - usr.set_machine(src) - if(href_list["freq"]) - SSradio.remove_object(src, frequency) - frequency = sanitize_frequency(frequency + text2num(href_list["freq"])) - SSradio.add_object(src, frequency, RADIO_SIGNALER) - else - if(href_list["code"]) - code += text2num(href_list["code"]) - code = round(code) - code = min(100, code) - code = max(1, code) - else - if(href_list["power"]) - on = !( on ) - icon_state = "electropack[on]" - if(!( master )) - if(ismob(loc)) - attack_self(loc) - else - for(var/mob/M in viewers(1, src)) - if(M.client) - attack_self(M) - else - if(ismob(master.loc)) - attack_self(master.loc) - else - for(var/mob/M in viewers(1, master)) - if(M.client) - attack_self(M) - else + + if(!usr.canUseTopic(src, BE_CLOSE)) usr << browse(null, "window=radio") + onclose(usr, "radio") return + + if(href_list["set"]) + if(href_list["set"] == "freq") + var/new_freq = input(usr, "Input a new receiving frequency", "Electropack Frequency", format_frequency(frequency)) as num|null + if(!usr.canUseTopic(src, BE_CLOSE)) + return + new_freq = unformat_frequency(new_freq) + new_freq = sanitize_frequency(new_freq, TRUE) + set_frequency(new_freq) + + if(href_list["set"] == "code") + var/new_code = input(usr, "Input a new receiving code", "Electropack Code", code) as num|null + if(!usr.canUseTopic(src, BE_CLOSE)) + return + new_code = round(new_code) + new_code = CLAMP(new_code, 1, 100) + code = new_code + + if(href_list["set"] == "power") + if(!usr.canUseTopic(src, BE_CLOSE)) + return + on = !(on) + icon_state = "electropack[on]" + + if(usr) + attack_self(usr) + + return + +/obj/item/electropack/proc/set_frequency(new_frequency) + SSradio.remove_object(src, frequency) + frequency = new_frequency + SSradio.add_object(src, frequency, RADIO_SIGNALER) return /obj/item/electropack/receive_signal(datum/signal/signal) @@ -101,10 +106,10 @@ return if(isliving(loc) && on) - if(shock_cooldown != 0) + if(shock_cooldown == TRUE) return - shock_cooldown = 1 - addtimer(VARSET_CALLBACK(src, shock_cooldown, 0), 100) + shock_cooldown = TRUE + addtimer(VARSET_CALLBACK(src, shock_cooldown, FALSE), 100) var/mob/living/L = loc step(L, pick(GLOB.cardinals)) @@ -119,25 +124,22 @@ master.receive_signal() return -/obj/item/electropack/attack_self(mob/user) - +/obj/item/electropack/ui_interact(mob/user) if(!ishuman(user)) return + user.set_machine(src) - var/dat = {"Turned [on ? "On" : "Off"] - -Toggle
+ var/dat = {" + +Turned [on ? "On" : "Off"] - Toggle
Frequency/Code for electropack:
Frequency: -- -- [format_frequency(frequency)] -+ -+
+[format_frequency(src.frequency)] +Set
Code: -- -- [code] -+ -+
+[src.code] +Set
"} user << browse(dat, "window=radio") onclose(user, "radio") diff --git a/modular_citadel/code/game/objects/items/devices/radio/shockcollar.dm b/modular_citadel/code/game/objects/items/devices/radio/shockcollar.dm index 9d0757e26e..94bf1ba30a 100644 --- a/modular_citadel/code/game/objects/items/devices/radio/shockcollar.dm +++ b/modular_citadel/code/game/objects/items/devices/radio/shockcollar.dm @@ -11,6 +11,7 @@ strip_delay = 60 equip_delay_other = 60 materials = list(MAT_METAL=5000, MAT_GLASS=2000) + var/tagname = null /datum/design/electropack/shockcollar @@ -25,18 +26,17 @@ if(loc == user && user.get_item_by_slot(SLOT_NECK)) to_chat(user, "The collar is fastened tight! You'll need help taking this off!") return - ..() + return ..() /obj/item/electropack/shockcollar/receive_signal(datum/signal/signal) if(!signal || signal.data["code"] != code) return if(isliving(loc) && on) - if(shock_cooldown != 0) + if(shock_cooldown == TRUE) return - shock_cooldown = 1 - spawn(100) - shock_cooldown = 0 + shock_cooldown = TRUE + addtimer(VARSET_CALLBACK(src, shock_cooldown, FALSE), 100) var/mob/living/L = loc step(L, pick(GLOB.cardinals)) @@ -51,33 +51,27 @@ master.receive_signal() return -/obj/item/electropack/shockcollar/attack_self(mob/user) //Turns out can't fully source this from the parent item, spritepath gets confused if power toggled. Will come back to this when I know how to code better and readd powertoggle.. - var/option = "Change Name" - option = input(user, "What do you want to do?", "[src]", option) as null|anything in list("Change Name", "Change Frequency") - switch(option) - if("Change Name") - var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text - if(t) - tagname = copytext(sanitize(t), 1, MAX_NAME_LEN) - name = "[initial(name)] - [tagname]" - if("Change Frequency") - if(!ishuman(user)) - return - user.set_machine(src) - var/dat = {"
- Frequency/Code for shock collar:
- Frequency: - - - - [format_frequency(frequency)] - + - +
- Code: - - - - [code] - + - +
-
"} +/obj/item/electropack/shockcollar/attackby(obj/item/W, mob/user, params) //moves it here because on_click is being bad + if(istype(W, /obj/item/pen)) + var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text + if(t) + tagname = copytext(sanitize(t), 1, MAX_NAME_LEN) + name = "[initial(name)] - [tagname]" + else + return ..() - user << browse(dat, "window=radio") - onclose(user, "radio") - return +/obj/item/electropack/shockcollar/ui_interact(mob/user) //on_click calls this + var/dat = {" + +Frequency/Code for shock collar:
+Frequency: +[format_frequency(src.frequency)] +Set
+ +Code: +[src.code] +Set
+
"} + user << browse(dat, "window=radio") + onclose(user, "radio") + return From 315756d95a662fe2ac2300896dedc17cbaca405e Mon Sep 17 00:00:00 2001 From: Letter N <24603524+LetterN@users.noreply.github.com> Date: Fri, 10 Jan 2020 19:39:57 +0800 Subject: [PATCH 066/203] banjo --- .../game/objects/items/devices/instruments.dm | 12 +++++++++++- sound/instruments/banjo/Ab3.ogg | Bin 0 -> 20372 bytes sound/instruments/banjo/Ab4.ogg | Bin 0 -> 20396 bytes sound/instruments/banjo/Ab5.ogg | Bin 0 -> 20411 bytes sound/instruments/banjo/An3.ogg | Bin 0 -> 24289 bytes sound/instruments/banjo/An4.ogg | Bin 0 -> 22221 bytes sound/instruments/banjo/An5.ogg | Bin 0 -> 12373 bytes sound/instruments/banjo/Bb3.ogg | Bin 0 -> 20968 bytes sound/instruments/banjo/Bb4.ogg | Bin 0 -> 20460 bytes sound/instruments/banjo/Bb5.ogg | Bin 0 -> 12614 bytes sound/instruments/banjo/Bn2.ogg | Bin 0 -> 24458 bytes sound/instruments/banjo/Bn3.ogg | Bin 0 -> 24228 bytes sound/instruments/banjo/Bn4.ogg | Bin 0 -> 19891 bytes sound/instruments/banjo/Bn5.ogg | Bin 0 -> 12633 bytes sound/instruments/banjo/Cn3.ogg | Bin 0 -> 24724 bytes sound/instruments/banjo/Cn4.ogg | Bin 0 -> 20696 bytes sound/instruments/banjo/Cn5.ogg | Bin 0 -> 21014 bytes sound/instruments/banjo/Cn6.ogg | Bin 0 -> 12670 bytes sound/instruments/banjo/Db3.ogg | Bin 0 -> 21442 bytes sound/instruments/banjo/Db4.ogg | Bin 0 -> 20334 bytes sound/instruments/banjo/Db5.ogg | Bin 0 -> 22485 bytes sound/instruments/banjo/Db6.ogg | Bin 0 -> 11750 bytes sound/instruments/banjo/Dn3.ogg | Bin 0 -> 21168 bytes sound/instruments/banjo/Dn4.ogg | Bin 0 -> 21865 bytes sound/instruments/banjo/Dn5.ogg | Bin 0 -> 20948 bytes sound/instruments/banjo/Dn6.ogg | Bin 0 -> 10611 bytes sound/instruments/banjo/Eb3.ogg | Bin 0 -> 21159 bytes sound/instruments/banjo/Eb4.ogg | Bin 0 -> 23906 bytes sound/instruments/banjo/Eb5.ogg | Bin 0 -> 18517 bytes sound/instruments/banjo/En3.ogg | Bin 0 -> 21121 bytes sound/instruments/banjo/En4.ogg | Bin 0 -> 25966 bytes sound/instruments/banjo/En5.ogg | Bin 0 -> 16852 bytes sound/instruments/banjo/Fn3.ogg | Bin 0 -> 21327 bytes sound/instruments/banjo/Fn4.ogg | Bin 0 -> 20228 bytes sound/instruments/banjo/Fn5.ogg | Bin 0 -> 12854 bytes sound/instruments/banjo/Gb3.ogg | Bin 0 -> 22079 bytes sound/instruments/banjo/Gb4.ogg | Bin 0 -> 24998 bytes sound/instruments/banjo/Gb5.ogg | Bin 0 -> 16774 bytes sound/instruments/banjo/Gn3.ogg | Bin 0 -> 24891 bytes sound/instruments/banjo/Gn4.ogg | Bin 0 -> 25131 bytes sound/instruments/banjo/Gn5.ogg | Bin 0 -> 12438 bytes sound/instruments/bikehorn/Ab2.ogg | Bin 10582 -> 6193 bytes sound/instruments/bikehorn/Ab3.ogg | Bin 10824 -> 6788 bytes sound/instruments/bikehorn/Ab4.ogg | Bin 10471 -> 6592 bytes sound/instruments/bikehorn/An2.ogg | Bin 10589 -> 6387 bytes sound/instruments/bikehorn/An3.ogg | Bin 10823 -> 6859 bytes sound/instruments/bikehorn/An4.ogg | Bin 10760 -> 6660 bytes sound/instruments/bikehorn/Bb2.ogg | Bin 10465 -> 6255 bytes sound/instruments/bikehorn/Bb3.ogg | Bin 10823 -> 6922 bytes sound/instruments/bikehorn/Bb4.ogg | Bin 10759 -> 6750 bytes sound/instruments/bikehorn/Bn2.ogg | Bin 10702 -> 6356 bytes sound/instruments/bikehorn/Bn3.ogg | Bin 10765 -> 7125 bytes sound/instruments/bikehorn/Bn4.ogg | Bin 10640 -> 6377 bytes sound/instruments/bikehorn/Cn3.ogg | Bin 10887 -> 6897 bytes sound/instruments/bikehorn/Cn4.ogg | Bin 10817 -> 6962 bytes sound/instruments/bikehorn/Cn5.ogg | Bin 10641 -> 6327 bytes sound/instruments/bikehorn/Db3.ogg | Bin 10484 -> 6921 bytes sound/instruments/bikehorn/Db4.ogg | Bin 10759 -> 6935 bytes sound/instruments/bikehorn/Db5.ogg | Bin 10581 -> 5978 bytes sound/instruments/bikehorn/Dn3.ogg | Bin 10786 -> 6894 bytes sound/instruments/bikehorn/Dn4.ogg | Bin 10877 -> 6610 bytes sound/instruments/bikehorn/Dn5.ogg | Bin 10875 -> 6015 bytes sound/instruments/bikehorn/Eb3.ogg | Bin 10480 -> 6590 bytes sound/instruments/bikehorn/Eb4.ogg | Bin 10759 -> 6748 bytes sound/instruments/bikehorn/Eb5.ogg | Bin 10582 -> 5679 bytes sound/instruments/bikehorn/En2.ogg | Bin 10695 -> 6225 bytes sound/instruments/bikehorn/En3.ogg | Bin 10529 -> 6545 bytes sound/instruments/bikehorn/En4.ogg | Bin 10816 -> 7256 bytes sound/instruments/bikehorn/Fn2.ogg | Bin 10696 -> 6101 bytes sound/instruments/bikehorn/Fn3.ogg | Bin 10529 -> 6657 bytes sound/instruments/bikehorn/Fn4.ogg | Bin 10816 -> 7377 bytes sound/instruments/bikehorn/Gb2.ogg | Bin 10641 -> 6199 bytes sound/instruments/bikehorn/Gb3.ogg | Bin 10593 -> 6799 bytes sound/instruments/bikehorn/Gb4.ogg | Bin 10816 -> 7435 bytes sound/instruments/bikehorn/Gn2.ogg | Bin 10875 -> 6154 bytes sound/instruments/bikehorn/Gn3.ogg | Bin 10764 -> 6929 bytes sound/instruments/bikehorn/Gn4.ogg | Bin 10818 -> 6542 bytes 77 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 sound/instruments/banjo/Ab3.ogg create mode 100644 sound/instruments/banjo/Ab4.ogg create mode 100644 sound/instruments/banjo/Ab5.ogg create mode 100644 sound/instruments/banjo/An3.ogg create mode 100644 sound/instruments/banjo/An4.ogg create mode 100644 sound/instruments/banjo/An5.ogg create mode 100644 sound/instruments/banjo/Bb3.ogg create mode 100644 sound/instruments/banjo/Bb4.ogg create mode 100644 sound/instruments/banjo/Bb5.ogg create mode 100644 sound/instruments/banjo/Bn2.ogg create mode 100644 sound/instruments/banjo/Bn3.ogg create mode 100644 sound/instruments/banjo/Bn4.ogg create mode 100644 sound/instruments/banjo/Bn5.ogg create mode 100644 sound/instruments/banjo/Cn3.ogg create mode 100644 sound/instruments/banjo/Cn4.ogg create mode 100644 sound/instruments/banjo/Cn5.ogg create mode 100644 sound/instruments/banjo/Cn6.ogg create mode 100644 sound/instruments/banjo/Db3.ogg create mode 100644 sound/instruments/banjo/Db4.ogg create mode 100644 sound/instruments/banjo/Db5.ogg create mode 100644 sound/instruments/banjo/Db6.ogg create mode 100644 sound/instruments/banjo/Dn3.ogg create mode 100644 sound/instruments/banjo/Dn4.ogg create mode 100644 sound/instruments/banjo/Dn5.ogg create mode 100644 sound/instruments/banjo/Dn6.ogg create mode 100644 sound/instruments/banjo/Eb3.ogg create mode 100644 sound/instruments/banjo/Eb4.ogg create mode 100644 sound/instruments/banjo/Eb5.ogg create mode 100644 sound/instruments/banjo/En3.ogg create mode 100644 sound/instruments/banjo/En4.ogg create mode 100644 sound/instruments/banjo/En5.ogg create mode 100644 sound/instruments/banjo/Fn3.ogg create mode 100644 sound/instruments/banjo/Fn4.ogg create mode 100644 sound/instruments/banjo/Fn5.ogg create mode 100644 sound/instruments/banjo/Gb3.ogg create mode 100644 sound/instruments/banjo/Gb4.ogg create mode 100644 sound/instruments/banjo/Gb5.ogg create mode 100644 sound/instruments/banjo/Gn3.ogg create mode 100644 sound/instruments/banjo/Gn4.ogg create mode 100644 sound/instruments/banjo/Gn5.ogg diff --git a/code/game/objects/items/devices/instruments.dm b/code/game/objects/items/devices/instruments.dm index 5894b559ae..13be39aa11 100644 --- a/code/game/objects/items/devices/instruments.dm +++ b/code/game/objects/items/devices/instruments.dm @@ -101,13 +101,23 @@ item_state = "synth" instrumentId = "piano" instrumentExt = "ogg" - var/static/list/insTypes = list("accordion" = "mid", "bikehorn" = "ogg", "glockenspiel" = "mid", "guitar" = "ogg", "harmonica" = "mid", "piano" = "ogg", "recorder" = "mid", "saxophone" = "mid", "trombone" = "mid", "violin" = "mid", "xylophone" = "mid") //No eguitar you ear-rapey fuckers. + var/static/list/insTypes = list("accordion" = "mid", "bikehorn" = "ogg", "glockenspiel" = "mid", "banjo" = "ogg", "guitar" = "ogg", "harmonica" = "mid", "piano" = "ogg", "recorder" = "mid", "saxophone" = "mid", "trombone" = "mid", "violin" = "mid", "xylophone" = "mid") //No eguitar you ear-rapey fuckers. actions_types = list(/datum/action/item_action/synthswitch) /obj/item/instrument/piano_synth/proc/changeInstrument(name = "piano") song.instrumentDir = name song.instrumentExt = insTypes[name] +/obj/item/instrument/banjo + name = "banjo" + desc = "A 'Mura' brand banjo. It's pretty much just a drum with a neck and strings." + icon_state = "banjo" + item_state = "banjo" + instrumentExt = "ogg" + attack_verb = list("scruggs-styled", "hum-diggitied", "shin-digged", "clawhammered") + hitsound = 'sound/weapons/banjoslap.ogg' + instrumentId = "banjo" + /obj/item/instrument/guitar name = "guitar" desc = "It's made of wood and has bronze strings." diff --git a/sound/instruments/banjo/Ab3.ogg b/sound/instruments/banjo/Ab3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..66e263bd615f51c353ad8867223909f6e71a7d90 GIT binary patch literal 20372 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 G7@YvU`L-ee literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Ab4.ogg b/sound/instruments/banjo/Ab4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f003e03233a8cb2dec3aff2f4082a915d862c542 GIT binary patch literal 20396 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 literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Ab5.ogg b/sound/instruments/banjo/Ab5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c405725208e891a68f5c2be6b03b7e3a0d568b0e GIT binary patch literal 20411 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 auaSipo~dOD&)SPHVIRk4;kr9dRR9k4fx>A3 literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/An3.ogg b/sound/instruments/banjo/An3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1700704c9c10877dfec52c9578744c2337080640 GIT binary patch literal 24289 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 literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/An5.ogg b/sound/instruments/banjo/An5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..d9cf57c0febc4cab8285e67a93b4fe509cc5b606 GIT binary patch literal 12373 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

$a%}}Sl3aiQo&yet4dgVXsf-b80zj?*Pm2l zc$k=9Lkx1Ad1h|Daevo#GPi3f^dJ$*aDTB47o6*lud6Vb0#hH(OP{A z%9w;lj>Mi1cAB!;4Ek&$px~&D#9Q-SuKp?jNLk0{iH6cl@3v?M(s>7rebUwjNPS zzZw3VEH3O){vrgW_DaO8Gvk$*>Nt)x3qyca!HLtuj@DpK?4*l$Xqdbmp(Glg4tD5z zKgHe0q`I+@XZQmC5p2;2@qPg?0q~P)QHEww9wfNJ4ikkK1-JECu5Ct#Xt zf~l7XWr`^%9bWf5%A}PNy*WVLG4*k%KPsHA?WV86`(BHlQt4*Lcft31=I(jC8X0(~ z+R;q+Jur9LsBIIYc6;K2Ag{l)%!RFz++|IHeGkf0XS_cfp|fds?(?1P%jlemL2eX< z@simFTxKu^%r8eFKEYy;Fb%WAku6>$$_pU^T|5~0U_SzaO_*DZm~Pll1i;ATQE=~R ze+WPG3;you5fN<9WO)HE_|AxPUd|g5SgUYU{|y;-vHtywip-hB@xw@l{9lJfELCo_ z)mNj#sT;~xjyEFe7m8Nwtgy*_ZDLh=QTcV`{c}0#XVD2Vm7wdY@Bq>MmcmRr>mE^5 zUJa|i%>Ey>XD{@g9dfKv02}AJ1)jpxzr&LmTmPbn>;{#C1)p5hA z7W%ljq{*z-ORuv7*gAHy5Hznaa48Ceoh^VbqBH>*#^3h9NFj_6_INdoupBZ#kH~!R zx@w&L>SW5@_ATGDjM!O=nzZBL$<6NjaXIDNAJd8-IbZL|bIV^Qm5d=+Uiuj=OK zQ)U)@FGl%Y276h?7-m#ykLuxz;|jgoGjs`v#!oa=ttk^E#U>T<=@m1Vjfb)*UZ}lO zFf~A2b-|tnTG!>_7sPHaG}--0lV5L-kF1oFeig8!w6u@OZ+lqS8%<`I2a}(ECd!Qg_FTCfQU#%Wtl7Kg~gQFY#aLiH&iUW z__Gf>x4HvUDb^iNxOlQ@AQ@BOxJHB@z z{puGacQGgFtKK*EfkJnO*lt_87@_ zr9ud=&M1-*m!k==+h7}zECG-ua3jT&9v{0dwQ2jfMROpDXjYYpB(nwtP>>?+V1g(x zX9%6oRD|1+Afcbhg21&+*t{A)s6}4{+k&q?(mu51ewwLQL73OLY<5#{`D8okV}T$4 zpq@>$amKu>LNP~>c}b|gq3uRh^{cXOTWM8i2})*<+b^Z5FTY6Z?T?6;k*lqnUmh$Cl^5(izwAlzLNqQZu?G`jse%y<%Acqi>hKT@Z{>49hWH}LOI9B$; zcToqLOjpQMv3*LNxshw`9*T@7!_S3bj!BMbJnzSOU*mTyBxEJcaM+Z zbKU1&Z|OIPd1s#GY1y2&`|`Wl!MY3KP~gMFK zUqx(C=`k*cYm5BqW=iVevD0C1P3As{6>17h{n%P-kxIB)mbjmhXnrJ7>V4IAnm3}U zZR%`yyQ@I{_p;h|A+2P~YpK~4_}7fQBU*o$mzvXaJE%I#$ShK?3&3P444&Xqfve7M zH%G5gUOZTvj8IdjqT<{P0h>fT=lcQ-sR4H#c>Ht}%ELb|@DQsbySrAb;Q5SNgcfmV8l`G66i8HjrwvojnMzO#RE_;{+>Xl7jq*DTYtM;P9r zD$qE7q0j$BQoWy;`(_cduj-q7aS|aVDF#EH@84~f5b_#1aBI6Ajz-Hdi!=sfYiAUv zg3RgT4t7Rtb_#It={METr_r z$wtr*bh+X~<2Yh~;|4e3l*!?o^p<_A(}&7|AC+h_Y-~&)C7Iobj!_vH-3YXZm{RN$ zAJV{R?G3ZX26|=7lSr4OTv`}(K&Usy7%A7s88VxA>?Pj?G*Erc%k3H7ZD>G zG`ii~>Lzh;p8Dh-ZFVKW3roLPBk6u7K?z$pMhJm}Bi}Vb+jArSNO8XP*p#pE;XOcQ zp8#qwo(W$i^x1l?LIyS?pR7NlT$6BtiB-QFHb7@5a&cIauM|1;w6Cku#FJFqNXX6F zY`x_XQgijP^Nnl8b78~3zev5SRr#HNku#FXBz@MhnG&_%R(@O<414y%qfkU*j`Z7$ zN^M!vmnOw-_P0-+C%*dH)Y_xPOAs`i) ziKWCas(99sz47XbanpNo^9MbC*uytoVm^5VW`0yG_Vv%4P3P1x3E>XW(uMtY9h;CO zoc2EFe(K0QrO!VNxA`L(j=pb~iX2I^SLzI7M-v%68LNeIN*T|s*e1pk+HfMVik6K0 zU*ajyjbZRiEdeBY_6rPbbD)Q5N*O^sJgERrh9SU215a1n_qJCenk$pJ1>ZL4G^vPT1ULBYy9Ya8XCc3x@P&@=kdYGUvW@V5G{Gjkj zieT*UFu#{m{Xt&zJyQ|m84AeIBtHNY_(?QBsyONp4>E1PT2{(Ux=}YwWbEj+cH3C< z6?uQJ>HBs8$tvp_=-PPugSoG~{Uyo)F-OlrnwDL5mUYL4Hd+JT`+3rqZ*SK&N*iDE zw$$%4HQ486b#{KNly5y1a<78HMatp=!L66?pQ8Rd(*gZ1c7B~_Iv_;{VLMd1^tgfU z&Yq5euHK%(;kLfsx4k{@`g`Y{v3qTo?uung2iK?c?y^z-u{N6#2%s1QRHboZ{e=!B zdK=%D%MkDOUtw(90`(P~@P{wLa}dFVkG6CnXhK)|8BLG}4}L*}A%%?uWqeGje|$Hi z<|Yr#QRp!5^jt>4mmSvYrYx$DW_~yg6q7R0TTWZHJ`D*S2^{E$dkLw}Nla*#mB-!p zkh(ax%vtimZY}9s33_2xY`pJ~5&yS0?YKN=XBYbQg|+g-b>-Pf8Ef;eE)_0?@v{8I zaVn71627;1nbc-ysveRut+UwNuXzSk>0Q^EIiLeG$%Qcbft7-WIJk7!jDNi*+@}B$ zb!MaeqA4Bp+yLm(dXqx%@)`ujKqFnLEHb$dW)t%`@6x9TE77`G|K1Gt>4?GRpzKz& zC_Oc}gI$%Z9ceqeD}6!J}9xQqM`_RJnf?FFlM|*AKZ(9lUBs17IKek%@ocJFR@c4Y~T$w zi5=kxth3z>c8DdRQdqCTS6q;A~=H_ZjedeUS6 ztQ(eIyniseOO|6Lf8g)0;bG6t@jjx|!IX{aIB099BI=R~Sq)!$;GHqmEw4;$)lFAU zijWA4@>^w!5e1fYud42s6s$X6pFOT* zvtyq0{I^kx3Z)C02H+FVs)r!t)b@UcjS4#0#&GY~71gS8hy$BOSaLnTE_=+YF#xs+ z@)p@oFXEY@v=Xjb&Pt}sRk|;{s)$yUFS%GWwc!6_A_&mTn`KG*H%$HJzV4EDV6lKr zwdzXnx7Q=Z!=EAF4!p2#;H;o_lGxIW-mOXYY^GkX;aK7(`pidu$03o>kYL<(nA7ar zXq>`3Vuj~_t_Bi)CNdSjipzaY5OCE+==;xvd!lifksofM9xrus0y{iX_&$7*K3ppA z*fnQ790h_9dS>ow_rAk)=&1lbnjVb&ycGvTpBf{BUK5JgI&6ee-5=9+7n@Tg1Yu!c z9^tG8`04KA$_nn5LnzN)(kX(TB)iSAVh&meEPnw}U7*xi9ruBGh;H3NS=T~E zI=zy7Ta@!FSHD2Dk1Uyy6+99cr3ykPTAIkwxiPyV>x;rEz`!=Bs-iZxW+BO*QgW?t zF6+q`wM*Xm6j!=W205}&G^>y0+G-w4AxY)1kG}Bwg^9CVW%74)BaVtqvd=EF$U~i z{h78|%o7SDXYcAJJemha$`O%oKodF@ei&<|KgFdMmP*qsJ;!=;(*fPP|HGPSHI5E_ zOE4<377uFyh)wapGI(<*(FlfS^f@_`^fhz)ewCwZP+QrXHin9L)xecuaFNoDN(|@g zO3-|^uV7WCoc170T#St4W$t*#9?j3(m?UDV{irtg4t4?N_{+z|(^e6cL6;OIJj}eW z*HM4E&tc)gAMdid8?ITV#Q#%HY-IMM;OpTn<)Zvz>OdlG?Nv5kdME~byVG1t`%#7Y zIQ&xC(qhEv`|eH~7+{-0Q2E%Kx0Yg`VHGMnYo!VfuN%E#Dv@e;dn`SlbBF|RA@tj0--yZUM8;-3}r}Ce`N30`~u)w?-NuH@g|wT1ym!j6GRrYrZHaQg(nbW;_rIoJfRdjmq9y zzpCO>c3xsU!DUxmUw$vtC;Joe@O2`C#ybyNq?qcr(%zUqDZg2`AH_EF zvftH0A6Zr#)KLmq(Z0BeH5w;q3|Q*-r1M%G*4SHU709hyaK{}*%YLsM*A5wyKs;=9 zNYrv?Sl;4Eby!`D#Vx71jdNXf2^jypL?M}|*XpSUS;gDO6fo-p&mja3AANy1uV3|s zhk+hWi??l;;i;^Rt3}FTNAB)&P}JggC73R6elkYYVG0J&cz=Gx&(mKuhsi%ICGM(f zdTyCiz>F75zZU!^Tw~?@G_zMT6B@bbmiWO?)w{3PVc#X6K9&>a|XUd)G zt$1t6Jw5bxbaVIXP%C?*#uk-cwQ-4Dde1`l$6ayi!vo28P`FH}->@SoZ=@bIZVWf< zS6(7)6bOey!U#CopLvo{jGwunjU*YHb1Q26JeODf#>ty@Baa>I;>Ow}d05@c8YP8c3FkTtP4 zlh5N4aI;y>`D}P6Qd)YxQ}?mgda|;V2!D4z=0xR;&|poP`j`ZMN$K(}TSv>juJT1F zqH@vs_5Iz=zE*ycWp7iVcm>WReCu(m0nsgM?Z8E`zKDgN}9`>>s6`yk13WYCo}zfGS;{8zJmRy zyf~h8dp-( z8{Ahzj^?*Vi&^JG4Ps65%u`=Iz4lx+fWdK>nd@+ZC}KE)iCU7B)c7vL_4t_Tm+cqa zE(?klsn0$Ty+hoVz%}q8>Y{y$l_dKr1+;_fd~b=R&s3*bGTxT3l3%Z`$wU7Q(KRKF zFS=I>;mgN43Ak+5FPkj$&Yz95^q1v5z4hHoO^r<-3${1t0pTKEO(;(A&zu1)36{_tx}+m_<|eLa`DzWiHY%kpA}d}vdaYu^J4@nMO&ytG7q>V57U zt|21Ys1?4p+riE9TOkF`amIX{pLf)vGvX)eZ;&@m#$^qZ7?p<*&)@a8oX{O7zNbcO+7^5KQN%VbxYE>Wp{@==z3r7}-!63Z1$ z-_ZP6VD4jqC#msPG+o3X2cOSK+32%x28a3$oo`^OR}_j2zg>YP{Y>^cxtClJc>3T6 zd=&(*42S#ZR_;AM6Ds|M3NrGo zpCtTHA0fc>ep#yO%A=xm+Mjm!C}B8V+#c)Y7Y~f^;3Eqp64xxXao66((c}(`J*)q5 z+Al9mtt^LnGf|m$xwsBWTGgbqbVaC2jw;5qwmJH1Zq)qY(zwiMqnSkZ+tkO3l!LGKf zkR*>h#k>dSrzTw4f-yXru$6uf#q)%ZAE#^0-XM=yI%$8aBT^_pRSqLXN&ysM6UBOm z*?MwBqyDO%il1bC2N!H+t;P-i+)ViXvhIiK#Yhe@HwNV}!=H&oQOIR_J>_A|;YmGH z#_LB@EZC`1`q2HzqeRw(+!^DeJCo_hr^1&?r@s+P<)ScdT}D@*aOlpACtjAiY?%5O z7O>|h@f?n1*$>up(<^iwD%WOm;U^f9@~7k)Qx_yBqlMCllH;GLZC?aImnA)G9(j4p^ApSq=wJJkMVUt+8_(wTE5XA1 zg7MqA=7GYVSbCUoA4%)loF;!gTOiM;;qIc+$vb2<52M;Ty1efsNDr;XRV7DPF1{ja z;k-~h&+_2*$1EtGq7JT~tuVhj-MXIcSNaQbvqBqz5`vmh$m1WRk~H$`XQX)>HBS(P zBuXr3<0qwcQ*>yncf*?xpF@YBsP}%_h^I88Ox`+2YjmUaM?ZaTmHg<-lM%>SH7AhYID@GImPn6rTTPY=c$zSg2cqy8u73@PD{1h zoNIsveikpV{^(|e^ZTqk9&29wh^#`$GTR<(@C5yKjnR=*y0u0bjUP&Kwp&kGn};t{lQG#;O?59IM#94pe3o3x#*{#!28nA4-<-& znd3|h3~(1dJf>$hl-NuX$yZ%}gGWOwW@dV$HI;&xOIPI*2}`&^6{|Bv)vs2ONMC~Y z0`;DE8;aPh8cdsf4^m&(kqkA=4N!!ZsOMmVl@HBsk^o7})5qK%fiGto(qsk}J-kP0iW;x3EztguelZ~JZ+?8+cu7o8 zqGijAU@p>-b7;RW?ciidwC>&ujrr`^4bmD|`?~3%@9obNVLf$M2q};n0Y!T!J~Gwi1f=Y zgllyq!o8}lMNw*?B}K_JzMI@Nxuz(5mA|1+*yzJYJnE&@EXlZg0>3>h{!|(kZwxaW z8Q049#pd&{Opo{$)wx~I&DLp^Ee_1@{2u)%oW&IOkYDsLiZx_z6|H;nVLW-DADm&YIa2d^NS-yR z@NXQX&Z-Bg2maDPhds^6>^IsBfAjgZpB?=@lYHd(kG+I9t`{wL8H7+J7as?HB1;OC zFat0suKLxyO6|Z!|B`b-Hh>ySc=Qm&bP;$0gO^&5DYs0LUF2A?oNm-5Udf&#OAKs^Ms!~Do5@ut?GjY%^iDtF$(6_D)N11 zu02(Z(%AX39I7JoswSbxnxM50bTRn4;*r-j%G!s@URjGfUD*h8PtqJF>%sQoc@&}L zK5Om|wDg6-yONL}r#9~BE0;xDc~-Q|=$>^j$+z!>j1g(@_XlXOg#}Em-08@#gK;=d z_-0Q;_|gSjp3(fNbcPQj{$~?+#GL&8e*qp0;qy)lrhw!k;l3C3D6X(Dr%0N<%C2n~ zTVlyUR|BgmG!;E)#RRAUc43Z##m#c0%s=iC*;cbk^7%V;Z?$zZVfchl44 zI#f6gd0q&j6DE^{-nSzDgYj4?DIK>3h``V2(^0y zogxqR3s{hct=YgM<(p`X(OOZU7-!^an)=WBT}xEky&ieFygpicD82BJ5>Sn?8m;=q zN);f-ORMPmn&O9XP$20hH8Cx`lzV=$^7ntJ_gj%kp zGK-Go0(n5-uUQw_05!r?$pVDtV1K(%Ry7a+US*8s+_Dx76z)3g;12*00J?+?AP_x2 zMj^DO0JsK#&0stSDZPl#15X?fX^w-ojASGjzhb`|7_*wgv$-PM*Mqm-Jm~ROcddOm z6CxkUuSIlvu$pW9Dw9o*J5p3u za@59(yf?C#dAeLHq^EIyMN}GmPuz@LFAE;^kMp^s{D=s`AGywhtd$~bbZcE0QJEep zZ@}X-1`KDsw8AB&%SD%gfB*nKX6*g)_8#mY1fh2KCwq$g001<=1`bI86F3Myjvl{m<05J9xM_n4wc%ps zpYCJg7p5Xq2(9O#vB1knX@U``k4>1*V;akN<_J2SjJGrZCgA#AN@h1fU4lWa(DJv5 zvRp=3u50z$ukx}$yXK#OrQfM^n$MD+zE6kDK1&LJRR;kqnRqfqAJuW7SX>N6)S{L# z$+g4O7UR?*9xDiWFF~~s)YB+A)(TG8Bf{+Fcmn2)qvSl$+&L?{ajDc9g8{r98u}Ul z-eoL(yQdkP4Z7EXnGg^9mq3F7HFO35shC9B2*peR8A^Y;pO`%}UtHCU+|fY~9x%=n zxOG*aP|y-wf^S!Es&&k6=>NLOsIHB|lOdl-Ox|kfY$>`&1OB{RlvkHMF5xbTMt0}P z10zF!Uj0*3*8!<2LsQ!wfzk9UDle?2JDQ-nksx0jjND?0^j~Gq{ISD*mfop_JAdj$ z&|j>g!8k6u+F%46&a}GEkKZ=^tJ*xJQ;B#W#yE*6 zW*|Akr^!pQXYgzY(!iA(C{GismPmqdOoGg!+2yEQuMmmI|JvmA>X1;%E)0oh1QOS+%=1Gm1qo zHX{CF+aA;=?r)x;3fO;2Ysny$R!(GPA*pvX5*}u3^SNa+*mOkLy$8bZp#KB{5+VYQwZuiKlQ^&}wlz>aP7KcCd@iqe zl{*F7Y?y6)i+q9T4BjrSzMvu$Zsj0;cv72Dxwb|Mx|y%*<)WQuI4u1j`siJ)3u7?s z=lfN$i51$*bZBLZ7t^pZ!&nB`#E%Rc5}#odqD8%9`H!rzZIkM zd^uZN5*_#k9%gLwcG*e}fzbJ#lH|dD2`nhk>7)`rR+P2U6tG1~ZpKnk_L;{@YPkAp z>g$_R7~#pj0N}a`&-TAw2T3io4gUJW3(V%SaK)$NKT}#EQ|4@3v3&Uw(TkMl936-S z_T3d{P+^X;FZ-=9PZ1?E>cMs(7+>IqvA#Skis5_R<>98QR>6+_D)?Ax`{*13Id}J# zum?db$k`cP5M_hsvS4dLN017<&aB$3=^~<>mW)hI^513Ul2ryHhER8S;Dra&%G>}x zW^Bvl8hS9k5Mg&GW+Hw70OHWuz~M(Z(NT~}Q2^|Q1?$dQ~)3WI4{x+6(6&DXHKh3W2&Hrnq~YEbQNg6bY8Vmf&;6h6l?LG zb+v#L;_Qfq@x$G;u}6?OEzFmFxTIvuOJBut&th}hSbc=y6e2RXUK@?QSM)(rfzw{! z1aZ)zK|VwIJj>ckZPV->)1(cOBg%Df)j9`M zjtfT>_5NmJtrXaub?Ku*s#9^<9sl+%NDGKZ;GXH%5lBy5UhA+yX4i$+9O_2wOIsJb zyg*K)E7mXzolC(;mz014US*8wT&X2<%IMySEaJiZr8OkvW3qwAI9Ex@LTd_u24wg6 zEnc)&Cg_)?&7R!en$!S4A5x?+3L@^lzSSKhz^$`9dy9H4_BYapdr9p@mt)*oPE@fg z*Ds2KM&k6YZo6GNXy|A!38b#R)EpLV_9D97u%zL6os&jxXq-l*;>VqHvt^F9EHQUz z#TJpRTy*Oal6u+}==01a3f3^D9l*wTn`&1|OJP;QccTf{C*F1Sl-HYT!%y1_saTh4 zRAHSDW&l2BoTg*5J;f7cBD{5&g!!O^!Gmla$8 zZBp44A_=ue>jXeS)8Gy@+MDW>r8^2SQJMq_oh*gwTZX1^_;0oYrHdo}_Fc;yVww zh!6TF5Re+6gbh5Y4*8}$trP`hjfw~PcH}awTh-H0bNut$TPabh{*nbO>gwu5soO1f zU20U)t~w8i&eS0z63#X;MK4)Fv=bkBaB2Usg8p~jI;GlYIc8>kOVMFceC>g}DdUjne=gW?c7U8%T9G2pb=z;6dL7unI6LE#xY} ziUC+cif6^&PSrc3lY>sr;P!8F3CsR6{o>J0B-f@Lw|4++xJY2sC+-wgMhNO!luf|Q7eG@^vk zpoD}V@eca?|DXT+yzl3Emb;g`GxyG%IrBZ|e9z3iefO>oK!X2#+L``cOlUJ@AXpK; zZk|>SUS~xJrIP>L;)nQq(SW#p_T+zm&YnE086@uXrMz z^DfHS!Ak#c^C(r6n24yDh?vMF6z^>pR|j`bTQ6HzZ@#m(5qSR|H)~qy9$1abxYhF#Blj{H1#nK$ z+Jar4;y1j+d%R@fal>2bUE<9TJ2xr*YZA_;9RRc_bC(D6JE#q9p&hoEXFtAyMEJ8)ne?7q)BD3aEX@hCMK1h?NEo2tb zrVqD2)=j_ASeTOjcLtpY7{9~0=`WQ3p*SZYiocJyx?k+Q;Mu9PWa4>2hEH>F+UgazXR*PEeAlO3IA)8iB>V9 zJsA&fDG>de;Qz85589r1=6CU2>Q!7CLxLZ+#c%%-|3ss#C9a`EXZnfGXPDkrN78gy z!gg5CcGTB)vd-4HKFF}{KL+#9Y-YxN{)gq9nFxn;?01y}-2Y`cnY^*zF2{1JCU6-h z@Z3wj`#7yI_2o+8YvTXSa_pn>Q=;-Cqn09Lc^@Y`JWeZWeC^ya0I+eS>VN%+mbTESw#2Bmke;sG z|Jh<-?WnlMusBp~5&(<%+Prj1Hy=FVmWoA@b>x|-E?g#rZVwk|0e}(h742m398i6isWc!;^dhlW z`am;)M2fT#w4AdUY*|Lu8UrB(44oPse$d} zzMdg{u<`iAxxJt{hO?H(M}1(e<(REyz0VAw=;*-lC$yqB@tNvQp#M%SEq? z`l{|0m6h~Wl^2&euff`~f}$$Hq9VcKs**oNf@^gJMNOrBRTb%F#cOpNByR=Rn%s-Z z%8IMj&uW`W*SbB{nnVKg_}=FguQnAnHMy=edGy!0FlQI7w(`I4sOYQOSZlgiKxhqSYq;_pPua(J$R@%*`Uqrc;uz z;zd;{Nsx8#KG8>~scw%yGT--nvdc+{dY(dTAkMHs(}&Jt7eHbzBLF`860Hs;e;3M| zQhODZqbrKf?sZG8i#btK&5=EEguff58>`xz@r+u{o-c7on;JaDaU3&l_y)HZS!9m~*mmVi>hrV`Ygg}RN5Z`S%y z8j<{!scFvv4psrR~OYh_=y2zyFPuy$z~O}oGGUn9426zU$cDn09*zcMKScE0%8C`LMQ$O<-2m$dE&8P05kV0Ouu_)*9-T!HZmhpV4|io|i9NQ;nbRA*Grs zcP=Ej#LSS-IS(e@VTJ`FURj39$uhXSqt^&{LMjsTz;vSGi{cPXv}2K58x>`apkuhm5E~%f>4#J`?&( zB)E6xGu5OCvJ$WJb)ym!v|)E}NQIuHPnI2fX9-_Q2&--*MYYndJ5FWn zxnou(65|lWwTo#^YOuoTLn8oR@CZN!&Ut0Y3k*d3;x>N=fk8nv#)wAHT1AO2WhfHz zb)`U#lgDsIJz$VM;~z1w0{-lV71B%0XQvFW*#AXL{?`@J|IZ)_AQe?R{RXa8U9{r_}j>{JRN_dibn-9}6RP6^KI-?+@jL?U=LMoMx> z^xmdGiSb#&Blwnc!r}B}DXK~Hazm8x@j>`Ni%v9BOZC#$=I72$K64!-MruN^Z36Dx zF>OcKiwt3I&B$3-6Y?s2xnoArLeS*Y;7_Xk?={Mov(4 zCn3JtF{_wbsDJ1o#;l?x#*9e7tgAb~s8o1FB;{0he470`*X)pNEBw{=Sz@3K=OXhA zE$m8a5LIUwVGoDX@UJX9?!U_@WtRRy3j%8C-+hUi3V)$Rm<7xDSRlxF|6Xy!E24h{ z?k^a_sUek1gf0IoOQeQ<{H1q^+GmJ_syVCp3)R0@MC@nk`g=3`zh}?5AcQE+nHT0< z=F0Bla2B8Iz|pktRRb7O06Zof*Z9VIQC%6~$?D;8o|IO?RN7I}H!5va7`qro6Gd}r zb+nz9Gpu5?ZojZr6Mb8fsISHwA2#G!QtR6fGfEU85TRth6pBXBGW5cZ!g2XPW(9Uo z)C3oIo?48Ul(;9{YsdiyP=@!C#z)>ErKTwgeQhNJ?wDBg5@1N5JgJE$Sr)_MnSSv> zg`;rUBfAi^ahL}*uKwT1Za1_O$tdTN|4V=ofE9oQG86|#nshArQ;Imsc&Y^IXEccr zz5vW3Fcbj8g%=qaX&0OQ_B#%jl1+F{=R7X=-|DjyA>qGN1^4guzXTa;`mg#dLH^rK zs75Or|2sZjem-Fl(fri(jOQ6?FS;5c)D!ywnmRK{8T zFg9)f`_fD$Zx4OC=!oWh#$V9l^9?dz|6Ct@>G(@XCw>DhqSuV;uC^h)kvt}GBuM6n zN0mgDx9-)o%d@{5u6-wt`zF|c;W%!@&pFWQ5g@)wevL^sC$oW)jesh2TTAn4fyU(l zsXs?_&-0VoS>JVv=(aNC_x+HrKx7d4$=+8```+cWHG21(n!EpLoGDw&!Ge$6* z%##vEM@iq;W2cB1gx^m&_MEwB=V)s-36qX|fhslOqC+biFU7C6U$(LuvYIbXNS{!6 zQ@9IrY^ia~NiSAt)}HVaZs3D10x*wv{Pr!w_)oU1 zx0B~cWaRpT-E(({cf=iyozylb?)@?&V&i^1m(|W9O&hjjl-i z;UtfG)a{KuQBOW<%>@Wv|RV{Ts&H5ONTWe>oGG`Qp-? zAYkH2T?DB6H?4zKrZIhsb|mM|+nJUfH-dm0t~)ROiM;F(85q)wHQc_EY;*R1Td64}P8AgDv!v%jJ zuHjQSOtK9Wf&{H}AQLIsKmoiFC<~8F9J32#VZtt#j&}TN=UYt98*jzzQ2>xm2kJ0O z7<`snNZ>^u%5%fWZUvyR0oCUTYrPkgp#`CXjW-E3dw6Fp0q`Y&{<|ItD65Hq$RczK zrAY9GMGIj5(4%NSM&sG8s_pxYZV^8~ytcyNqY)MU0N|sCaltecO=20^H9a263}cL( z@M$1P$;1pUkfHIeURX%tK`~PH<_E8I-1=%;BXsbrG6aClY~YT^#brW3WPy_>P4?0h z#4%?=fp(mTRBjU9*zev!RiRm{R05OKX6q_2m65%WL{+g z1#-~%W2xw@lSUuBZ@qy4*nI~8e&WpFqarTe!M6wg2#b?UJF^#d^Xt&j!m+v_bdQIE&kFREKQQ%=u@MaOS%#`jlxHl(oD^@nsA}HSh=z$+| z`Ym@Kv04*=#J+C^g0Nd2TnsLFcN-EhJ3KH5ON593_PZi6z(87+M7;Te9%PdH0L+Fx zyxBqv2{x4ghy%D}U_u&tJ0dVhi^l6^vPTaCKn7;tVnKr$VJ)CFyHGn4jc&ugyy3mG zduuB9Yw~Z)bv6KQs)KVC1VrPAWlGWtU>{2W!c`I=?JFql`Z&V1s52Ee?0`4ItL za02q0?*ROUJtfh@8r~}a(8KRlUhp0MJ30@`z!bA~Cy~*IF)ECK8+d?Iv5Wvcuoyd! z=f;oegQF`apYS0vFG9GJ_|cxwFL-978AHtv?%vPcSN|0eP`BJ-3-Jwr8B#<8m3bb} z%P>y^u3mr#z?uXiFcD}2T!7ZkrbQq(WzHJD3{QJV@Y@atEFwWBE{(tqxxqjOK_qrl zKmIln_?}#YH~0ZC-9`;CG5i2TQ$oRfLEI6}*-94KZyErE5wG#VU_V$RbW5-~g>)zr z!FsN?qZH$9fnIv}_S=;9k7>41qb$FP4V;S80)F%i5{rW+i*pAll=i=uQ6OAN3fDL7J$3)L*t=mxBi zg_sPH1)8-OGMT_oC~^a+t8u}6HFdv`6P2CdN%vhDhkF8?;OlK0ga)%LtIaG{w@x*g z4m9~rEA`$7UkZuWam;Ww&w(Z^K2{M)7;ghWPG@hq*0_s^6#@uG1K^KB08H1Ha7}=f zfZct9s4-wo1wa!Vod2hu8FK`v5CXDD;C~GY3g{8Q7paLedw33jHexiwW*OaHf782` zuEsEs;AF4g=9O5#Z|mupf+o3Wb zal5s5COLRNy-k0J?8e?d>{EaXXsj6?IGe*va+Fg0O$1oJh5(6;fw1jB=#W6uQ`pTZ z4!{z^|EMJZ#AyKLH(Xz-phq!qT3eRsIlA7NfUDH|G{|ikoA1;canKX9M7ECA5SVk|_|{524K{u${m5MPrP3Vn z*O6ny@!1D%z*6MK|hp1rd``ib|;y zQViIiRu)i#t9AWk$11na<(>*B?@sz2cdflj+WgMBj8hRpZo#%mk15B5-~Wq1cMOQb zO<+d|h9g1bN`nHj=B^bXzyws0flLcHwJP;covcV;aRjA+(6W%A0+=eOS4jxYJ*a8u zh($^vC?}x8!Pi>|R!T}*%50pU0JD7^&`j=XH#Pb`^ppGG<-a@1-WjCuzRdy6=QhId zyi}+fpYrus;uikPy#B>jJUie#b#C|ISRvS_I;4R3cpY*8%qemcY@VmA(1_!bM8_$D znvxVGs4#%Czp1nMdDe`rMm=V8mdUs0# z5@7$p`_`FENI)+ylob<$3$VJ_dIE6S6Y_HNX8!03OkIZ=@MWEj0`@u4OP2uuXHGuGDA&R}P>bR|P{MU67O+s#Apxkro@E;1GXZX0P1mWhB0!uu z9+*84gK>iZpt2?1&A**l&^QIybaG#RHmLB3DmhWOUYe!6XqmH(w~^1_Lz4WS$yDLR zc8u_8LdWzMJ|I1h`_iYMB5;j-)@UFf8$Hq0_S0N-BMC;P1|*gQ@FR%)P+5u=2xe7O z>Rn`eKb-R0L;!V>P7!wX9ug^wR}cV$?GO{PkTF6hb0-&iMlonj!kQrNa^|h9SjX$@ znH;FxqPu%0g7_vuqEq;-wV)OOOyVJQgfRA!0B{MIPAEci**>o1nau zn0B=n{ZjO@r+k{>$mjW4`&l-Oe@7qwOIy-vwkCYk)Cq}a#pj1I4gv>vzr&O<2un8+ ziXpQA6By3;;jmQbGTD$|wF7R}g}_{F{uOk8lSKfWkO0gAENFmy$`%P477IOk$A_hz zJ5+^)^kH!;9HbT@m~B4u;&gy;83#T15f3EzzQhH2oX<+qCW|^%m-sI(Uw&4R6BC91 z;p)wcT_P^#dq3|Mnv{8Yayk4`4=&sHoL*)}wA#Y?SB+i!8i3DkztYyULdf})VBswY z)I!X*k<21y@l_@O@5;C^`JCCIHu^rP!fjdmz!lly$)kHy!AZM4*!- z`Wp+;UO*29Kxq2V;!dK@_977&=+CleKI(ww<3sx@k_Y)6;ymNeoe%oE%KUG>OM7=< zZpWFS=6od>eUWo!zb)xh?Y#Q0vJx9<3K}S->u+umdW-S4<(t;!KQCAp=j`_rV6{Ms zI`s527)BEko-5O4dgO^$2z_%2Ojv0klpE*W~KkE%&B@z3`j-Roq5rYH8t$syqH(s|(_S5Q* z+SGvM{P>3>NZo}1^TY!T8DS_Hx+5ZmP6uEQWf5TB98xsU;0VBSOcw%Eg#;pIx&Slh z17K!@zNvm)&m)CfqavA`m4Ojp0wKePmh_hiL7JNm&{lo`?D{Jj%Ne=UPp#l0Ju${;}NMGOD+1}F7-qQNEz4c8`OM7>BXGaTm+E!O;Tj-LofckLd_Ug(0 z#HEBc)&rekn+OVkhnmBL6P-uj7{IYtg3kstk5O=Q9?r;F?r{xzomL#g;FA!YKF9B|Nzn~@Rch!( zmj%rr3FSs*=Wmg2yLZca@$k+)zhh{&_AEh`<_ps^_UbJoS=Y3Nlz^5Hp&E^+xwDPQx!)?KZXv(r_rPZ2wpKyX{4=ZMpjQs`>=mpqWL5J%{Z|z!AjXg-w3zq=?5H+ zFB?2YR?->RLNn{g6+_x0CYn+_{EX+m?C*;nkU}#c#XnI=wU!LjnkhNS?m6b^UZx5G zK;${tQvqhPU@&XS8~x`oy@Dn{UxTRs$#4}SOM@9o$Po=>A-iRS2AT?8VaX2?P@qS7 zgD1-Q3WLYC)i||)Xw>FGvcO^5{v=>h>xFL~CN9b#Y2%DK z2%aU|z#_qk?fkDco2X*vW0J9zcLoN&TNgN29{-NZ3}FFfxD^CIcsWgjK&e>K$bp!$ zGrfQpne7Ba2BuRM4TlnYMj^)TBLL(;-sdm3u#p2d91wQ_I(kUc>2ZJs6?o%_M296< zgZD|1QFY-|W4c05Rri%+bC^V@9clt7bw*A@`0vZEMXfsS+C+YO)x4meqDk=7hh;v+ zErS^0~sY7*N(`Z30KiNOm z4q{ws*(Rh(i5l=Qa$u8q3a3efz()F$f&j61wVW5;?lpb@xE9SI&2TSMrjru~THgxazj$C=|>-wrSMt_$vT6F?X0F9e*41RQX}p8rz(q$I?P zvJKSLXJsgLhdh+mngzyu>;NQ9t-ZhzAAm~8{9qB7mA(i76R2M<#IK(QWxTlHd$8a- zE48isjacGG{=d=JbluT{Ow2bcf>l|k3Mmyx2Sje`6t#DMxuv|O|2)sL^;7vS-Eep4 zC)aP8v;yn{lG@i*G->9e={tDY=m#`(zP~hz3sohenYQhme6HK}a+l?(&c(d2Dmi}B z{mh~6BPW_c1`=8=9!8Zq`vqjoE%*StJTIIHz{GtB_{^U%awv$F-}s;zs1sOuQ3DU1#+86p zo(+ofB;KL&knuW79ULN#_lPq5C{mlXR6tKI7o~4Bd;aQ2g9xeYv?MKpb2|(sls^e? z`qUiHDc1`?$5TTPtm<&j23hWMn7^2jf&ZB@g4!0StNLn+@(;P6%ujfnp!c z?eZb0cKxO>I|z+Ujx*}DeYSc9e*tp{_aztt%0aIR0Agyx_(9&Y9|>_qE??n_&NrnX zneD!1V!@VE0~9~}(o7c)>=|->B73kJTU3So zg@8_{4A-5=Nz>vA<@PV)S!EWvE?SGJ@C6kjD=A*+Gqo?B@t1-pcmN#)my9606og;< z6--|jy?fkt0WC0bgDEyNk4_5OAE`!-zB){)qlHtgZna3ot+Xa_?TykWN-L9E z^yorwyEiVrCnyP&@}i<0 zq=Z{?$~_>CFutP#FiZTp33cAf2Cvex0eVfDs378X7a=&k3@}G9Tpf^17-6>i%_;@F z&^UOHf_ZKvUt?>$NEY0yoVZ)AtTwa|2dXyqbm|!GmHgF>k~&@N=|8qSxZyX?SZ5tK z$h&cAwW`@FKXvX~_O=Ooc~p$VRUdkM4T@iO`YCmx#qKT@VxBIpVA@t`@42{SYIb%{ z;>0zrS6ZrW-yycmaG>Q1g9%_F+!Q!c!V5C50qp0h=QkjFeh)#kQ*OY4P>=&nFBq#P zF<+g{Q?L}>GYxHUP_j$VION}c*g(vbu}y+NCiXjrt1te1M!64A84EE5OfOwkRM&jA zCEesd*pW`#R$BDFnkL|C5J9iPjQJa)3$2U!xSc^Uhsf7~a&Pgf{!B^)o)n}%Z1tu) z#VpqN{Xj9?ytRVMmiBf(oecUNuF;Dt>blJi$tx@78<%3Z_(CAG$*|nA_UCbJ-ug5b?$m!LQf-d?L+vUWxjcIJ>fGs+rtAEQ44k}MNK!8HF|wBG#ymG&8l$` zbJd9gHm7;9jIIYKvx+J6g2{s_k_k)l)66s3XQdF!`;=i=*|Gh}xosYc`fhP%sMRo`wYZCFG!x4<2eFFi~_)3voOtj|`mr znG}Z~-@kfVS}N+cn@%TUo9GWdU;l1uK=M82q0=-4URYU;?IkOg6B^PXVV{Pi& z%2lIKQlgXfb8cbL)zpEWSmx{7G~8DV+xg?Id z?6g!buAh^;ZT#)Z`0w8iOgIHds>gP3GC%8@;0B3Cjkev&B7yk9?aLqGs~UG5Tj>f8 zZ!98;h0eeHEOlwXcN&Det$iWeyj4F6Y<5vOc!RRK*9vGPx-t2JHWU*kEN8C%j6I}4 z=4KAL0c2?t5jQ37lcZ6Hag1@OhpF5_WwH$Oa7E^4PDwMn`bdZwnLZ8wv2r2cy<}nl zHT^dfvu)B_5>=wD8TsB}9AEMm0cKaY1> zlnG!SO$SW;ELpzf45L^0ypHzABA+*RUK;te9ZnlrokibQz#snM)sZJWzwJGu=0FTI z3jks>z#&Zw`j)4V@=W{|hpAT~j9D;QtVL{|Td#h@AFnCd=z(_?934D`jTS*GF5#SIn$_m^^CoC`t_wkYf-uM_g*$Mpxt!;3ZxAJ&v#Kyl}%`1SZ`g$K#Ibzy2XO`RYo@DEd_sIq3%3=Y% z(5nQh0pka91VHmedG@EYzstt)sN##v&=A()!ct(G-<@e3F#8L-{Z<^%%VT{dzB25Z zULT4S9I*fl4^Jpnx$9Qs=ehB&m#kF2hgkz*#@FX7qvS6)A66GGfccjV$*L7>0_GYm?l3RqeSn)7xF5Bur#fu#XJy!z>j=c1C{_C5p?`5q;CX?}LB?s49 z8&iHbxBUL@y6#S={6pUtCNev#%AVDqjyAg1RDKR6-H^R1zI=@rz>thDL%`*|nO#DY zAO0GX?v#4jGfJU=y{cxsHhipxd2B4{{^=2U%`UI!w9rRb2qg6<(`IEjs6Bi!7 zqPi-gM&1@|9_SVzlKz8tx7|(Sp5OE%_=d_WQJhn4t`gC~H1+oPGOO!&3vY*ZpMN$? z5*xi|$=jbI)O7dQnBZN&RkHP%ox2{nCKn|`%!?%Ai(gMO&vgi`8<(ahRUcW##@8UH zZN-=QYu`EV2T@5KrwL!**v`VgHTsuETYQj2bar+X*y___)YfKYR`Ry3FVl|kCmdd8 z!^H)gnb2}5NX~q!BO$;(hhZACAA$gP()r6dA4V<*YTR=OXyGkgpyy2>^mrkX- zOe9H3t01JQQyT2hfr{3?rO*EAKMiK$9-ooXyNKC~ z5JgKefX1qJz+o&3d25}8juJ(m?i42k_3~ zL|o=R?{eb_nOy{qPO=sAx3TI0$o|m`Xg^dxraXrN|s*(t?8wX4KZf+En~HPBXz2qiC=0J7e;Txcq(1rtb)U z{5ixPsp9-+wSow$4t~y7D`0XC@~I4z={mc+I=dS>x;nAgu8!XJ-ac&WyIxkik#EAb z_i9607gcsP_ciCw$P={t^Own0?vMv_D=mqW5Q96X$Qvc~2YA*haH(1Z0iO7gVb)-3 z#sYxbHE1JR^CH9qhqljuG76G{47eyu{%tJ2@NwXtOjk<;r^2=|@yyW+{&3AZOZRFT zm&syn3Am1J+g~LRI+u^cU-K^_RDLOl4IynPWaBq2e!?dZSX>ggWxDZs(%UvO=iPl- zK`NzQ)H6`}$9)QCBQQ&c{v;63h1KE@*`HD*Q&F!=+sGbBUUhZa7E^1zsHA`n;3)1X=+nX@0e;X86w3gG3373mwN=u9 zg6Fs4u1tL>T`$QT%i`3JmD@bONvN%KdgPJj1CMl3N@dhv``c_kY9iJL&2jJC&YvrM z&iZn^x)`n2A2NfT)Ay3KlcHUYx{{9cxE&r-DW-Q%aqzmk>X*Z?2IWg}?47)dRGU|x z-)q|+BKqv(L45PEWtOvem>i6RBb)3i{*rCx0?&f=>Q`j0f}gr1v-E(x1QWgnF#J|) zPFX^ru_q=%^0WA#tOi^q#mItb1zvT4J%Ni7@7It(nT@mza6Ew92uldy{|EA|TRQn0 zb_FUwLPea1Xs1W61#&&Ld|mGJ)kB0qa8K|_Bkx1Zb^Hu}T)Ix;*vv<&&p**LKl8}y zdHX&mjejIIQRySSkwvWKYPg_vf3|M^&5tBH4to!MRx)LBMshAcbLxBn!S@bdA45tc2ktg!&3G z<^^1`RfBtU7tu!!9fMiMSdapzFvXx6C3yo5&Zw)!2(8asIcYV>X8If|svP7v?H|FDq^5)WrG1 zwfU@o4LSL^6bfsu+Pr}aJM2PHwz*%MDknq5!s;w+G-%K_cE$P!T9I%JiNARcN}czE zbDcfwIa05kWyrI{-oO=E!933uAj$uC5V+x2dCiquD|v}PFZ5I>XDInP9`^CHONJv5 zgkbW&Pp(OxC0I>Ite5@eO_L5uza&MJdidqpVZ#?xO65~zf}i%+Bf6o)#8 z8lnb;)OXXm3E4;tSOOFor3ODVZCd&nyRWQrdFK5o(+g7h^ecY|^;)6y zm0{{b5~ zOxy14@T_dv2e;*^1}tOQlPEBL#fZ&#Ai2pLSHXCMUMWb_qg7E2l)J1Qo-CxntfoZ8 zWgK|!Yy)P(4z3TsM})w*SBt=ey<+Q&hQ!1TuETSWaMoQ=?&lx49&L_W<>pG1a%oK^ zP#t4?NqBCC&Z&|zKZ4|NC58Cq&!+oDPvh>H!VYn1F1E~koK4DkQ?KFUbY&_6M(}x!zT!_mPm_W-H*u6j zU;vTEkW3IWGN!49dW$sa2GzPnAlLhz zf+vIgFLR8Wi4~mt0`E~!k7^I2xXp;Dx-E;gYKyqU4KVySJj|=-Ntw7=+ew{W1xV%d zrK&CcLthr`DNpqmY)DtHYYSh$k_2Dvfz!Zopj3PM=d%R2KW@)0sz_+ctj@D5L;RBt z?BaOfw`|sJecjJaPsjnxJzq;)qV011`A(>jDs;nqH(DeBTxR>bB9De9HT#E#T0g`3 zMQ%fIg&U`|L#oa~R#P!&cY{mW57%0xuKBP7-5S2>^B4q`PNyUJM$hf$0*^IhH7C)_ zYqw>LXB_dL*l)bb_!)yl?_Rx6S^ksY_m-HzB@O}-Ji{0Zu?wdGUjD!?Lhg~6Ws2~( z3Q4W?uGgW+R@<2099v`ShsUqewR>h3`fz5S79))zkCKvCcobEoT0?&mQM_VV^L$xA&@>Xoq*4PpXr)&%mkYr*t1bd;;$-S4K zQe}*9e9@ni)zSZ@_aa0ZyP?eaYPT-DrHMjHGLMr96sFWrJW)`8zon_d_PKw1SvmBY z3}|@P&GJZpbprwH;c7+&+zXoy0sWi1Yb{Y$Pou{sE!~E3ZAo5x#5Hb;>ApA@vOMhc zjPG`0R)oUoyZC_588-Z;LVeCpEj=u6`caHZlMwPw<_GrB-&F}J#XXmnEVuMS!@BxU zBjZQe8#B}yE&IRL!%@2#e|VpNH=X#5XbB2^i9E60`Np&0_9?J+NQ(7@-rxi#m`DqB zC=NFK&Zlt&5@iIq$`zjUqkCpYP#_lc#h8zzm zsF=TmuK|=Zqp~A~MY|kN*;A=f$hGq**=FX*^To`AUa-v4=Cry_}D953JGOCA^K?{TXfd843DO z7bTuh@ouf+>N7~)zr#vH1pVkX$BI&IYdx#tkm8NqE%=5>Xfa|i^O@<2l2a)k!1f@d zo{aP_@e!ysBLiO$@ZK8yqXme<+H`Qi`fRU3JL|b*7Ac+|Q(rUi;kGnf%-$yh=+=t5 zT3_DVOQXyd)WvoD;lp(2$(mdQJCD8~IQ3Py_;34H6UDh|<8Y^|TupoJ%ypm1xBSB$ z4ozP7uZ}D_fzjSg&!1MTRj9R!v&m1$%bEZ26w^noE#xw2IQ>9JD>_)&++&sv7-I%t=Hg+-aHO!3yICuh3?;WoXZ(zVp%&S-j@krz~+*{^GzMe_Ii*ijJF>PcaEYLZY`KGcOC zjJ!DS6uO85n5&Q#IY;zxUuy4!Gc$pBSwY=Qbv59JX-=K2Ov2a-P>@vSpy$$m^lO4= zf9!~%A>>B$!MA9Rp~4QOo?OAn7qvE<;m@Uxgoso#U84_8j1<30i5HQoM|dz@ka}&U zUHYT$+}%*A!Y6*jLXo$sHpc2YhRph_f7%J8pb;mwC7uHJo;vRbE@*M>M$=yBDNU!_iZsBbf;5YM%b?92p;%#8;9@F{}O+A%~M|a z_u%C8u}kw^3G&w$o?;3&%`1ZDzoP2|YI#gE_MT7jt91z|`L#c#%ks~>J)?sdr6;tadnV$g-{@XdeZ5*M{4K%gM&b9@kA*xJh!?iP@6d%&6<=F< zYgkFHVCjXJn2?&nV_WFsCvy75qLo))^sud^Ax8Ag1veJHS9RlE)DI);7Y|#|$~Kd> zj&>#^EYZut+NVxMxHOvJ#5QAxeM@38_*$U2Dg_S->mRV0$L~zEjBJh1)=|(xKYvtJ z!`1FDIe)k0Lk&VaEKU;Dbnpdaq9i~|meDM1XBuT`SbeylLTa;L6`Nxm; zEKRJ>Q*7|Jc4$9h7i3@&J>S6abZ6pgyZF4+kn6gJ`g8GJj-LCAOpM%w!6PwtyL^{_ zy^Sf1WO`q8rv{Z(skrf~YnbVZuC{Q0#3yxwDrNn>IdRoV1lqugeY#|^= z2vcp73I2Pj>)XLw3?`Evi-^ra_^vBig%75fK`yHnpnUUOWwTsH8{zvp?(YwsTdzgD zYWzvNS%`Ca@YMn`UKipII%P5ds8jY8y%0(|4m9|F)E#_(qC||mXB|`>^y!_rk=W%P zYpaN85`AW3cn)_JRV?S8_2kE4+btgH+wJUcfv#SVwx;x~! z?i&t>y{6J1qne@%6M4ZpJN9OCOmmqx`$ME8ivqrH?OA;L$*~n{@7Lz(!WwWxbO8d1 z;46kmTkpECvKSuNc@$1pU&pwy__ODx9=4V_&8@vz+cc1w)89Hz>$pGGnmNkz(2Z22 z>ae_+h|(P{%DP_#Sp6#p$1hgV$1CrSYKlj7t&*JH?~-f<_I?^Dl>Ow6OCL^QIz<7K z=vNF3S+{@>SR>-M+g$pY$O~*W5sLf0fnhnTHL2zUeT!&|3Pem3$K}A`?9axHZ9oG`0Hh z#Zp-c6<3Wm3Dsw(Z9IDLWlGF*j^j7dlvk94_la}Sf>p9Eg*C5>4IgrvyUB$h0d>zM zJFN*XmD%X8rD8a1bpej$)qpim+md&Bd)xNUhZ+8{fTUdy3r^0$kHp6|ZDrag$UGLD z1Z>M4ozIUgO??HIE@y=xPdmPr-&ET$eEv&Ne5LvV$L2lEMX*u2b3$5v?YDwnk*?X$ zNx|Lvs#1jd(WJFNnI!waR~>M{-&d>tEgrz^7?_3RU7_vm=+NapYRC3;_Pp=u z?Qos8%{bzi<1AWh^^|b%s(&Mk>t4^4iE#p4q`^u~Ogo*IT`y0%_=U8xt4?EH(hwW; z#zqxu)p3%4uYCLRT);U~rfv62Q@FctZDt9iwCz*zFWO#MDC>Rmjw1Fx4TFq5oIYnO zfi0I$y9aX|yKjF!z`$K!yvr77bpDHs%R&Mg2)6m_ekDj24|>be_pZU4Q*O3wc}+;P zKw1kw*sMc%DhIM)nE3$zdJW+HzV}D4M_rpMG7mn{!V#E!74%4TZn;?2u4oVnnL1Ac zF7W2jH_T1UgBznrp1E14rSXWz#LvpU1$@LW;!@~e)eNvl1yKS@(aEuGqI;CFALOR2 z+nu}yu8T2s+LnRKw~K(Mbtd`!D*<`C-={7{NY^x9r1)U67cR!{rE}aZUnBd`&aw1X z`U6v9Q(4}5;e4L_5eX`dS)Y|4p+a9=>uxs3++Yb&u4D3VWqZqBv!$nVJG#3c9#3WM zlix+pGcbwjE4j-iW|U_HcVFn>_JILDW8vsN$EvKL|L?6?m_b`OVQ!Ue+f4Fn!2K55 zIYGJR{o(11X+M*sCOvfHa)UjG0>9IIn6^jkR%6g(8ryKybLS(8f!$CWKh5gMof|Bb zRWH&Dio=bs;cZ+_HH=SA?68#^m`irLvK5v}K_T0Je(3yRAhB*~CLiTyD3SKe9-q5v(27XZkz+lE@BAJfxY}gs)`$PA=0!Ywi*2^$9?I;?oaeNQYVjU zBED5xbvnb;l*n9h1-O8aaV$8uy}tdXKzaLB4ETk@s@I|kjPc_18Oy^xi9ys?&uM4n zN+#+$$#DLKe&3YpYa#t6MBvmotEt{GDERH;Mw1V}@WQSaz9e%ETT|P5VG$XXBB*{z zf5+w08ZN*0t4)8Zo*Lv8`Jwe~@wP`_O&VvL58Yf3_M`a*D9pW`AA4)cf5h`^9Z7$X z62PQ(ei^6ufsvFan%k z1fMUZ5P9x=vS+2&QPW|jdDH8FbnRlc)D6j`1=ARb-Q*J{jFRNX57$FcL6((YqzcrG z?{-QbscwHrzxDjNiMy&}g?HbYf&6x{Xx{gy0bgH6`#;<2!$z45!6e+|!_F%svOfj# ztA0f?zi@yE!Wbtf>9T>E6MTW6f=K%OWb1_)W6wX2c{SCwepB+98*PY2ezPx&cG-`; zIoLEAZq>|xz=X;zx%>Mym#EPI>L+fvl3woPDh};vRiCb88}=G$4gnb}CN=7t1$U$9 zUMAIh+?zEkT3y|lNNBuhLH9I@ZKLt_E_ugM>P`D%r9M}(i{jG_VV@YsZr@Y&Zs0f4 zjWjRfc^$>-4rq*qEK<>3z4s;`)=Q%+X+@&$1S;blX-VQt+cJMYoG~5^jO_hN2Gb+) zOcJFTF0CtP8^VR)S*r0&Q(Xa9t^j41^yl~A7LQ}o%iNPPFHtZ&_I#m&5Mlj`e2g1Oe{7rb_8b`3Keq)(<`0>- zW>j8#na{*7XtXXe?Y%aB<^DlY-$v8pXA$QL!bxim%EiU0*{A8lw^0I*N8#=mxwm3CT&8?4Q`V385u_Xtzn}fe*5zFv>ZSMv3hq5lU z`m}LGBhIU3RRmJ^v_|lczZX9~3XmEwN)p(72=X3EFx&j#I>bSHNXBwpm3woI`gCP! zqosN)9ox8om)IT27WO1$l9;r)xqX{;sr#P6gX+3-rChr#gI@}L_dYOkK5=TAlh%CT z5SW(5Y8J)d5_d{f{kHx(|9E_UxrR@~!@$A)z5zLRLt-II=|uA^&F6Ea8ak^(G~B}! z)!EEdR8>|!*Qe{c@u5wB*`B%UD}959TjwDG_9-!#V9J~i6#U4L#cNUeKE0$@J2}9f zwyBWYa%RX(?cS)2Gp*idz{kN}{IGoN)66vLv8rAEe8BXog`o{6n^8j*>k|R)YA2Ep zqs^S3%9`6nzWGPJql=tup>_KjyxcG*61u_||2^njt~-;%y~*1h8gIgM6hu|=+I5{v zB0?VqUr)C<&FA7~FqnO$m|Vj`uQO=+{{(#pg7~N3i(BiM)DK3QQ_tDn>47!~4g@JB zp-Rt|rM)j@4Gq3!T;d|(A#2|t*AspK0PKM!K!tR49&5!609ao@jRVXpqdnHfs7u07|O-^eDdLh|=l?QNa?CYk9~`$v$6d^IBh-|X|fOzx&| zukINCbFoh*C4wk#+>1KBEu+B$D_p^As`;P&I-ds~nGFljLW{0)G3 zmu?t^liZv9Ct1iq%)Y(X9vm%hv1Y^Kso)Er)O?-Gv4xaDy)4M)D!OLQnLdjOc)p@R z2k&n!&?hs-;m9K-n6IFsS!7YWAQ$fcZT1)LybOxQDT0WDmaiBwSk^Dt0~t|E8GjYUs)gW z&G)T4o@>rutH7mW(oTAuSqV)5CIH@LoZ=$k*Q@5JM~1(chX6iRLIZ38s4|J{`>dG) zQnU|Y&%x+n`7#g|N5SXm^mrh?oR6as0Ms5dmR6H>FRg~O`qzL;wo+B~6g9u3E?|Qs zQu5DOQ(NCw8TV8V|Gf~^+d{h;_t-7K^eNWyQw28|(p!RrI)_-bdz95IW^C$xer1qKLm4C#17)5K ziDP0?ddTwu83CSUT>bbDk*)U@Jgg6X005K+TLDzmRnap_Pym1@koxrZ7(UEsUxO%I zPT+WJ+DUpR5?OtkryQp%D~3u{l%;ax!Ttdh0apbjSwr#zWYG zf%%xnO8;% zf+mU3tU;Nk88!6lNOeRzVpuwwE;bqrbycnQ(4C2Tqgf#XTupa`)RsnP1vY-8R(nt{ z0DfgG?)*G0YHmTUb}A2m&jmPOYk(?QF6XQk6tGXn#g%BbTg=||)dL%RxFmma58Rnb zjb>>{9nAs`$ilK9xH|bFlT1JlH3zu(&VCqKE+FF?VCQwhDNR^sQ9P5@<)FE+W*4!) zobS1#1u0$rQLPJIeLg=^?e#mHkG#-R_p-#O2G~iyI&~wi+;!_hkCt7mY&)$<|Gq;N z^}7Dk=wFzAZh&mgwq^)#^da|;duSzhc3pbG1AFnl1Fh1X2Z?!+;_rC3HggAf-ep|c z@~f6rjvl#0nFo+m10uj80Bu$I+G(vQKs81+!BCge^I;k>A)B<{%Ac^e+4{Z(qCnef z1q3t5vW#mu*739!Sm}+RO_+YGPqRLYvOm#pQBvVy!tT7pfOqN|W71gA8{B-BbgXU} zD4EFkkx%AIhLMg(9;P_*OX5{KkPQXoqg|R`ctVE0R~u)B8$)>cGUF@xwZRXQX+_a% zLIY7c6w}=|^@S2eyc8{CwhtT^ky^WW%*A3Lr5spkmrFRVK}`YPWjy^T;V!b;wBXWW zcpwOW3lP9s0Of1H5~o-&K>F)Cdi?5HIaWPntr=&UOtq55 zJvxzSV}*?t=pIhdOyt~x?-8J(ZQPp8?d!lRzhw#v)tebM}0I-b! zC6@?9Ewmy4lp>#pF!%uzO=WCm!l#qvi`BW=j7(Magd9ybyjUEl2`dD-er%y7#L{c5 zzx{x4&q=6BuOzC#^*yr_A1ydY)Lod?5s;&x>2NTw(HHfGR146*%EU6{DBb4K)iS}T zFmp%sUps<)G}-wazjDC4GR~NVVALvN5iC`_rVrKggIZ2$8nE*#s-ZEEA$x;X7^7t* z>%N0%z$MhLYfn*PAT>@N0KR4X+v{hQb~nS8BVY;ZO<^201Iz#b07O=o_A+fAx;{=% zxAoc{%8%9b(z9p|x5vVrb0_y)n**X|2)frXx*vMU*kgATV4e^88HJbmWI)S4+!KSu a8}59r$@hs<_ml>B=(Eq?=K;!Sfj7)IN*hGz`XCf zTRC{(nqUf*|8((zofVp4TDXz_PPmacO3jw|FtzmQ|CI*t|4wunq8mB5+F#Lfw}U%5 zSQ(y84_AeY3X6yeiwcXu`Lvu}99-RPJZxM%5xBWwgnx%3{wsrv-(>)R0ATn?;|kVP?~Nku zn0e#e^NSGNV!2B#M}nI^5>cGy4o&rUS#W@XmI;&-=~Zj!hiceH-f(N}3h2;D zyb)8>)7LP7l9$;nZ<`r!uNm(EO;Nf6J?`Sl9^!o- z*P&0@Q(+)QePmz#+`o)~Gdln%5w;#TwgE^Rx`J=rC2o1h%y?+bK&rrLjGKkCOjG(c` z;~8tEE%Z<+DkYP*p+*1ieE-0r>`vBbC-MU{B5FRc?uB-#R3u#ienqray+V$Dvm`B(WRr1=o{Sf zb~b+Mwa^r9HtV%C6RDMc z$YIpc?g?@(GDajKYutp-kVMa3Gl!K>i%}pcFL)-%^2#(PA-gH|mUa0U6x2gwd8Fdt zlwHNQRadW)K-(Sx&;bA=(l7Fw*?m-XAWvabgfu&)AIV#kJfVsZOl1~B@D$TpuVfWW zs16jSFsnsp7t&fsRY8LQG4x0NY&?MhhN1_+ib9tR5uTzuidaj~9TZt*(?ugovh+rg zBB1GAt)QBQBy-`FTTiCGdYF6mDEFS=HEDZXS;}gHD2&j3%vMcvkvbY*Oj~bog z7`@F5oyN=)@ey$e9esl#I)f>Fg9SzngGL?=It`6|eFHj00|tY)sTu|i&ST;>bNUAF z84acyZ59{4%IiD?)^)oF<8HIo`(KJ9Fl_Rmxr^k-8^8q73G=y)3F7}yx=8yI`r z7#|wknhsEdsCpW63cp8}9vY9(HFlG!ioeBSN5b%K+H}lMt7euw3 zwy|vTTH8=ct-%D;5*4|Tm5tli#h6{`2*(lPLQpJKLh3tES>xlfMiVR)^x^sB0) zL1==BpUAQMY%S2RIu}-`t#|M8P0OosMRpmGq~%qaLe zGr25D#hK2;=9hnIT^=z0cMr%x1PA2@$eutH=Ya`wvOS92a`sj;^g7cojUS zAnl8XumQtigKiM@jO#KU<|+&jajnzqQS+DUg-)mL~SBicbQWy0iMS?{Dt42?Cl=z8JZ zQB~5SdK>|oYCW%zN)BCANUw$#G#rM2TreT4QdUT-r&`tkO;uFLsD>74q&IaDnP!7V z6w;ciB6{idoCSL`F80EqsRnS&&v>k+r9e}qhbE!XRZo(1hqID#Q-#K%RS}IzXmv;` zG`c2S*ThL=I!o6{0+I@vDhcf**lS{{-rz-TLVhMyRfD19y{cY_IZqL@8oH)|(a}X@ z?L69{3dg*xhtV_+Vy@>XQ9OMQM=*7kna=P)S4~gq#zF*Z=k}?Lhui;Jxz#|g&-7noVhKLMpO@sjMA7CC_rA^3y1a{B9yTkIM2P!nD!+h;VAODo+s<;F7UH@to6miV+(m(BFN;g2IYIBm(ZK zFUn67rjF(<3x+gWogN6g581y+B(}uct8R% zKrt6Ue35q4R>Q~*HgRZYWDBF>@68IOk|SY&#DLDKVI-7M%RvMv-g_1bWko3yID#(v zGaPC|6nWwZDY|3;@Vi10(F>is9wCW&(4L70{BV0F8cF;tMG4UhPf5~+*g;DwbEklG z*JFqyq?l~MA!s;BcvC~L>NSx^SM?YiJ-TN7Fo}dCqeY2K`~A-GcNRi4q06M5d#sRYA-}UuCw8? zERVSV3QYd1MEd_(L>Uxk(HKIfbuTk3$=|44iT12&?etHOp7yu;A2IuXMeqMp$<(n5 zg4};*0QHKD7@QKb8Y*8!oF^B+t&y4v3iP_uAc=|C!y*tHg<+6+p2?$;d^`|J5C{l9 zkVmJOpwm5cb@_RUQgK_yqzPIOnwyxXXj=Ck#N`@EQT-&2)vT-vqG;OWu^{AfXsBux zBN3qsb?KS4suU@l(1rYy*}4*PAQMMObVor%!?aaQ1EhawhnTi{EHQ0D4whY90Y>G8 zTf~#Xx~@0NXSU{of^E4oZR0Kmx{xjMaA@IDKtrg)VT3CTGQ;1tu!MiNQD0mC3oQsx z>wo*DXv>{Ji{u&9hG2(4#&=fYfl8!*1GqCVhS5TyTnaSv-?kK5h{suYm!gY9B%~S~ z;S8#0B~mV&y3RUt{T+*o1tEyy<96YT8{7qh7o5aDbm42;_oD%Z0syz!dz*;qet1t- zSgKlBf;+X<6&l@Wq;ido3QG_3REkIuy`HY)MwV5Kj#jocTBN%&#SqPx7&75r+2B14 z-6-KCK$x0KEEol&XYPj>g%Kb?-V5xw$ZZ0GPqdL{M@{fywcJa4HYe| zwGGYt%xVX+D<^uqpy|sG?3WE6JI*xp{863EIj}pOY?VCRN9MT#mk+T7Dw$ zTv35X46c%Zt+-2EHTPZQWFciP@7v?v7OY}goy?g4xK9K?wIl#LMdOC1Y*}RB=fVYu zOo*y50bo%CvLe>&5;g1c74aLTJf5_q+Q*4OcoX~aJPMMA>aVEP0r*Xvr!_7_3Bb6P zs~0c0zE5WXOGvgD1bKp{+vVTQAGUdj3oTd#$bh2SQDd-?qXW_#Ar>6LOgKT}FJoUx z;tBwg215VpBfQ}TsBk~r)!zSC+hQY68K%8E|I1j+Yayh!^tD~+Enx}T-9fYFwez#< zQ0*rp9#L?5GHKk(#VrD*cOX!?A&E(LdG}^gP~iO%=i`+>2@UPa2M6T4-jo2#mbP^X z{N%(0;(aCnQ35U;{eD>mAg{R2r;##XeD}xuhk|ma4J5#j3>1~_r7gigdP9<59_KaA&x zYI;`T-|5ITOcOB#-*jl8hMhSpXer=VI3_R~`WKKBg5|?g=$^f-QK50k?n4UdmVeoT zm!P~Vbfr2u0)b-(wM$zJWEoE2r)81yQ>;t>UdB=K-&r%{GQFi7(s+;JeO>G8g}vd z%ul`7Qx{$9T-8za&>P5I7%(y~1WI&}E%U)(sy7P97D|mz2?3T<19v$hgOiP8ly?Sm z`)~wo2rYE`$%}w0*c{e~)i*kXP55sg2eVcj*15U&6li;f5Lx1pfk2yjn?3TbK&9&< z9gRU0c3icJ{Y~?9lCif zQ$AQb{&f65B= zd65eR^8maxC5yOg9Y(Y)PeXBM)Ha`RMwN-=j-NIEoXwYdase1e1VO`ZVln@3KbhnY z@BdzH52}@kzP6obwSZs34-Npd8Bu{Fa?)`vI0bcri!2x_#KXAI@^Y;`L`pey?55uL zbw=BJ-$=zLKL-+82|=C-1=v!C#2~|X5_dm}#z_Qro$@Y&<-%0FDQr+710c>LZT@+1Au|^|WzBlab2LBT)^|xRhGQLu@F=;9}HWUjViRsO4 z;>S-lPG|LG-|geqbl1V6o)cn_!gDZiiZ{*)Qf9ePOdKzUhk-YeQ|7k+LWR?XKX%Rh z@T<|~B9jMrfR7%y+<~RxT-t&LHeUYV1@3TxlFzyT*1iNPX#3RREdwWYNwC8KU4N+P zmQA634I3Hjw?&)TKGji?QkBN5Se_G2mMMu>oKx}$51iO=mneq8S-#U{uG;Ny*U9(x zD+^0Av(WgOf;9YOf#93OsGGqbxdH6+8kiLo!+epqeV;zxn3?&CXl#VoA^iH*8(I`O zzz_nXCCFVeM}_$DFpw#(Cw3t|Ve|D%7IJdl-}H7`TZVe|TU2j3|x>{MiJ;raDnod-8az0=rsk^m!^ z0nB8-NyRe>u9n2~QJ_XC%r?wrBrpD$9nzU|c=~d!>M9}@2J-3jz;Xt=D;DDGidkLm zk--U&msE`BMg~co!C>!?4_=KCB!GCLlwap$=*Pvi`w$O>6wYm3_9;r~RN&bpN|LV^2A?(7LL!-Ksz<3Df02n7piM&Qr_aus&>lP3v#7Y5wYoXBG`GYAD4~t7JMscQ$ zPFKMFLv2ZpD`{rSHkla}IjH-8>gUKHHPWwtV81T-{q^kog4|ob`ih&dR3FKOTWGOt z)X>5A=RE2ZXa~~)j;no;i&REcD*9dH`#QO^{QRk|a6|2HMr|x~nk$im7%L%R8_2-R z3INsaBMVe;a-*o#faU?N1e6IeRx+InV4O}iHz6n&X+dj~a2FdP{YQ<0&nl zi{zya#TOSTbkn0O@{e-AA_X8HzPmCdN!Obej9 z2v}Fc{J`J@!|rC|1C~m>R|Vow1w)5W7Y-uPmOF1z@uJ^li-Ezgi=BjjxI|5RfavqB zt(e&odHT!7G?BkmWjr1lAw*0AN#mb^Knd>kCQhI=m}@?@ydHi$*T29MFYVa~?(@Sw zdD8)ZZpc~6=>T`LrL8UaBsS_|Cq^7=eg39zMHaVy+>iW_m;*o!9UdT$fKf(=fe_$= zmE@avIf`yLtBA|9e`1;6AKFUEYr}8(?^}Z)2HeF`- zQ9%ZqKLL!WSq&h}1=cXG#Msb&^6p`<@9&=OXgV!P%yIQ3$ZC-^H?K}w0rp-O{@K|c z55-=`B)o-#B4+-zu%kK*=SdhhMa*J8SrODaXh{d?4ajU@@fSN z9f}VQ0U{?a`z;5|c;A9@+3k zw+5rd;}hWrU2b+aGS4$#(gYr;ep+9ADCB()NOkKVtxA|JjB>vFnHeOyIb^Bi=m6?p zHu0%i(F?$2iuLqGE^WcU>$c8o00UhDut%AAplg>mbUdnmU4_9e5t1BpQwxf~ENU~0 zMk_oNIch&n-GlEIuQrMKJ#>tsx>3jyB-p1TQXqQHVj`J>oWI=F@BVL3iDUlIuZ|x| z0-pG=dz@!AeN#^aDS2|U`=&5mijR@xvDL?8%Qix{cd}ow?7$s5#9g2us4z}oXqY0; zt}T62W+d^oiKK=olZ+g7{3>2)Q(2LbF{DU)g6W|*rBHwjCI44icvo!`V;4T_Vfy?t z4@)6Bz+}@F!2lCJO~5Jp*X=K^rRuuN&tDkdZtW#d_DEh{F-v4^&OLM*EccuJu^6rW zt-|Sm(nn_Dm(p-%W2Zf%>%4Zc8EjF)bN#&#N!AV>S7wmN>m#N6uJ2&%&8&dYVx$^i z1M$=FyI`oUpGthTz(z^TqmS3)3C9hm)E?>CMM6R>lWgSIEC!S-kpOm#3Jw4o&hyQ% z;R2zBEDT_!DEBaTO$1>+vX?{f_p73)&=T~1uD*oH?rL6f_#-nFGzc+~SZT9My;9Xl z&kO2v`YePHWrEYsw!AO>5qj%RZE)^_q&ER8(`Hmse~oHT@AhE0^OPc+_YydU zPno>>uosp(sk;QIZ!)}H=VVBJ`k(d55m?S4F7_4zmQr?*=VOVx$#OGh4D;D)67!om?+o;fHu+xEz=)&K7P>lG?aj-Moe z-1RmrkIVx_BOGNoOo3W|B+Y4aG2o=Dee7^;HsTGzZW$#yQUf&@CRtDxO?PL2AO{C! z+Vb00S70glBmk5wp`!ZlbA*w42AYE5pOkoiUX$ay$F^M-Y)%c?emB6LL#mwbTNRBE z?Q%Mbl~c2f`ckmMK(0q*(CQq;GhI7=eA_2qy7<+{j|0w?d8*X43vU-S@D^?Mk5(S4 zj-TM=|IixnzuQXaJzg5j3Cm;A4n@KVVmzYLVfI!(9BS=kGHWXjUhUnyzSWS^-&+&D zp?K*<>RQN>8NqYia6DjPV-4Etw+O%g>XY$hs!wR#o?r_OubLee!)V)vRKsHy4Yn;n*iRPZOU zT*e}p@l=D8J$bdXJ(D@3+;6u{liOW%VLU`d*Pf}%9exWxC-s{2Jlg+P4$(VO1ps`9 zoLmd`lxIdVl1X3y^_leM(JS=Dgq6SxMe4pC&6Grlf|P`T7|$A{kI}(JvtJ2A%Xl%G zhv@g>BsnXiBThpvd)X4ibak`PR0x{h2#)fx5wr3q8+<&aA?mkVI4jKN;K7vtyjiqC zdVvz|%>s7;8$CLjXR5DndD-38{-UO_xvjRLvHC^p^U9{SsvL>^g-s7c$j*<;JBxM& z6n*RpZ?J7Z04tJ52mFO>YL?oZrG*T&l4pHpdVWO-} zd}kyY^{oEUh#~M)&<1Hvcvd|^P4h=f0H|;YbtatzL>3J!xJ2Un>xVRjoFrIYZ4Z1H zJVTxS&TjJi_W1yR$L5=NE>**X(}-T7VrXOL%YST&%ztOMfR25g#`cB}YjI>O!tZib z1n(9_7?9gR)=@uNt*hdGDT7WAa`kPZn)@(@|CZoI$jW&@xCUBZH$|u82@B5I%w-&P zah{{{_uFe^Px9SeNl7;3HT!&&f1&-F!KOcU6xs(j6cRVSu&&~1ROA# z7$IQP=|+hmB8R7xR9V}C60bUQ^O!d2M^}d5pJXT5)p47dAJlR?>nm)fn(UQxoUb`{ zz_u+CD16t(D<=)VK|dU+LYfE2=G18(tmJ1XeDYqPntoZXLD496LCIS7+>LQk=X>`z zL&gK%iv_j~-(pSbkPdrZ!oMlMo#@Kb=25Nu>+0hTuHc0~N`nqNC0!`ytAaFvnZY$}D=1bbR_U8=X!3EgVDEg0j(x)dmqJNzK_s;ljN{d;m9bDk*St;f|rn-F`J z@%LE?mk(}8WwmOe?K@0vW@InbZw0ctj`v(EI+?XPSJ8&8w^mVwfg830Ge_39NcN2M zNKU;zyuDUv?usM=7KF^>791+8gXc#mEQX6SBSv-xpW#2Jc)1%#+(`$jjXqb4=TfL} zp&x&3zwjE5fhjWYi*<3=C9{Qt#atd|HFkd*V_&nFFFQ1Q54l0wbRseHU6+nO5y=F- zm$|IJoxB^ZOGtG%M>+QKe(n`zhxD6IiLlu&#E&%l?C5qGf@M#JCvGHVF=mz2$^Ty2yD>0;&Y#tL!d!f1UQX)!j^zZ}%?-Uc21Gj8 z6tRQ4ugtq07Ac4CIS&#w%r6HYnUBI!TU<%E3%K)_{LgzC%S;cl+EixOw;iiY)Rp<# zSllleS>Ab@Qu^k0ROo&>g|W?_A9wcSm|Nog!to!dHUwph3K&10d``tfpr;?vx@TD` zExPT=H#RA7C7NPWxsrTf5wh*U z*N>ZbU$$jZMjtc|7;l%fKcQ*zm5a=)3S4*0n`bC3j}RnDCKwZ{=fmbk$g0*+TWm-f z-ld!1wv_uhpxjo|lQr7dzPCUAa-%q$N7J*KQ*-^Q3Q-*LV{22oxkbhNOK#3uWm5ln z{Jkfz3iPSlE5|e%2Zk+e|M`iOO7bE8CgxXvP|QY_D)lTiMxsAV)}K&HLwB3WzRhGq zZ5J44#(8NYZdn^(e~(bbpI1N(ztpLYwY%l(0*%_z*IoASzs8SaY95;o9%OV+(8S+0 z*tjnna6O+GYkwr5`N8an>8*QDI%DWSQNnM*>V${yQn1aJ5~vS`c5eP05(@rs={;w~ zO@{o1dT-sY)@t<<$lDc>O0}JY+pWTjMN||)Tsq(S!vwi*3%=+nc939wvrhXvaH~a0 zZ~AuDP&37xx&g0nCI=jLV&io5<7PcvBmJu-xwJ~+G9iY6SXvtIz~jTTz2N)!k0HE9f$!#h(O`RT;2|e{l3*?!;N`iBdQa& zb5Bz(DGf2vf%_?a!}PNT@dKuM3q+dU-lu=w&9-Z)mu9NwhetRVE$GrP5OiIIYo~r} z*vlt2qkS&`Uuh?kGn&+1l|0Os>YBjZ+xk{T^zq8%<%!=`U3slE8BPkjI|O-n*+*1@ z@5LL^!p~*Pjrd9>z8E=B|77u0F7PG$koA-$QPN$D2b)I=GLD0iBVWChP8$t~&Au8Q z&@xK#*10*C7+-Gt*j9G(g?HJX4ebj-y>bIbY}3gAY}c=p#XIX_cRJAae7@BOd-@O?6A7<6Q=A2(%d z9^D(+=#71)w!RV>!7yI@3mwy!!GgW_zItc=PjAuWA1#+VOP561Dt~{u-NP=HKJ#$j zpkMvVqLyr#bN!4#;=6ZGV^%#v6I^o2A7(yv6V4z@CBojh;P5g;&p25$!kJDvzVBS3 zLGw{#i(qXJquW=H+2P|7P3F7%$d&MW2g*f3j&?o^7p<=GWa=w++fgV@eI4UNx{6l# z5I!7wn6Q?~8Sz73;l5n|-oC;LPn^>g^QlhtTi70$uwH-d3)A2Yg z;E$+;36n#za9Q<*N^aS8lKIga7u*=X?bLD=uXmx?JGW9*z7z*P!Ry@RjV!%|T7?DJ zbtPvV`FFSHhDj>NEfuN^8;fRdWJNq~*gL*c*ZxG1sOHviRbXa^DOS_SO4N6%%pbbK zIUOBHhb3oVf8)DfXQPvORw3!OYHUkH%~L75tNC;$z;=7AsP0|ouFdR3TD`ELZeR6V zAL?Gt`_#+!As>n*@TkN$FLFc^7C3kMPzs1)e)#8b90puhFS4g-sM&`s?G~%PlYwZ#*53CY>HAW zKu&n2Ay=Q(>lKJ?s7^ifWig_dq_9b=GR>*t`ZU0M zw7J%QxvpYamp;M5M|5n%MQM7f##*0tZL7qu)vdX=tpgcQ6&;Gqoz^fpwqH6`!DW zLkAfX%7=}ErD>IN_rGn3ojd$Q4(%S5>%TN*95hhRUxar%y5?2!BgRNODZq;1jL`14 z!zE(Db2pb%hHlosE3x!T_$JLRJz2#tc~Y3jjW&+qLQNM6Jr%E*w{yCm-<9l@cCMX^%axdLbgkv zxXO;kaxee3+v2)`7l7yIcfdjI7g9^et4nlG@OvgbVY6#N(T&9OTU0$nHzc!0hmu>x zLKJ>FOZ9aRgpl@@PZSY~;iuhBK(KdY-ZZ_RepJG8OD56frLTzafP=YNOw=;n8hKOL z!ns{_GrMjb{*#^C-zUawtdPd=kL@d(8b5>)D%?y-m+KM>h+`?x-4wz0a_?Q5WXSoFEQ^Uoxn z&z|SQ6y8068xTDRcVRL5<QqJ2rOQZ(gb5)7JYZ#H=|IY)_8| zO!}q!?b+iVRfH0^Usci~?->S+={XH^eK$Rb_8!_%#IvK5p9VOuwLZSk;TLnOOQ+H> zeJ0T^Zw_l=6)2=2?X?;iQ|z`e9UqWv7Jb@&>5Ya&P4MC`fz}AEcauz^!ul30I|f0M zP1BllTY3z7-tBP%spkB4JzHrOCD`JR1^M;EdQ(?E=zgS~Z@itN%994O9~0Z{-AYBgN^=qW()_tZ zB=@DQU5uRP#TIc@8EiZ$A7)>##mX`@O23cNv&9sJhip%%hshT}QMh;4y0( zhQ^O8tF=wMIV67gkochYkJR?lqMXhog_@f!DtnWcpPu#|xyv!~8GMT35Tw+v+F`AG zPuaq|=hGcPanIkm7JDiYQ1<)XF0^faDh>Vc{jyEBsbKcEMYw`E^rH#e_S1Oh;K*fb z9*<^1=?C~`;mLfsr@thBQz~A;ryax10W)crS^Yi?b{{EA9r@ppw3Sk9PbJ8knD=pU zta@V*?GIZDlb>9XC(Ar9Of@g}qmgM=&<<@FjF!zyuJxp)v=vm@cT%a1M`HfQK z#U>3oi~Vk^wT}mMH1Jc0f?emT#x}VmxB2q;@bPzMgr~jJDYKREpxEy4Yu^D%jG!v!ZMr030JB9UbHIe&Fa`X|$i1KrI^Mb`XfiF0Ff*`PKKYM{VdxF6I z;$^j7MGZ^Kv3Yl=`f!@ytz`BDe;wxqVMF>i4xcZw0pU~Zhajn%+k>rgj+CxG$_(#n zg0jBW2+GVT_Q&^$xVt3^PXE$XY#3o=DyXcvon^SKX1j$ycCs~Ax<~tE^A#sPp*nM# zI{W%{EWF^S8xzIQtK=J*q&e@OuZyk{tCMw9T0Q7af&M>>mPWI>#(;0&CG69*)F3kg L-$0@lIk5i&v@^n` literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Bn2.ogg b/sound/instruments/banjo/Bn2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..3154f97419378d1b32056519afd338865744036d GIT binary patch literal 24458 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 DXm@sD literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Bn4.ogg b/sound/instruments/banjo/Bn4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b0e9a2b3b2f6b3d8e66f778b868255b8ddcf5879 GIT binary patch literal 19891 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≶&#KeKtjQL+9<1eEt)Gj0&jDO$oog{Wv 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 literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Cn3.ogg b/sound/instruments/banjo/Cn3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6ef414d9d01cb6234c73ba9596d45debb7b9a9ac GIT binary patch literal 24724 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®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 literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Cn6.ogg b/sound/instruments/banjo/Cn6.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5cdbbb17cea63ae99dcab45db84a46e2f695b2e5 GIT binary patch literal 12670 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 J#Q_dD{vU_=5AFZ} literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Db3.ogg b/sound/instruments/banjo/Db3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1ebffdf5025dfc538b4bb3c28e779f1b02462b13 GIT binary patch literal 21442 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 literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Db4.ogg b/sound/instruments/banjo/Db4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..5b93936508641e9f05d87b88f89c3c5284f9d5a3 GIT binary patch literal 20334 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 C{|b-* literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Db5.ogg b/sound/instruments/banjo/Db5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6ee4dde94799caaee9c0ec8bd118cad36029b6e7 GIT binary patch literal 22485 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 literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Dn3.ogg b/sound/instruments/banjo/Dn3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..77491b01b8c9782429ea42d1eaf03968893c05fa GIT binary patch literal 21168 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 literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Dn4.ogg b/sound/instruments/banjo/Dn4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..11f68b5a1575b0f22b713f0039bbbe797f6934cb GIT binary patch literal 21865 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 Y`F?i$ZlL5DrI=vizX_Q5ug3?50;LBNRR910 literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Dn5.ogg b/sound/instruments/banjo/Dn5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..2e9ebe49891f6ba74f8cdc9e17e6d5f34173aabb GIT binary patch literal 20948 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 aJUay_*;6v`eBGd64+qxsGXXLFaJG_Yi literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Dn6.ogg b/sound/instruments/banjo/Dn6.ogg new file mode 100644 index 0000000000000000000000000000000000000000..89ae62361dc126632f281ca3d4522126ce6f301b GIT binary patch literal 10611 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 T0k7@oL$|A8O>$_k>id5H!7cTk literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Eb3.ogg b/sound/instruments/banjo/Eb3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1d1e43049d21bfb2e88835f985f5853fb964e8d7 GIT binary patch literal 21159 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 N4j9e`yNc_^Z~(l6<6Zy& literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Eb4.ogg b/sound/instruments/banjo/Eb4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..2722655f5a3adb5fc812e60830ae05cd91534093 GIT binary patch literal 23906 zcmagF2Urx%vp3qaft)jfxa2H3Nm>ykOU_Xck&Gk}K?ex}0wPHyXC&v0uqYWMNm5W2 zK}A7CF`y#e!S_Aq{O`H<`M!CE*`BGH4pqOZuBvW~+}+Ip3jBLma{p7<)L%D%xS$Zf z02hzIqeqZt&A+c)f&LacAfux%|NA)l@`%E^6pW@*{`3DjM$!LNB#O|jJ^U}7GzxIX zd3(56{;eLTi<6d=l9rT~l)(uZ`S^PH2e<{g`34Ce)eT|)`BYfrj3orfkS9_GxIuV2 z#R3320G#=RY0@t03YVo930=)f*EuQ;O2%iU#}Bf(CQ1$c*99kgff)b{fQ87DOWx>u zPAa*x2_^>=DtVk!tiX{bm=Kl7AAJ>Y^(}8H_wt<-<|m`J!2*OYcpdH-Cex#fOB{DB z8*;hD88E_KksClE@}Tf0h4ct6%0T*EY1+9{?;eySpL#FUGOa-=-ZHCaAT@94TKAB| zAv|zW>22=67xKU3z#)CnAYs2ir$Kg9eVlN4Rsd4fKf}TS7#SwezRRTB$TZ%_`DBLA z=(Cs!quh*)mYKPs1#$#CScSMPh6FE$MA&4-*mXqMbi~*##W;MAInNgR@3|kb`u*tq zJ9Hcb3VD?>*M*CDjupRBDn>`g)}X+JBbMOEQ+b3_OLWUGde(X5v|Xxh^BHdv8*ife z`wAjc%u#PZp+|Q4|L44Dlj-(A|c)y0U_#Uv-z*#8Zz|JEFUC{6TVolJL0lp4;B zI;TPYkAVM6b1pLt-{l;=%ctMOXE-bNxmWiyP8MDI-bMR9ZH#2#Mr*dvj zE!^fq+@7_$*|kU5wEe3v|ESICV(@=x&XJ1nC?&7!q+ZbD9qzYWk zbdS%jyr2KBvY6t3Y0jmDimZf+xP-TH$wKj&9`V^#oyFc`bz5Ek*Ym$MM>~KIIT6j# z3gG(>%^^r}oaNM0A57M(R2v`DH^`2)?`v|_^?GvBt-*k(G_$uR7%u5K`EyNRXb9Z z9#icRO@){>4Wg3x6_Rn(kILIQk&gf=@<&-Tox%*^nE-I1GNllXNjIGo zev@K4CiR-rR8OfQ*KAUW?0EE;6iHqbop2ea*`)9=XY|DB*SS&Cr-cB(5g_DGLrC_5 z7N8RZM1Q`iG+BKnetkx*DJHi?M#IGn*(b7cCgv97j283e7RxM#7H#~7jE06^%q!D2Dr=C;go-6}J9RmRW;xm`f0!Hby@P76K`S^rjL$n>`= zd5gt1Ig=m@6AL#Ra|@dgH=FMkRtpjO2-VE+8MB2&o5i!QJ{Fk~Ye5zcR&LL}TiCE% zw_A)^`xddrc2x7?d@w>izus<3Sd)8I zUCmfieRZAp7DBCiP}L+>RV7y4RP(D!Y^&`-Rafm;Q$tQ&^;X+Q%Ew|`UH(;db=6JV zN7Sy`t)a_XU6SGD!sF%D@4G6yx_q~~E>E=iaF$fP?-dz;)G*fcajQ$BC79d9BKSqR z!@3nR4j-p0`F7u9ntYV|YJZI(70m7{P5E(lBA+$;av;x!_C(dsD<+q@XCpnWs?DjY z-fHp{eO$ApVPX;Ckm0tf;9$e*yQ+|Ex0qC1^}b7FyccOmYGufevs;qWVObs_5 z&80}V1JCIVa;6*Wd2*-Ei45V)lXXXO(-`zF38&ARk`|R2>vyV6O&Exj^6p003Ps-6MTD?Po&7*ktssfAoqZ#kq_NL8tN-r_^Hb_T7%bhea# zdsW+N>E&5Fgfz}y#-^{=*vjJNEA{4>o=5Fb_ENR zg*nqCgy8D)a6bFm$Nw6+i>LU|f=lgD<06e2sYv5*p4%oWrO&z`Ri&CHB45~fca~>* zB7|(y+pTY&2YSnWo3pJsYC|8HAp-Aoeziob4vYqPnB1-K$b=lJ?ddqvNnH=RfC(iL za*YWk!O8#w4Pjx6iPL2Kt&>W^!h;J+Wc+0;`Xb_kmR`cb$SA}SzvHjkk{HGhLKM_C zDzb zhB&wsoQOZ?J)LgNiFD{6JK{{`LM0W83o@4$p^rAu6ReCxI9eNwK%s1K!q&64WeHDK z8?zv-&yPUiV(mbdE#kp$BOTiQYe)D&3Ms&|l_2dZxzo8!C~b1eB9@Uennq+OH;P7s zj2Y<$GFMF~As0Fggn;;aMN!D5EPeKfV5;{HhddK53pygCn^FKE;*WSl4JH=?Z{96L zY$gg^J+hg4N~A^UXN8Aw>8YkjbI6b?1E>(*4O$)%(rveK2sFIqLg)}!4cVU2s~xoV zs^czOaH)}7L_pm7CfiF7A$UFM1YiYA3L4NHTJnNyc{tg1hA#6;Pie++1kb0YY zhD>-c3-NKv*^XQfWRgAdKN1lFayx_&l-_b4U2+4H|Hm=;pAz~1&mbxhKa1WHnXQM| zILQ9-%Fi<2e*GbR%=k`B*_W$wT|4$`5uUZ6h|9JuUJ_=Ishm^xoTT%EJrP$FJ z>1Yr~?{OB=W0K?1vBI0B(TI48&gdx#@gpb^7DnKMXmq-*-u*yRQxX2M%p=n=XR9ZU z)J@7?wqWXsv~r59tYz+~sio68!etA#x5W{a(?f1u66In|kyi$nTxz6BXH60PWOJ=S z6v);K>AIJ=aO;9gVk^Rb#6m2%+?HFgr36G@e*o(=T#n5sZGJRE{3~m2#M##P%k87U zz!Z^1;SpN6HT4iw9btq!8WF=k&!SWQ`x)J-xBoy30o2=n-b**u_zNwvBIKFyaRg*S ze@pyGiToc2?k^al84y=49jW=BXXy+`8-Lxqbkie5BCI(g{Dtb@5;^w~yZ*k+{m-{Y zz90fo^pO?j-Q+7797y7&8JJ1F`1cqZRWZpni%D|>PbDWNw?G!x_fgrpr$os0*NSbWI&RRTP6|@F|myx z4Mk&wL16=7TFM@S*G|oEtWx{SZN=JxrGuMJpRy=V zUdU=y!vra<Hu&qf!QpE zTKz046a1}6A;!Dw&ZF;!eiT%1X|mNl7ld{{KB1swxi44_`(rok zyh9Rd|MVLY*5mn{-dkIr$o(pZR~@_vppTr6CyGo%mG^Q zpo-IW@(O#m=Hy*XSkjDRO022gF*cvNG76vI?1m}nU;XSy^9dMEJuz)(DRBP$m`a*p zOu5FCs+RrkV9p@-^z&(3iHs!(1pTPH(YT79YV6TiG?d)u9%v0aF>b}xh(OKjhg%@kAZS$)0yz1Ziq79f1 z53Vi08M5!Z^YfcAi)loN;&iOpJr7$lPp5O<2^(#{U*F`XAswZ;j1S(ukq2ptL?|q0 znO`lX3OKX?)Y-3ZoR3wmw0`$=mNCMqWZ}3ES$o~!@aXjex-k2iyP%2AJ0Zi1mWHO zu$SzQ;d-qs!sF^l>bk)=GoL7K;K=e~W0%2|>otF?#=NdNnW}J{@RB;IwKpa&hoHGm z4G<70sTeyFNM|7yQhkf;*nwMG_wX1$sg2!51HE?NngOB+sos_*6F-+w@=249m1=$ z{t}Xcq5jUOo3#)LTy6*A-}>VNe@EX6A_VDlnNRq%dR;$v);16)w-8PQh2A-U;CmZv zl7cKUQ2vVWL>w4{P$(3Vyp9G!;A_nBLOkOib<{bT%TS?VD@qcma|0uDKx71m#Eb*r zF9Ledfk59N5fRJFWCpPB05hn;rmlvO{7VTk2KE$Hkxc*}3;g5U@eok^&UrR>%I%wW zN#^lSdKu?_pbuYC8cgdqZpWAESwzeUH(xj**MRv{ zLj&4;FraWq3{0a?&MO!|0s648GcDmA2k3=%wMh|qXCjW%%U@!6=Swk{(7U225V{On zbPzNgU_k-O83l(DCFrn)Xu`4y3KUQ!(h2D#V`a~a$_uCoZ${mGwD4$|;v{e!=EN+1 zAN*FLIv~SquHHYohISNy3@F0Ux6#K#S1_k=r0~fGK*XMs)Yk^aRoCo(ij3)@1G3M& zihTTn1vHeA04{elPMCrq3s%^`HmwkVK#e5`u>=B!kOIVZ195YJ|FGj}&|<>@6etJ^ zAR5A_qi`k2lteTF4J76u6YR?)Gg0sHa0VeV`9jD}Sd#qGME1+kn>6x0C_3QyofE#d z7a%js^5WUu(72J4tlhL70%%5b;7vcyEW$eQ!gEc-x@X>WoY#lq5~F!rvB~_2K1s92 z`uGqskcdMOq)EX;3^2kL+C$c}5FXm~f#5uH!nzdbfC^t81HRZoS`v5__-mn3Ac-X? zgt<-N0`LX?Ed1bBumI{i;tBn*1iLiOSlP(N{Zj%5J#P}BC|DChME&T__rce0;bX4a z)~>A0t!l(QJGwN~3BoHpDHjJ3ZRkt`(*@QD!KtUT2Ok)+@U_%lrFV%8>0t$9s#y3k z2l&bl*eD3fqM)K5!RDM9tPRM%;n742XkU$XmwJv9rh~Px;3Np8h5TXc5(>YED%3N7ery043n%bUsPDsZAG~NfB{Y0R0JveD4@lsX;IJHE2-4m`A(6BcB0y0FoaO_n z&$dUSH{{@hFko-^jbysCvrXc7?{$6`t{qEvs|OEF6)$81wV@ThgVwfZgO7WM147@^ zD3t8b0&s{COUB@yQQ#WjsAztKe}FiPrv?o-?vnszc`U3~0=`0E0R>xw{X@jZC){g5 z5&D?n2r0jWF)4C>=~PO7V_Kkt-o382%c>(ra0TDoVC8K)%3(dOV5EAO6Rx1TrQpsNe?I%|Hzk ztf~x(ix9&ow7Uu7n88^r5y?UAlfaaUvS1d_$?a-IR+&tmzC7#;;qLMVYM6jqa<4D^3L+SQQTGlo9U+bZcI*&d23vSi8BtH-?c?Ci zErx&F&Bg5}nT=`XBCwBFNHW|n-Ur9N9S>HDNC3QG%SEK$z zb~s+ppCpvJVKkDIhJ)B8z(x=mpJ3XQf5dp~dMN&U771|nD}e}gWWc$d9Q>&Ql32o& z0m!66n7BkSJx2pD#ZU(o;VTJv1qx$;iV0{iLTpZtHUNc>+fjge7yc95r1U{6rUc{D zu$XvQc6wd(wD0-S$+ge=A;T>SF%)*fC%bNB**50s?ihpo%oXFq-wwV4j-S2PZrr&z z^&8S7suA>2qmksCG`lb-SqcXTD78p{f=LlX+Jt0JKdN9jiFAi%me9jQXM84o81u0bQXfSjZG@LU5 zHo*5J3XfPrW@IkRY{6Id`56`3MiVkRMON=Wu?_r&lJ;*uHD*Dj7F4!;A)|8I?gtGyc$u+6 zw%>X3WJQGqXZtO(X3?wE`IH@`GS)3u4cf@<7cn(6wo)*?j(ABIO<=W+cWV)|2pynTaWsr0GvI34vFJ z?BHjE-POH1MZ44YYd6nxPWLbs+I?b8_#m1pUh}y!q?2q#@|*`t&cg=jv)y?yA1_oVoCy zaUJmc3UeqHSeKFEf4u`L%)qo3s7wMF5d6?^9>5ubb9u`A(8W$PC@ zqjm;EVBP2hSbWUvoqz#UeAvBZ#qPH|fi#7a%Y&-tY$eauCE5x^?Uy;~n1sjs{CxUz z2p?L=$@3u;5sK3T#sEL`}IBlZJO48$_YA zVK>VJ;lgq`TYBvr3`lM>1#}$20Pl=~g}~bokoyL}D1rd78|Q4solId!ySW`wynq?uo`Sd zBq7}8-0h&@#GwuExn8_Tks@kIbwQ;7MR;-=3q}b@=$#4(AAG>veRKmY{$V?W+h9c; zhnnN?B_K%ym|;>vfi@6>h#3%Ku6}~>RSrA~gj3@FbYSj+1_{YTZb`~+A-7B~*%Ft? z@=FJIeJ}p`;oimR=jC^9aB$wgpC(M=eBH;o459aGr_8p00LKu7sUMHs;#b|^z7zCr z;Uw3ILXjmWs2(EfaD{qbsQFVl3z`p+u3 z_A#CFf3>Dx^q}6Y;G)??)vT#OuPs@x5ZmS!1vA!?r34$b*YlMGLb}OW_vg36l-+{O z?cEcW-mG^>4}OE*#xsFjN6sPvf76~I(ti_5NwtXHMU`?WG0XTv z-)qh4fh_gaEsbp*ojn5&`}+F2d%6j|{e6Ufu8W+gzVDa49j^XR{9HroCD(UD%~=$7 zLKnb;^xN<-Nk=5ckkE8-kV&U0n&7*!3r4=XabR?M4IzRa3CI=(YZ1_HIS3x7Af!?t z_O%zH!V(}6V8jGAIDjH6U_xo02fe)1Lg+`|&!WzK*a7AzWYS9FzZTAv$?Yv&ZVNH} zpyzh_-4M^Dz=$HPBYHPvf$n=-gs@EA-bD|BN%!v7C55EA469>J<^bt#?4dWS>(-Fx zi$@>tgpAak_yp%i)@Pk=j?`r}xY<*{d*8;SP_pwaB7hs?rSD}zz-38DM2X& zGG!_7XvBxQUW_6BG6#}ClLUlo13cgEDonb21z7VDx}LyTpM^F{F+0quH-d6m-V|`J z4}(x4k4E-~v1dIZo_HVmtG7!m+Y$r%X#}#TcLbLc9jwF@A3k)A5W=Q~IbFQdiY_BR z>gtBP#0U9L`cAUyw7x!zIpN2CVpg!dk%N&mI&Cy$viY}bg5yw1^~Nb*Em(j6ngNWt zVZm!n4EzEI_?SUHfX|zN8WaqS-NEj0u)6{q;rZZ?4^Gq#po z8V^%`_o-oMfm-s(MV6DnBwQC)gg)KK937KZe=YDzbf2UD-VjUgmVD%V~62bK*Hv}%b|nX^`k;U zt3lYxun={rxKj4OZ{fMc;XK} z9@9>F%A`wWySOs1@f3AQ^yJKB4&9l~`YHC+E6F#WEMt$DeD=U0Szzo)2@!or@eymt!U7SQ zlz&4AY@I3gLlA%G$O)@+B{CYH!wGie(sd~9hL%hFRr zI7A(ucNhGOB5$34ywSM>>+ip#V8opsU$-k4ftuXnb} zZ;g;%Pek_pe$_M=@UDVv>MngaJ*_b|%jM1+GA>0V48?qo=geqJKzT5x59~>i0@(rd zmvjg|_8dKZ6C^Gm^DQ{61!93rFbZctg=idM5B9?;5&C9;GuVgVD`?#UX${Bnys1lu znzC+~Y}(<}3c8haA(*x_XKL$Kif#xwX&@pcb8bmb!n*wBPbQ~7O?lOR0B%g{R_<>M! zAc7`Jp#ic%=L*lBi@aJoCt{)Q#mZGI}SS zF!^e_h~96gc|A2C?fI%NCMM?j5=+^j!iLJ{XG!r3GYqm;f^)@A0~vvt2_9`oLgFGP z{AVYG!+~VP=xXWS^8?p#xC+lqG(((CQW`r_3?uHNc5Qkvlkx8bo9&@p2;LjNiTbn- z0YVM{Ay>h^AXq{sJzF4j4FW(18nXmKFdgiNZa{^j??RNYx)xR-qmY?w)loe|T006p zxthnyzgtIe>*5~OX_~b7oi+3P{$(ax%tgw`nWw4B9jaL02$f%)tR=w z{SvZf{^)H<*qq5vl~9t9LaIYCB!#SoK>W{lxsjHgd;y8@nP&(7DnxeJvvH{9E)kH% zMS|Lzw1G>85OX_IavcOl3nY)nRZxNJY!t@iSmJ5;g#bV@MV`RF2}QsG0|Wo?su>MS8+P}!|DwVy{fN2veZ}7h)n^tI9vSb zvN58}UfWs#=XjT=bG6B6-ltqAaXZuxF=LI^hAK_eg8X#+6 z0@w_vko6=kpt1wutRP%9(7XmhqL9Tz;z`NpXc&;e*Z9C9AhLoHIMOQVjZ42y=v@tl zM7r4fLVL+`RuiGgT?~9(OXWGE;`JT2_tH*Z>3Y(3f9^o~*3$xu3&Ye_oNJxd2XA3b z?g!VOkhLbi57)N8QqRInd@&UII-gD^yZ-wURj9rn0v@XVsgySR*9x&@Mnyk&_mK&Q z(U>oVvmb+5#spn`w%BWyjnX^AT-tUA;E!zy0S#UN#D(CC6!2NlVFDJ~z?>MesceY} zHC>E>g&>6Uh+92%w26)ki%+@)*Gqm>I;%x%5q22H|GnqAf~Pq54xV?EDQR9O@b;Ha z%tUIL)*n$&bFF5rp#+!lg5{;`jWBh2TJ4Cj<(7^uN988bB4g+tbIY*w!ZYpB@?bDd zYLe|~9DkMUNNHa^QSj0bKk+EjYI0hpU>#j2L--rHOe+x}Dw>gd@z2Thp^t!vmmdoY zBX*sg2?C2M6i0#JEGjn^>82V48c7RL1XskJD5QjMoCSce2>dC*4xh6&Fpp0CUiSNx zBRTKoBGyuV89~>nSDj^hI<{Igk5<30)*h?2yd3z@@4-FVt}prdcQZ2i)8ngXw4!U@ zI$IP)Q+;-odFOO1@@u)?cBma;M2=<wx4wyLBUSV$q5W{_S5)+8Nw4rAAvA zxGcg=yxAYCKTjw}@`Fd*zj5XB^gY^jmP)fz5kKGxlF3Nc!pnTHHX{|WI5#wt2@E6v zOHKx;kb;TK*n}I5Se*psv8Xv#&`<$h1JLuD6kt0XAs8awpzu81{K%;=ce=K-ucBm` z?1jRYuzJM%y;cUN?SOhc3$#NofY(eDa1V1x||{Z?d(c*q^&?>bs+<3tpVV64~E@UKwcV1w^1l zCH{c$he^B+`{bsz z)CSMTD-;aXrcAilHhM6f5HQ2FbV&>!+Ka!EdopI#;xkyKI~`^i+_+}P6d&bz`lpK;-zf zlb$8Q#OeWCIeOFgkzS`cVuV6a9d_W72q>dLlBc=P(4Zp;)xk75i6q4F;TZ6d#F@N@ zEEKPF^P`>b_U8GHLi@V4d7Us`*SdG}vW&c=2;8C3|LMq;WtiXrO(QPiR`gY3Nzp!=+yS2C0qtD}w7Zou+4PA?aZC1(X`3cClq} zb=Z2b>|XQhXKybj(Xv$;ZuSw-gh*0n^Z_2_{`_-H8&lk`nkxaxf^bYkpAb~2QUHNY z5dgnXL9+eeCTe;cvSvV%A`PVJMPLI10mS3EtpNrg7;Vj;`mWn2gVm5-BbMSDIS0F4 z5*?2qwOfnW{pmGVUe!iE-Y{L&cRIV_+~QQR3*y}_-;U??8+B~Ue<-5+kzsH3?6u28 zW{q%hK+*Nas;jE?0|cJQ+JkoD1`YMC+mQn#YHpk~haXHyK75v8udY%dPC0>snY0}M zx}0H=iU=QO?Ad`+URPc+#SC`)RD+x*ij-zjXU3DXG9(^L`jB8)182$duw z>JW~@m^yTZrufIA?pbTe>8Cz!v9+E|Ws;fWKK2Jc#f#f?DNn~up6!dMESNpajMwLW z{55jCfTvv~uJ6{Rcl4j_tY#qplWs~47w;B-KOIo87CZSQ=XveJ%+noTp(sNK(Y1Tt zjBJ}H&}Otp=BA|p;K7A64_VAnkz>{0?MP=O^Bpm0VoMWJG7>Fbu(x2zs> zy_4q`D@fT{dF7t!=V3&uUsyW33Z#RcFO}tk%lF+jt+Zwt7ZWYGug0FSMT44`8v0jgJUx-Dxaai!1HZMF`1D?|w60{Z|Mpphi%0X--TF~b?tAQ^W6OrpU7I~Lp~ z5rK6iC++U)c8gsy(A88S1imcLS7fw3tuE4xVr(q@E|y-h(y21?O+UpkB-eWZ{h1ih zZJeBprnyJAq>eT9*Y*AlvO9p?Y z0S$I&LNM4w5w1}JR{^BsMi4Op1$z@Ta3uQ*NMVq$l(Fzek%y}KS$Y1MW?ZM74Iiud z$%>lFhcxSZPsko=Rn^2iCVb6R(6e8DIPYflC7cX(h&t0|u*D}h!8@nztl)I6f?;lz z>W%pUKiA5Xvm(8RvPDJ0%r`Tychavy{W#Cgo&*185U3D07dehH2pHtItxKYSW#CbN z|HFsF4+;Gvj~?}Qj*Jd>KJFVp?A20%!dl%dhgLM}kYa5(VS&KJhEiG5NrrG)px23i zSqMzG={yL&g#lUGv_Ov+0|$&^K`Xk@5lsh*j{{$n%JV3YfPl^aHVWQC8iW^jsf6x) zm=7&`xyePl2HmrHqAK4$e!ciLpPUS(eXpVMUa;sPzp1SI>aWwEyz1-)eo_W3yqIHq zI`zWYI4`(GxPYe@!~ab)@AukbXCaCC(yO0pd&b{3d_O)o_R}NtWHa{4yj1sdJ7X$W zhCoDWe6JS;(<+twTIzRcAD>dg31F+RT+Ww?P`^CXkBPfJ>YZ2&;(zgs==Z^dn>iI3 zlSM1u$gXh>AVf+?!xHjQbRQrg4#dmr!0k|;jO;M4@f+*5fT&kddvEUGvKB+uAzhtcKwqe{VVKNk`Jm{o(srYEDSRiF7+KCItxhe`B*x=k>MW4rk{y z$X1FU(e+(lH+6Xb?u~Q{MOEWhO|!bMVebS7?zm;&nGYZl8#tP*U#*V65I!+xH?U|- zH9;EQgGE*t8NCCDVDlz9UF$uzT59a28}H(C2QI~J7CDfy>y<8>1K5rRn3I67E08hd z>_ZBYue_@*1QEW7%nztRk0wN*KvE;xlW$d`ws2gx)mzK=r&CZzioa6dKF6n;h)6(NATu0qNtuhahcBR)PT?7#MDJrp z9^-g+ojt|zQJ+|*+RITT3_3`r!5=RKOHsmq&<&-?p7a{&Y@PAwjPQureoK#8Z_ zC_!>-is#wxODJ>Q920SxDR(7FVY2>dWkb(haCiA)c5AMYYuRGiHMVCAD+F=d^A@P8Z^0{rkh|hOg zVF5~QHKvJ}KLT3q*M`z=oO(Tfef?_N?Ber^(vjZ{CH!_zQIzYy*Xkwx{&1i~E|B6Y zgZBj(?E~liXKpaDJ=z%+O*g;8*Uoke)~uCCLAcMi@#|!ZPG5EVE-k4{4w8=uWeo+R zku)kKvScCnMDAe?a*A}4@_1?YWMiGKtCl6vgh4SBkd8(@2m%+VffSg_L8X|LF6IC@ z<59r{3iIy*6d&s$XAlx8f%SBj;TSx7#hUK^@|%QlO7WqFV+;G^J9V2qM30~vBJQar zvtRha>vqd*!RlR)9B$U4TiEZ*q@R!-)~xlL34{GiP_SYdl9 zsnoI|fuR|}KIYAypR7(_b4(b?{Ztj=IyUr#XcmnDVpwjG^wa3LDSf1@6~eC%NCX;P zq;_oi^7!k`pqg(K`^p^1qBycN6N-UPSOOkEq@e!6Vsh{KJ(^H0Y%g=aLoo%m52Mnt zOckyxcTL&yhvY)x#8vZho7E3YnwJNztEHx$l8X@ya2(yu`}xHs)TAH~(_kW0a<%&e z*H@wKBB|b2tsnLmDJVSEJU@uGsFlQu>V=9%XPVb)Ua+&u^DFF(`c2lo`;9j2!etV~ z2z_0=r#Du$%+sUT=hlINL}c^j8E|hxF4!n2a?i8qRM;l9M%B{cyGN*C&DN zw;?)aIE1y(gyE_Tk{R4@!zM74!7fP76TND+!X z_5#rDmegcSC!pE{DQD!r$%lp=@VnXX8R@VU6fV;nz6E$VLv|Ums>2ge$NihuBvq z&4y~fWzjtl-I4-%um167~^0bEcYbbK!!9E)PzZSR?i6`>KS%Gly^KnhmP4I>(LnZR^IsXQv|#UKwUo&G_u0 z`bb?2v7gj+3ea`xaFCR=!7j<2g}I*C`_$HqXi;HlPW`*vGAtmxna6Z`zgHAR$4?3} zqfz^}PzCP~vB$%s2>C8$E2NXG`N^FpD0XaXQ&uA{MuexGI;m`Z|wk9;{yoqHwm za@k}DH@qG<^YvyPot73ocVktSkN9z}hup6enB^~V7vZ&eGsA@gX#jG zB_P6w2Z!kBWWu7xOhO(z@u`mF0cbVgTbww_*U3I4Xnqj8-In1`P`&bDzj`+8iml%MW^v~c~ty`v1p~7PpM%PM? zEYZp@hi10Ef%aV)q02W(y@QcJ{-!T_lMfmxYqiiYhT~kQN<0l!L~4`V6LjwMpJK(! zi-K-Lkir7qE4SXO5=z&+L_$;r#6C)ZqmRDTRoSC`Us6x-t?yjs>`1=&AMHD)XVt8! zMIDZpUU@wv+%7(rn!Yl!dQo2e+@}mneQjfll{b6xG2D*@o?`@zBrJVrAH=hn( zm_R+RmapGgNQj|erEj5|wq+@)C9hVhUn*zbGG2ItEMk=IJk$=&Fv;WLN~YkNHY4_0 zM^Oj0(WLmF)Aore!rKJ?o|QAM655v1o}0c9;O)Oqq}mEOuTTM9c#r}VlQ~%VTL52r zz?S=i9@Su+skYnjF}sb?Mp-sz#C>lsgW(zX&W#Eaeg*W5lYy_|Ok}r$|G5BZfr%?| zE6XbzWFO+x4LD8z{3JG1iK-=9t2!}rGO9LpiJekPjd7?;F4|bLP+pbqBBF9+GJQ+e z#NDVQx`-+Wa4bPIY$TNrH3t-((Y|nHg3t{uouHs|^h&el+@5hg!hSZI@ z+h*_Q#-r3SebGsf<0d1=ID-k0!tiv_;yP z2h$7V5(rPDp5?W%zFiO$X3MJNc`U*GM}qpkOy9)r^TMyH3Uw~$c0R>BWFG5Ct)o0k zr)9Wzyz`m+=ts&eANyBy#!4xF)Z*ejMDAuQhKxLtchTjN-Q(ceS#_DvY5%B{i$-D~ zH@@Ai&+jH~wfb}2W(+6DNR8;C?h^aoL_*k7Xu~bF(&Xj|ixhPI zVVOaNj6!fu1bEK~%3=zNxLnN934Y{ddKf?I9k3k_h+)(qzNyJbi$3!k?Cu`Ila$U} zC$l`0me0=@VLkS+(q!&jo%WWk{Y|s|p9ir{COwX@;njIIK7O_*Z`6|~w=xgqPVWB@ z4?xF!?%g}~iZrCUzCFis*u8dYX3pHz^6va?)#l@u%vxV*UGw{cB0n0)yRG-)Y<=Wu zYDA$o==^K2CrlaYj{zOzcqo40X};Wo381gMEW>J2ri0IxZ&sPwFV(R@**NF}>sc&} z1pg1fS2LheJUdY2A1za~mgc8#PX9?DqTuCX<8PUtH)91(Mcq~Fu$f|${oL$G@p#V5 zLu$RnludT6@Euj%7xloEl4o<29I4Ofr}*>Yu5~Fl@APDZ@8&+M^h3K|nTold2G+?1 zsWLyrUSxYN&-~-Mv1o}}$AEXUqDT1VmEzr4RTxp{3-7M_Wz65~CI6G1#?3XIhH@XK z%7(b|%wH_hD&*_sRfVy4njmOuwTeUgDUkN!?er|NdSfKmiLCmYfl+l7t!;UMFl5H#PI zwW;ruD5&@T2k#l;^XqG(Cx6m@>Fsho-yt9DWa1s9|6#Vz9#vJt_{w%lgPOQK5mq9R z+2d7yx)4I_(7{{x8%+$-(Ko0EWGB#d?F7|O*%ttpF(6VRX9n-+@|(^Jw(PcWCs4l} z3wKGt-*Bg-EYkL+jk{@OPW&wgdQh+$;zmRJ$s`L5gfjDSk3VzsCQ*(&WFx1t>~8h> zHrl!2ud!Cl-T$QIqG#YW+Zcv!;!9EqRya@kvwc)5pj}~G{%%ZllJx0?ia`mFoqRo> zvl0%_*-2t{m7QwWOY!rg+v{@ruai<+@bzix(mEGSjOo>K!`@Yf5*1EaY#~ zR+9hmFI|U}bcw9c)3Y~g(WqV;Emw>#^iHX(mDP!5Abu)ZX5|Wsg^>Yhc z3M$bG9f-Nw8ukLtDC|@eb+@^Y4I@#!rTB!z*WQX$DNV&OCA4=>|tVGO(}1o^Yw zq@g1DvvN$h=<`?Kjj#lv;+$98IZJ!{#%IN>H>*!%73fRLKgno3g&r$6<1QstR_d;w z%bN|>6Es@mk}0jucNCW}T(7^ytnm|d_u%{um2{5O+|ON(r!GXYe>fK5&gbo_CbZrZ zQuF9+Kgp_(r;tcixGU=4jE3|7WHgW{9T>K#_c0H3KOXGwe*AD`d~mdXpl^^c@OXIq zXv{x9REQ)6FdpiqY#{&NGTaiWi?32C{@Aj>1kxcZ4X^d0)toNItL|t*Dhc=u#U*%h z+}8_g);2S+mTM<uF8+)3+|xeM ziS+tk4M`hJU%mB>KX@NHUQzs6BOdEK^(k-XeNTC1OzFpT%lpmN%4OCj+T%Q**uPHc zG_+FQ=NWa5<8V93kLvLcNE9!;>6AB`DuKV;7eascJmY)m;%pLT0dlpA>4zcps`vZ0 zvdOdsq>LVaMIBH`w$T^vjSE-Q8Z%9+lk%y7`IwW=>_JRctck~7YL@p-q<{zGo8teso*XpJVer6d;X_0tivJ+DeRu-kjA8OREp!wY?>Pm-% zOy#7W=f@qC>d!9@ML=&m>|&%Jn_Z8;W`w8Sp-5n6U#47U-w58O?-wI0&>hzL)^UE4 zDXiP)wy1NJ#%8K|zg7nSv3zf1B%Yf)Jp7U-N7@+Q;Fv;$9OR1r+&&{k;Lb=0;6KZu z1xe+f5vT4;5(;K}VXj{%D4_84OzETh;xL*}f&%u)9u$%Xc@i>`K|k5_jSky|v;*Id zw+q>iM{d;jvoT9iN!(>wX8lSjxo!GlkMTHT7(@Awc09;iB1{}Ygu$Bc2}^!ynz3CUL};NuB>5kOED}ff9+1S3`*~S zxuQgO#%%D-RXEPf9xRcAuV|1AM*2`NwQrZmX5Tv9a^DkGE3uUC?|pS=EygPxe^Qbu zcjv*OkB^mK=9<3bW|pe=v(>@MLsu$+wWi%R>~rF=By@$SN5rGyBwIPRC9yECZ{LJ2 z8x=V(K61NBFR&BMYG~br&-IrJ$d78;PJU|4<{6x{P8%#+QF}Wg>2_V7Rcjft{-Jg; zXeVr5?~S0@0P9Jy#2;`iO*odNqXD`AHa@%gq`OcE-R0#!Mlq48(;f2d9et`uT>yAs zMFKK|u)8P7WIY}nZaO+Lp=wbZ1*a|j=O26>i{A7ulGxiSz7kZOS+rfNV=cvvF>Ic= zrp7_pa?WF?H}7ZiPVb{PK52SqIeLq~v0!Yzp%~jTx=+*u`zp1PaH%um)dC~LWBth0 z=N4`52PbiBTpjuPa9Pp&T2X0*)PV42ceqZsVtv+Fg7WcGFE5zyHcu%F_vw$^0V2p= zc5E-QzfmvK(8EU#OJ|G99LP+t{raLhRn1pAc_V}D@Fj{62sKEc@hE%}3RmE&{Pf=M zynYLc)gro9JCkFy*xX9ThWgwx)FlyufFv3Ff|kMg+1gzm%0O-#+wW3v(RZc6s@XMr zyL)nHAJm-NT#vr=V%)&=PZ3pA`?3$E#d+E=aeg{!zorPM^UJgQw$Z(8IsHfA`H-5b3%ml7>+so}%2xa*`ZBO-i8M(oCLYFNZ50zBKCc zv$1K>@>xi3-T1yI8KjeI2MO7MgHy;JmUIUk-u#!1MJ%fHrpAZt-#(;k`6r(GHphR} z3#Hu|@DcHO)|?${$aCVfTxCLAes_A3!gr01+>rM9TL*8h^anG1h92>nipflKUCJlg zjj!IlvniS`#`rwr*u=sk<=wOKbphN7sT9l5S^5tichY1z)1|r*w>tRs%5T2$r$2Mx z|0e<${pbcBX4L-n>31-GDTKNr!~=Gc3GT(CTYyPbG-Zq?6$54I)1xAHy(W6t$Y2sC zU3}k0++A)1z?cO98vq>qtU)`?XFF=l+zDWC?P1Nf|C-%Ozzn%tA_Gk@Es6wK1?ayb zh{%3smS*Mt3j>^=t0OE8(>=fX=2RwxfNOXdDOsK{npn*LcN#N8d0km|j0{InZ)WrM z*_q!<1lcL{EX4!#>kx#pQ&S4JidBJ49rfW9%_j_Qx$Icst^hUwUS-7ecAh)+;~|2S z57-)*3;+}y=m1o{T$QJ_W&kXObq9{X!fNIkMN#?AS^mg*tLGXVfSYpwWVQk@0>Do} z5p_iuG(84=TjT)YsNc7Hi_BIk-X!%`HNAD$ImGLAE{C*~b<}V>kGF0Y=3f7P4X%TmTmk3JDob2kGy>@koF2&z! z1+#lkO{IAzwyt#<@Jz3?MCAx7t!UMzw30!YU+5?R9%ZETw$*gThlXJ>59qT6m>7qV zBbmUX+KSq9(P#=FUXEn=*E0yINb#hK7N*=rH?+zhP6^-=(>OqUO#na?%6B>Mh>u}} zpkSJR_alN0NkgbGBS${Hc1lUICHE8!x`(42rf#XJ{e$*{3&qG;0a#Fg`UC(2fbS5`#Q_w3!n?cNR0&x~ z$e(u$h*h6_IU-=^6FF7!BuB*b!h^OXJt#@I70|bY#*KbIYO6Q&g;Rk>cBv|_WA3&Y zNWUs!jSUo5qy~OE;t#skrE1*n67oB+vDJvkAas_(L8{9X8=e}ry)q+Rp4_XSdy#Ae zekw70uXRjw4ZX5C5N-AbK4xs`_(luHhd}rTjWd4$0IH}6IML7|T0H7Qwjr#zRQ`Aay%`-Tkh@>L-ngzuG+#?yoo{1e3-N_5HHp>iZCHu7s zSR6**Xm+DM)N;t1Tb~eiDGJt~CNNU%+D7AVJX2Z!5UE*Aq@wmjfUJFiXyQS2eV;@_ zvlv_Z5it|@{ZegI9QMy8gn7)XkID*yls;^KE|pL0)m|*Ev@V=*ZJ}-?KuBGTMoSOS zxmcYersGrN0X}9d>3pxALV7`jhhdoycy0;q0RRs+a8wdy=d=+_0m=~T-7#q>vQBaq z;v|e?-;S`7`o=e^0FitE^uGXqeb~v?quTe?6uEAJZfBHKJ3|^6(UCbO z4Ug8%HCO5`c59y3R$>K}W7lydv7 zm5eIkFbsbH008(-Hh}Vtb5VOjPykqEz*Mf%q~f(5Q4-WvIEskl02KcLpc+NZ>aVt& zthANE=}ZZ_4D5>ZnD!n4Vl;XDi|^TL92c!9ca`kDi6oTGI9Hvg5T(|5C$wGZ_b#?A zLge{p8`RLxw%rmt;jc$Uc?>f5EL<2r%Eb+Yh3d%2y2rmv89?&yz z2e4=ZlO$FdPiRt8KwOFe#JD*i#Nr^HX7-R9pBp<&W)rjIJ4xr%<_ zX=a2P-g3vBUZ%13qDPmYK`>}Sr&>ZDbqrC>>5}&;$QIgJ#4}D|TJh)QI2x!Vmh*KS z95!0#WAlwS-Wpa0Q^l#naiF$tPUPWs$Qv2;bF_|siQLWrB=vVLIPfFVHdgykiM3Iu1|l6ado!$Pb9)?tnjyj%u`)P>BL#-2ku!dxHxoPB*&5 z34!4g@{h~pW1&-B(5ChCx4sU`l6;oaxLw|RMowwA>(6pcG-J9U zzUQc#fG(6hz{(VzcuhbKJt*`i2Ya3VGX-VnU7=8Ai4Tp2>E^-GdJx49VZZt3q|xM9z_9tkstG9$$p_{WJ8(GZ2Q;Emab;5oFp4pIhx*InL0A`^;@A;H0^t%}uq$j=;6JyFuCxh@CV|KijJHE8NG) z%D|6R>|*baCiSj02WYN0V54EI*b3`xTEJLvF##TCEOmSJ9<<*j!fziI@PM8S_SXP5 zfNEkH=RBn;VE2{OdmA{63#jbXZmPs3`6qO6-qI>S83GV~E7~jRG|e>%6-+>Ms1Pa* zJ>d_!7SJfi>uG42rEp~gLQjsWoYkHje>p8a(d)OjmrqsHm$u@OWuE|cVQ7TS3-+Id z*KF+D-&io4bG?3LdJd}F_$_}@l_U8cO89Ilhv+&jSkOK^T+ZZF8|FcDRWd6NLQN&v z#jRvQUUsFh#uHT_S{JMo06u0c>3p9aLi?}@zk>$g0oMum3K;9ElB#GNI|_J3%Xs&+ zzF1|%$#U*sy(#k)R@P(d=*i)L3P1z^{83CK%7i@;En3A%vQwrwiRuf(F@_y)zNE5vscCn?-v z-X6|QYDUmvJCbF`80>(2ZCg!L8U=3zHSXw^#kBSG{e^N(P!%PGy$_} z4UMb{$~F!FK4vWKcxn~xLm5Jy-~*1z1YZDv3r$s35{)*30_i@b)IJXuAh1EPy{^Y4 zx4zm5DT0*)gCfB7CQXw6>#X@*=6~}Z?_H2*O$>#Abo?md%hrFN!vI}Gj^(6EeewY zwIvEqXJ=CY1c09b0000009GLY00sa602;b^PY}SvxW~W6!ok79$j8LL!nQtUEamd_ z9(Wl}KMZheacq9)q&A>ps1*rtMHK+P z3cYyE>P|@pm+lAPgiUZuNV0uF~ zDhw($u0|}5V2%~^>>_&QlxmB;v@y=grP0vqBLF^TEdBVlQ-og%VcQ{iKvxssUO>@R zRbsSNN>P9s#a)>GeCU;^nBpXBS!L?eeAXF5y`S3%z#;+QEv?aEDuU}5^q#FbiswWc z9mPhY{e#7Pw}w$)fi(IW-K9?a8nDo1iufi0=Zr%90}3x8?p{zgvJ=NY}F4lvN5UsomE9gbaLwlPCYmXIP2h`0&^-3^oh3UBH zJI~wTRj)r!D{N% z$`$}pgeE8Mu=-fd=3txCAi2RGk)E?o4Ub^1kVndeK80aAXbWeCKY}P?@oOZ(iFx3C zDz%4E-C*GJKv&0_&&H;qvL)N7RC61bYCNv7{Xe9>!I+4hj{jSS^YN{n?C!F$SBPdA zacg4ADn$VaSP2i`x~CWeb98Ll>Lb1Y{(GBhk{)#&8asc%unh{*5w(&>bF*Z~tV16EbVY6AESDKanR)5dQh*Ze z7zE~ZF`HlN`bS@Cw_ik`O+EmgWh{Qbx0Z}wIzoR0VWR$-XQTV`)u+gd(01 zwM}cuuyjIkA1PuQ%`L=6(d zbl}n~L>4Ci9%h`<@>C?@mq@5%@PKOuMu3rx1XZPD)J`c1l+JT4_mwk~rar5UIVZP^ zu9{zSMxv)SpfpV{?f6MWRg;qn@7>0RH8V((gWco1T%c+n^k!P0R%*;A2M9%U$5&l> zbX4YQR#z6a(|u6CHykpA!jSsbY~CeLn)*%!?i_B0TK|ltHe9qWwQ!KbTMm}v*xPP5 z)b%D`6vmaPPP(wGaFG$gde<}zL5}Ltf={4`X)&x~SPo+cE3UD~I}lmWN(Vk>>}|i( zlJ+4I{v_oAeFk_J(6n9oF-a0FGzIk6G|?N&cy5s(a`33iOjNEpTKK4zvLOt7?UAdO9L`2~vuQkkP2YiOP;0G{5I_I#lei4))bP z_4eDpfHBisr-E76s;j&imsp@MhbHD24EH)%1uXy`X6$9ZT2IO+L>K@*V8;pW0DuQ= z`H6EbYEn}G-He$nZP1`JzDIOjmd&w#t&x>*4!wM=9drf@|b>ObH`8k>lIwS@H9T`lSzd(@<-ZN07v((?A& zb+~okz_f)!qk~gK5bIaJaqlP;^CS*&VwOI26k7g5CihgK?G6~tkFvL#6LIMqO>K*| z(pei+m!}jN|Y(cQhG}ZtPK3^Zj@b__IZD7z^(|jwL;UXKYYbI>D9#+24T)tY4|Bf z3j{u9oa=h82-0sN;m`1Zo(!A=7IhUXmeElQ3Q#^N#m>y#!L+K6rsQpQ`oPl7Zezx3 zhf=x#*C9JoiwYZ}KwEoW_y&A)>XBm-J2!UQTbFFA$M|$usydavrSL@7`zT^qCDw~U zWA7XT>`tO&RMA1B2Y1o$l=m3-?Jr0H3l_tXI;zQ3fpxcGe820DaEH$)_|E^=_&3K{ zm`S#{sO-`%^rdm65}nAW`-s3X6MQJu9ZUOwOV?(Q$||Zeo2t^78YV>bjt4$w9P57X zJt@B+eDHuiCHMiDTE8k*^mIs5fUai4Kqft+A9tc|9`~u)yMx1Hw~krK{xAT@6SK`n z_C{3(L^DbzO8*|l#zebvOhxN@&)s2`beDqT#o?i-ccR0+Bb}`EUgIR8E1A7QQJyU_ z_e6c^5xRaMy>Pvb*fw{rbHFFX;t)l5i}+NHZ0~?(jZl9z`x6Vfp3QtRYsq=H)4Xlr_)C5H}rEg{U!1U_aQ$Ne5X7#D;O9 zgW+_2cB(Xx;rSemEg(jzWNgJ?n9Grmh02a2r(E&k;9`pVd#iYXbKTgLx32Ed;_ILh z{bu9Qr`v>m;%B!#SWsqrkILvcAaAtpgPu$7&sT(VymQI+cbM zJ0>Y+P*9s5US+Iqx>^+NHvk^cRlt4*jMZ4aF`lqmQ6SN1IoAIiNFS-z?_zuXUNR@Y zD<`H5Gc%;aV4+B@phh+J9FXg5end^OOW23dvPI66S literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Eb5.ogg b/sound/instruments/banjo/Eb5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..7a109dfdf79c86481598fe92ffc6537a2c20a49a GIT binary patch literal 18517 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

  • 06F7uzPqauD;oQIb!-W(wez-nEhN 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 JfbVDVEeBod=okP1 literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/En4.ogg b/sound/instruments/banjo/En4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..64c14daf915cc314592cc1aa32af3ce9e09eb9a6 GIT binary patch literal 25966 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 b^T0Ur*X`CD(w8Fmd>{7R1Gp@J=1BhsI{^?f literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/En5.ogg b/sound/instruments/banjo/En5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8e0b6c1637e4c0eb529562908b6e60398b2b8e9a GIT binary patch literal 16852 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%0AQsFh?G)f$w{rCFDSZP&_#xLFPa*YjM zJ0e`J$s69@4gV%|@$rkojWuKKBZVTIc@)RlTY`16`-dXGEgPLOfN@Y~05|m>AL8!2 z9~)FX4x%pebDNrJLA}r=|INp+%W>|F;9I0vC?axr;GGGv3Yw35biy-m4H6Vw8C9X61D6 z-n+;CY6@lR#n};rlwcO4uYL!b7`>Z&ZuWfF@#U3MNL=>vaul~UkpmSzoQ%~_HD}w^ z_(}7bGF@8{Hx^Orij?;s7sjB1Ib1je3{SL;T@wYaQg&dK1`>wk77~#Uyh89rqP?qD6n0G@Um%MS89unx8hR3R7IE^><03 z|Nb;#|0;X7R*eL&kME{NdNpna1+PsK#ZT(%<64k6huv6+#I$|v z`n}ty^o>tLw7W=0zTm#HI@YQ#yPw}q_4&YogG?auSgFSDZ5nYUml{K>5z%GPpGw;s zKJs>q+-BlAudAna({c)pls|qRqc!*;wHGQJu(g}7p8Vhjivn9}vAEDoy)$ZfxiyMx zUkY}CiaY0A@_IEQv(?F*{^-L2a99;E3z({ZIEu133H%f33%7jxllZ*H9_wW-+6vT# zMnRZv%?@+eosZyqIZf)h8^*!V&8nwdhxU&%hX5~e<<$}c|kM}4bh;` zn6s6sHLD8Gm?n0y)k;y)DgNAEY50;&VdUa)MVE?jFrU|J_I&E~CCA{?FIlt#lW^kfx6>(v7KU&>|7m@{A7e@(J z@(+F2IPJMQm_p(;YGa{xsqYGe zz;^#r=^ihR1UspM7p#p(6Svt5dYZDA%kUmBLUh~2 zY1f#pKQm8cd~tjU`@+23V)l7>oY?Sf+jxqj_?p1_z|AG2ET_JjO@Z83S)Jpv2SxeO zuRbP=MEG=BjBcD*2fHgQt6zT-RwPlxOwYI?U~AH@A$%=Q>jQu6cpuH)>I6=*M+aqj zYuTBAXYn}w@3r$EKgGiHKfD>%AGFu0W}s0CCTR$B>3tKC0ZT{a{4D#7KVTA*rlYRk zk%muTeu*0;fQIwM-&P^w=Z>mK5I$P7^^=r`rk{z}t@V85)Gw7`ctutEy$p>uitChP z+ka$Z^5RABuY(LTf)CT72ba}ry&HVqHKASZiiVCJIl5Z*OwtxiW=*T52XdlQcIUK2 z_eUvIvqR&=Kgqq{r0?q0Uiy5I)Z7=*Tx9+An)YDfY7=+vBBA|)b*)k1&WM9wm<2~w zup9qPn((*nHB!|d;&(NFA#%Q1u;O0PhfV(O(dkJq!qKTP@c7 z>MVp@?8O(3JIm28)iahzt0!mraR{L!#y-^k+xutKj!NgG(8q-Vdf|6<**cR%D(KxS z&G;f}Ul zN`8lAZqoxPN8P8T?({FdVI!^GgmJVc)|7YyDV?q9MkV>)O)wjppsvK^8VkD5Iliw~ z(J*T5-S@loLU;Vyv8o{Ku66kN(fN@^!o0GaUqs)_KztkX7DhxPmT8xbRc>`2x;&}G zddh0FHB(&a-BWDdPwJ;_zp#s|YrJkzjF(ZuhAT`nf<#`b#yWr+wgPGIa-E83ULdG(&+&61?8;QJ2Z?Spf=G$A8xC<^`YZL|Wx!RL*~ z>NhAw*bQS&%lHJhlQpL@mp!(ZeTB^kNlkmq9kV{>(40>l*wz-%ecdd*l9~bMZPz=# z*8TkV!^gvvjFe|a_-1v2g?#ar-PTu_0z%)jKNY^EoBR|n_LxK*cAvO$78gd+=@1jv zq~+Evz#N%g-pkqZvzWL*r?DyMk-KtM0*71%EPJr3I9ROwj;8p)0+>QSqBGRJAId)P-D$`1@jfpy(| z%yfB5-UmlyY|J0K;))XK2j*=o#F0mg%?}*hg0Pl{1j+e_cnk7HVeQJip{q!eC>ZT! zTi)zwv&)}qRPw~IRKF({nW|_-2hX=&yPCCNE?5-@zdu3&`>N1!59>ewkAPuLt^OTJfI~y* zumXBW+uPI8(be1jv8AJ{wee$ZS6yTC$IkXo~f>`Wn#q}%ziqzj8wWxW#{z(%O!=dp-x>3%dGIkI~0eYl0BUG8R?QYtiJi6 zPYHhPRn(--@KtIE?-9G$)uz@5)W9zs9{Dzl;s#FcmX{7#3cp`IYLLujfB&h6M!cvJM_jW>Ni4&4m4uklnzoNGBj^*@ACRbgu7gYNygX>D zZ2A7n%}(I@(HukB8&tbl2kxUmaqElu7$(*E_H~r>BHZ!KooW)7>Dff6c|C_Co1RmE zOYlj{a)_=mo)N52!v5*=C9SuVjjH>wiQg%)jl4CAYFOIpQS}cr<>!POgOI8*)j}2V zPNur@cH~Ga#al3cl)KBRzdF4%EP{6nTMzp@zp@k=PIXTNmpm`%YD$e&4Q}LNkk|N%ZUzk2MSP6$WN6 zF>wN>5mEi@*&jMshVS;6(g~?|oUNofajOttiMQcQ2WnMPtO9LZJW1raVO017nfa(( zJtthN^i#8jFTr;ryx3plW*BdBauN#6lv?lpQjuuDdV7sl`mG3cmr>5<>ZA80uO9ef ztY}5C{ZhcKp86R>#T5h6EoP?~juRmc;!-$bCTILTg*MZIh?eTRYtEnU-OSi{7T;2| z-haJ~J&~oHpw&{_S|)<#-Ohjy-I330Zq#0ZgkiF_OZS1>>HEep3z(vxX7=JSu#ZZOQkQXDL>5 zF8L`W`P{3h^mSFJ94}r$wu6&tv$NI4!vT7OZb7SW%r*Pv{%+4?Nhyy8+ib9LUxt^P z1UuZv!B6geSe1&-3zbV|_ZU*t@%EeVTsT1v4S0G{k{eL?5k6krA)F%;hO3~#85Tc+ zk>mVnxgjgded^DucByG5Dq|5|RD{>B?mu5j$JwFD(GS4czRj_b6;b@)l#D?2hly!` zf_=lj2F}pz4~`mtTFTS=t-rQ3B>DyBENMT1zjQXE+|Q59xY}A{hj+1|YTZf;cOzS1 z3ODe^;=JVg20#1^tfGEmn|hcGf?5_@ z_eUNDi*%?;A4lCKV8xPPXU~#h(Reiqdx#QsIUO|Aa_Y|bNpuhu1PKwMhmOw`81ifK zpp%lmB4^VZK`uEb%-7Xp8ox~oR(>w!@U?q6t!vvS*)!KW&9CyYY^MWdLiR491u(WuIniQ$*=5PycF8Ly-wFF(l(9$ z3|nPPsTpM(uxsN0+bq7HY_{)~;PyJ|r4?7`Ht?Ee^e9z4jp!6%c2bmA->yE;<7jx6 zc+xY<=x6rktis`l?J6#*LISzN zsxpeaCDA`j?afc(#C2Rt-WED8;OzFqur4>c?hx%cvD+Ce6Yq^IV{HvB9Cd)h2ZxI@ zKk04!0yMr|TC2of6)&leP((5=^vEoR^b7yP>(0nOY!~MD)Yzm0p2J>$?P-t7yIVNJcJn%n zoKwEml=MYMb+Bj9lWm^U66T_sCod%H#)2o?t_5!bZ=|}SyX@b7FZ+yt2^?a`Zn)xMSV8w5D9#$eH%`V_VJ>N7ISpxUV}PM+Ws%J}F%Hj>t; z<@P(YyT9bXm)$T{L7mNI_0~II#s=m)yp4MHg#{&Rm*yJilHD}xMne4E^V$cAp1wqV zA5z|0-$c%bIqx*hJz;+;j~|riJ?1U$k`8N{VWA#;)ci276ssi^w(3^18g$*-Gc*<_Epaj0(1N&s|klH#SVu%2MHoH&qfSPtS2HzDm@yEbLV|Ow3f`?pcxXqC|B5o zZw;o_%?R9`o(@+Tt}AjlXv&Gc(DV~XNnJjPqL5Q@H&W3dC_?zwl-`Dqae!FeWZ88m zC<^fvy_jiiyx9DNj*1DX%3+ktZSJTW?)O{m6<#fqu+~Jw_~2FI%Bq#dt`+BT zYz92GzbJ&odR_|u)5XYOiM?GnW7fNA#$w95E@Apn1K61siZ zZ0B9BnBvQ%@<)k|G}MgUh@!bHsF9P8ln3=*QZt{>M#0TNZYyj&&*!!XEH`mD#~tpG z91FW!Q*m%*7|Zd{|JK2A>$wk&z1d@2%EWY3YX6B74zyPxhpqVu)_rF)hcZ7R4~-I& zdiA#QmCE=#dpSSJi-wY^xJU2r%9J|wi)*jY$0$Em3iMMxj~G9xDd(zrThFPcV}#=| z`9y1~s;R$i)*|wFR-5~#oA^ui%?Qn%K~4q!<^kHlKn{i4eGf2yhOk4>Z()DK8Y(J~hMQJtao{>cl^lu3zP(wwpy~TKe$HLATKl5o zb^*1Nv)MU&DWgQVi0dt~kd=ww^I-0rxb}kEdOXa=v3Ys3XZ)*&b7nu5wtT({z4*Lg z5ypN#^G(%3TEXOfILweXx_AD#`Tad^&n4s9W-hJ!&($|x&a%02d$5(0Npiyq%SQ)h z<$CkNg2?06t60lqmOQ(V!K6{mldoivw0~NDx$Q(_-MHe9a`69Xq(TZ^H^<(RhAho| z9xCR8Z@BjmJ)6QPy4`2>Bfo_V$X>>wD4hkyi+|Wp(6ZJyI?&1+J9O2B{GsqB@_!jL zex&gJi;}7EDJt~)3kE9YhXw*1uB-Ihw5*LQfYX zk2$?aLtUvE*Uz3CVyg=2hLxG-G|76#dbI%xXcK6u){QEVw!V(FA=`Mj6`>-Ns(LA4 zUslR{ey*T*i*tXtgC=IFdwNpvPV!naP4QNoTCO7f%fY8!GnV^x6w87p)!s7{QV+3# zrH-AwizdQB?LoZeGSCfKwvlE}BVM9mo}WC4n-i7?vID;cfW`IA$aKed#(n+u;&!`9 zHg?KUlT92;eciaQz)X{$4#QnGZTFMVBxL*4OM3ca@09Xs>2z@dhPln$r>s|hWF`rH zO{hxMtXF&EEJUSm@~ZZD=A5zHMf1fZ!t2Q<5Br{JhV;uwMZt}oryqkk8`}3x$*`uhFp^l)S)3`0n7*Xn-Rcli4#kCFD&&u$T+$zPs@DV?m7` zHMb!{im0A$(6`pH`14n(@U=wAAt9{qH zS%R0>h|&)Qh^!2(JVG5sNb>1WqNg@ZfebLQFh#?R@gv7?kW+*8^*Ud6Xv_{QA- z`C?69@1-r1!ULuB_h!4@MG8A=L(}*|KG#oE%h)7<=o!aO zq-cmVq&w~++_7SNUJEtYq-s&4FKuJxmqzGk4h8DpJhl4$bv0LT#wMn@I1? zpNWhwlM*8vapjm+PTw?)={^}TJ-A{uT|k3Biy~0qqgUo5_K|Oh|01`0kr(yE&9sTj zHq79Q_?unTHR7mu-`SHC-JEBAIPUEhKN$48^?jdGt^BLD1)UG;z04bkhXJ{clo4i> zRg9|lIA@!UKRqN1p1l0?Dp-MJ>`1GfLU&igd8{pnuO^FNlL{E@?AY0YwAfXhR%{YN zRc>^pMc-f1!6fmG!?Dw2|Hbo)OpW4q&azdq2djfC_ceT{vkpJqUGn;ad-rz{;z3x(-kbTj zmqoWb9|;6I|LRq8`tXLR+IcT}MD*h*!<$pb*z-qrcPe*Ybltv{?4fHOdi0v%X$g0- z%F{~;1wnh7>QkIHLB6i*i;r*2KP#Bp4C6M({(F3Z(~9-q#}~NZ_#(NM9Xh&V}wMq4^@w~A1=UaPO0M zJ?5l7KiB8F(1omfW}O*ta`nPWGEwvUIbD}>Q(~$QxxI!UPA)#Ju=;XR=8>?oJA-q= W6?AIqsp+46R`-b)CpTdR(EkJFHe=_j=yBhV4Fk&8)rGTEDgS+Iwcyw6)a%P=J3O^i2O$=GbF8AhZx4R}Tw& z&$}jwLdCx>@rC@Yv_LfP?)Irvo~BvnYSUJ#YLNuM#1@pDX!AY&`1lq7SyJ6boB zt+g~g^RES+#wj*HTf&Cl_T{{t$nYFj!OJN8r{+(TiCI}X1-4OaXA$&Mn1k2ZPi0`1 zE;EA+4A^Z*bJ z{fpv%7k{Dr4~h$tVmOA`>qiAfxbBLI-f{8$nqH_p9zTd;E@2SG@r~c!c~*%jI~F$1 z8FCh;z*S*||9BK=RC=pKSqzH5P7;~!F$^mPz2ZL&cg*~WkY@5f&QB-Q+C(hiIVr%c zBPgk-t7qWj{Pd0YQgejKg7@nDi`Dsf)BBPC6IlP{IRNN1;eUNH#UhS>AS>*#9QHp3 z{!O{#WnUrNb{%AB(b8lkcJMa$t0=wG?}%Ih{?3D^|YS#tdI3# zleJOvi>FQha+rVIW_8~CKRoBoMHs~rHk6al{@ZhM*b~-86PQ$zn4c!G`ls1OXOzBu zw_BQr^FKVtE~Yp=rZ_5QJ1T)aI?X;hqpUU0X}D^??f-fHm*+h4U5kOvTTwqNn*WtKiA;w zqzdX`@hlG#=<$1sj8(QovB0p02518Sf`5?zBe}=8%21BNI6roF%AgoqVe*s;j6027 z5XMqOWVw-*KczBMkV38&lU+b$8C?n91Ym-HxVaOFq!1Yr0Icb8mGE?#EN>Pdednd zdX3JXgsc~J^_I!>W}B>+$bt;gyjKM^o`OH;K&tnA+6&V;XOr}QvC<&<%SuFVzDZcy zOHW(R`l+toQy=T67kUPBFVsM)j>aOXo?esQ;+eBv+KaDVdL{Tx}vfF3aJLHv=Ww4i(m6kO*msM37!Gj)F1UMI&$Pt9=M(S93mgExb=p7(N!$%X+ahqI~g zJEMz;I_HO7mA{8U22+<}pIoV1!Q1LxsKB=VpPbU>q6vkz8Q@6EDl^N<_v>6Zdn@+k zwDn$?q*|{&FnN04W%WUV(R_Sf*UKVAlO++5kX=`a`@(YY0{fHW zQos9e@r`ru{AxVxfma|lAa~dx9+t^v;6y=)LI4bgZ4wphNGWeH$i1EE15{u4wfeQc$tfUMqzC8?@brY6Bhvy$&v zg(aw}z?za&)xlAzs@6up4W0Psvfxg_;HW@WNvclV{f0*Bjowg0+`pr$Y}9vjsO$$j zXDK9CQ>|?zb9CYVMyYCFdDnSqADK}C*tw3QaM7H@9l^+1axTMDwQ_C-9uE>MojYbT z0*?MIxrGCF|C~kTUFRINsYzhx-##10iKR?gfUJ_>ao`@|9^3fsv!|2r z`HW%3T_0-T4B`2z^-Ld(ItWxi27zsza~DGH+*URUKCWU9^%xc7z?K^oV=MJgmxICd zMrE;B8pp+8u)aAlES5qtH4g4ReMcA!l!6<~JN~*YhDLNB1PA{qHlP4{aX&p6cQ7al z$-^ed3rH-XjD_T&T?$DoLEVyj63B5-SdPoG!@{*xIbab`RTY*(Fu}#42J<Iy{Ub+GtgyHI{Y^5QfMk~ERC=~XM8ah-qEXZJ0M$8GQv4Bvpsr;C3 z2xhPc;D8SP#t{}E5fhLh&jmH^>yD5D#{mEiH!vfr(YEpoeVqfwOccQXE@rBVVdkbN z!TRY_lHg!>ph%@2c%bh3^zR5Mh6nT@G@OKepdhUJ4dqoU`<^&fF%-^OR0z+5Aa4AY z;iw7{9LHJ#;0rn?P=iXPD8fdL%^_ssKz+{ND_+}{_QMzELdMUnBx?Y-=!Yl zBzu>C#DN6xXFo^~+orxNvOE+1J2Cn18utH1h*B`mBGdwa=7tbej{C8EDSEuH?A zq^JM$^FMO-|IXh3x0;b-B?!6yEC87<98BOAlS==QD2x)9>rO@}0hs9Zrh_BKpb3wJ z?G%KA=E;>;6=P=sQ38X3@BuwK#ZdLFCmhbfQkZrZI%W)2xk28TEQND$2e21$tipzw zyRH^wm0^W*hOykB%c+7tE#ibD;ov2G3l>8!~Q3M`wPZ!A~2Op z0XhHEmO=#f@i)Cof!`q#RLvdXFI4~5uo>>u_4i_if9}1@1wn|S-bG=i9p?ODMkk@K zJ*ZlCgQ@@m4*=X39QI*zgY(D8WibkJNa79Uv1@J)`1VdyXB;BH&K7^3wG!9A$ zJ)S=Eze!b{KE{@pNV3+QjV*}RbfeZpZjc}HOJF{lYeOl)aX^vVP2vWOcr#WKe9lG{ zSJsDjk@Nc^BY!-up1WAq@Kk?$-t6ScmAoFD7e?_zaADb1)KmOJYm;j=ISaj8Od-?_ z4|6*8)jTF72U|qLUtEQnE&7>w7{$5aEMk2NwUSa?yvPULX)vwuI;PK>uELJ^=1ki2 z5)f`7C`poRjwxJ}H?=sG8u1Hr%_lmWR%ZO{tdmO_pt#3aYFWr1*>xXtCv@w(%H!SIKGa!yI_VK4C*a4|LRfjgZ8|1lc`=b~*ZznU|=RykWB6EiDQ`+$JN=O#I zq--9o&a?+U;>QxW5pX_cQGH<4izS*j*ZtHpx`TZ7(KKzGapljg0GRB~HgHOM zql2=ipRTnqdl4V^5dr%U)osD@kT< z!=%f;-c|zwCa;N&;m$s)PRa@;JZ+!Cq`2q?A>l=UWWjhzc3?jf;v(A;050WFLOrnT58jL1O1 zOm|HOka4y4S}Fv` zGjbNek&UH$UCPb2I>!Niq2)LxD%-uY~>z_~F zh?Kv7asLn3TnhLL;)P_Z{2wV)D~-Mh4wD7{W=UN`Vc$- z4JnNZtWilM$}0B@0(P9XqjLy-p39-N6f7Nb_^G);E?U?u8%m9#%Z7}%<_@qjj~BMj z^YYaXfevTpt7DR1rlbc5B6I))fsBm)WC8&cdkZWufCc8y9hJ|byk_)-K4_N^T9jiI zbYOBJa04G^u>e|b57)$wk}*e`l-`e!`+!B4z4~a$=#p=LMtd_kMcqyt1>r`{b=v#Np*lHxm};wYlQOl zNuN8`C$4;ylY$T+G;t5pP!N=E$v`vkdR>JCs!Di5Sj!>ujs1JzTO`pf>9>Q z^aLT|!aZW#W{?OW3H~)#nP6fTH$XBv!g&hcJqB(dI}!H)Z$GA&J+MxWCdwJuK0CJjna-W`U)(uq7eF2U86yi}#0o=(Rh@? z%T;R+ewmVSzQ;}}UqlM()qc|5r(a_RBPZN1_UmsN0EZqRiH+d%+$XGxBFL5Z3ViZB z9KANP48GNYl|yDPT<@jwR^Yzg(re4}QWrY+4iW7P8|b9z?nwVM$8H3NEg)6&#qF4L z6Z4I4!1LGaWx)UfNup(jN)Cv4ZQqv=6$i{%Ndo-jH`6kV!W`t-<9-M#s?x;a$)L4UQoqCFA=MFTw7# zr)xX2-UTL5V#O;H&jj&O7V?4QWNTLdGHyB$2^|Mp(p)rhP0$FP_uES`PETp#;<7^sOE$?M;*qPdH3ks=fRHbr`>H`_kDw# zX+wZ4GmTiT94CIm?8R==#3$Dkj`#P0AVAyh`kC!#$&5RB4q(SJQ-vc zKy3UPX@FwNrAH|NEUZk_FgW9UV3GM?hK@GzJrZi0tn0~{ic^Bep3nN$VyN_M^X_C4 ze{^^~E0OuqpSb%6sFl?u%Bb5pOZBa~N|WOwr){yHt=rS_m9d$?=18m}1Bxz~FCldR=^ z{Id*R-%FJK2_eb1npZf0lnu4b&F3#wg(mL;77Fcl=>W6gX9yUNEGi$u3LXH7@U z9V3&{q%Z;CLvM_02I-S9S1^q5ts>YmFRH9xqSdegz(Vtyiw*}ZUfL7$H=iXW4J@7% zLaTrEJM{foF_f)8RZH-iZZ_}an+p=@uL+nr%Pz}UY)1KISJ^5sx8&k#lz#%ev!+hF zCGKJm^!qd6w{{P3Gs9tbmx0i91Gs!AD4{ctadC3O^dP^K%p;Bzph!QQnlK0^0giDD zP@}W3*tB6wSl1L)Sw+ZBB;#YG1ulfU)W6@e%XE`3?yUd=qw6a2?lEb#B%V; zXc52SGQqKh(!$>yYb_+cox%w1j~Tha)dW_PvkvV=@8E2fHTQmdbC_`9hO;>QROLC0 zjFRxIDs*Q?E7e-*tNRtVtRIkwwIJ|T29*|6{B0&>%<1mYSPLJW_~kohlvH+zFvd~XfHIi{{*A1}%=iqIOB z=mV5AdH@lO&Rm1Fu!_QA7mCqB{9ZENv)eUtxlcLKSW((MEe0)TTw!iTB3-AE!n~h+ zHqp=*M=du3l8KK#EHDGhPFa>asoN9iNV(0)?oL$gNG@pl^(+?km|ZtT3b$2CSC;26 zZ3$6p4S8mRH!FR@59`VTHy+>c{mc#PB4+Z-ki`7e4Z)Y;LsI*Fo(s<^7DmTnt{nWT zLeVXdBGSsZa#)ChXr4iNAVWlsLIT8Ld|5y&p*~!54}X4-eGL#<^9?CPLA}hx=A7t3?iOEB7f0(F(A@QKwr~)jU*-=tVThF8e^{U0_XZq(5iTY=*N-e3_H@1YUtFj zyOm-p+2G-c)XG^AJ7-B=E~>0b7r#d4=F+DEe8~5RQ9E>oQS|VRuLPv02uM`}P{^pN zo+;yX?u(c?(=@v$H?;^8G0Zd0yi8I(tybSs331tJghk|dgd?+LtyiC z`%+uwA=w~k1~0Fr=|j-TpHuT~PF%Fay@5Q-ol%-O52zn` z+>!*;i!ugHp)b%ya|H~`(;Lf(pzi0Av!5m#Dipb3Fyoh^X7De6G&oVX-)3RsaY;W| zu{yRQ`qKj+WBB_?GRhxoYNhKpj3>uO(wM5s-Qc_$j-k5_ARZH8eFG>p^*`IcLa__9 zXU;CJk=Boa%G{#6VMEPOuAP7ytS>^Mi#RPvmk?E4fMiX7O;jt%t0+XcKJe9`v6@w; zDyDDlOaEOwHy*i7BFnEsAdu{DQ-QZt32+7%hKA=iCKmj_f zso{T$oF=9Iu(^2FqK(o4IUFcjmVhY0%q8>a_c#To5c-54KC=&Afsc{|WHW>iKs;Kj zH2cEp7lH|9(QY9(kmGVd2C{$>2E;i%)6;Znkb31*swi-4Y=)FZca_p9 zPDMzNvt&Q3fwC#{n)z%D@$XIt&F{Z#ppsdw*t8%C?NAo_G3$CNulY=9Q`lO`#d4@{ zf)-~b-?97jP)B|yqrJ}I+`PdQj%oPh=KwWD0#n7NL^KTs)ec4$uwspuy4q;leSMSp zMavik3ZjXMs75pgz*6eLVePCciJv8r*=PieafBX^Y2g9}@5u(y04I_zcfe2APseWr z!lPxMvjPDp0RG<>kQ9fp0jQ6o3{^ zeowq)O4yx^kff>zF+>vNIzaXhMoz&=E@kPfVNP_Tr{OoLvmaKrT)6artSGCeN^zDGa5 zP?q(RZsXMZYMUo-YRDso)rM4ZVAC>-ZFRDkz`wRJ?)LD&<8B)R75rBdJJW=8Xsl;& zV6dmNYiJNT*!!_}aJuzlA2=Vv|7b9gXTQJw@_apnkB%qMpf``r5<}fRqzICTmUwS_ zL@?S0$7->~^>o82a*cy&_+4AS=@AN$^As}?2lxWtdyEP2o7;vip<;1SAl(5M4tE@7 zGsy8RP{aO#|1hr4Fuv8|gY7_a`2H}gQFbKGY^@+RRE#p3t_Cn+_{FK6n9~`PWXAkh zw7WX%mT>W5>28xM`wl5bREyS6eu<0rI&Tt~iCJ2kL8h4O{<4y=a-R=rd8Y}I>x<&` zBdWIh9G1RBKoBU1$fpWs$?L$~(+@IH(f~4qNXr63f+|-7JQ@-ge+t9NsU1cn%#j-0 zqhUatuplY{(v-(j#`KF9-Uw&efH)h9D=B#hozZ0Uxt zF;)f>6o&DSk{z7(HZkEFI^!Pz(9=eB5b6eguBoW;6jtT|;@Sx^At9ZAPyj6r2pL*G zMkfs*gG9gZ1?=CpW-wdY@Vc?m^u$V#0-`9L)PSE>EINRNbQMmS5hcU-TwQ(EKA6#H z-H?sPI%W94nm39(E=Y&99IfL}VSvdl*g1AUS64ueX>95N9hr@Su9@=qr&vqQ5Q+9j zMC6_ylPJpE$?Y!B1wIU*!Ka{oHSxbyx8>;m4D%K6rjy>(u;v2KtVcb&)=9Q{SA&Cg z%-N4o0WDHH0y_lHgiy4Bp`#+iYswl+KX3gKPHkq(-GT*JrDg~L3)n5BWC83H^;7w$ znx=UcKL(7ttDxwCT3)j6kSiDflo=@v2+fF3A@;&747r=Nj5a(;#|mB5hT6J$>IH3@ zOc@gv;^oWflD;AQ~lKO@U&Khsumrfj@oWSD2$te8b{KD&+2|+8{4rgdRr`B zhxu*&Eu7B(@kzCS*AEH{Qq6JBK?i4?v+ncK)23LceQJyhVbsaAm1CAMUORrYwswUK zyGIYEfpU$m`e|xzX3Cb8!URBTGnym)LQz2a`kE;imw;Z%%Y#(txd0L01_A|K{L`vW zC1n%I>BtnQz*A28c`+U-=A@xjX)|#HA2ER|EOs}7KN0}K5PA63MnfC9fwpH3Zv6<5 z!V7!_9<5a$6Y)x0lV3R~t{Hzn^f}eR1Qg>$6g~ydqwSZPcAZ6}z zWS<#)uUcDl`pz6Zs~g#hzql`ZvoYC5U-Dd~PYrnkIYi4qsQ(0vS1C6<2TJFEICod_~MZi@W&c&x4Pop z!RpQRgb4=$o%j`&_^tynf)bSvor&4`svmnG10|Y$fMoYF+j8|X*Kd>z%?AY?n8gB+ zDgb8-jTT}l%m(6zju!O~x2OHn_W-Z;CMKsW@@sPH8b)o*!tv7Di;r=^Gt0QSnq(W3$ zc)*py%SgR)ns}PgpH+7Ivk4JA$mM->6`7FKb#^V}GqTSH0C0^9Ww{o2 z=F`GV55!bX!v4Gjmh7|J+Q9Ag0AYY4gdl z!d_}ryeDT4YNs{cNwprgUDwss)b7K}36`#84WDpyyq!=;Mj3NK_5_I*PvayPwsb)| zrB?Wi@bpk5I-vf81VE-^Zae@VNgok_%oxv%C|g?>IX`$)(_D&B zX~{r}K?B|b9G4&*?|dWcD7L%d}Qx~K|R;2B-)cs3{RQ{(qkBE9fz z<2N73j#eZKFCS%SJ1eSQlWyKC&soXGyfu^`t30yaqjWRlxJsIEI2Rtvo@wm(E|_xqsF&G%~7U1|Ox_Y@Tg5*^vJ93_n~^=3{&Olc@7D1OivY;D-DR_gS>BvsZ! zzN~vU85EzqdT+LoymMd7!yY<4h{QcUQyoF98O1zWJv8~uceY4Lj?W%f@UoPG;aA!8 zRYdb}KiZ0Q!^ew7+jU=Q&9>$V(VsP`C90TIM0zHCi1!Njv#UwbpF1y%|7<)rY{)7P zd$y{6D zmJm*D5mH8%CmerVw(S2-^(S&?VKiV~C#8UdNY>0y46d^Ei(S%thN{|qgnEi-WWlQJ zLdc{v(+|ztfWCh~Ik2L$bQx`mq>2C`a(|~=yfp0x6<25tt5NBNMbp%CI2c|VPHgo@ zGIoA5OAn$;NjXKUQgQ%%eHbJVgU+AC<|K$`rE_TZ+upHim;()z>GQ1hs58VkR!@)# zGN|fn765`0i7IgdM67WJq63Q|UA^QTD094>bl&eQe>1-S;yqRN)G#l`%-X{A2)JS; z5v!*#DxTLtRm30e;YW~61VFjZIfji49O8}Oxht#`toZE~=Vdz^k^IDO3BwYS>#FRw z0zNkKJRx|i*rr`5i}u;Sw(#T;b?#a#%J_*6-PRQLinZ?U{GW<~n;%kMe@@s>%+;C- zl0kRw!=T4U3$nN-hmUI`ThRn`&)Xh%<&|U@S6+11jXzg*9L`N-L!xE$xI(xSUEZg- zWrOJ+5^*GeQl%Huq;`yX;W{4qbYX^>m~_YCR)_!7rZ1b~)kgF1GTf z(Z$M&#%&pgx`IN%pBk?VMidyAX*F&8jX&a|G_vEl$m%tja*7^ws2uO+V|1<{XfM{f?bU0*1_4LONF z*Dp$A>YiBcSg7>9iY7c9kxZK~v{PtERGV&-t5$NR!Z`P=+$yOp4+~Qx;+0B~wHs?r ze96A;O-Wj8OYLpgS5-T+7Y={F^OO@!1`dj}dAyw==nxv)t<ho7YRR;R`!!~QfD@-RS=!!n%(8vS-(DE=keQzu3lz59u3YJMup>^R6)n#qIncH_nJvxCbZky`!- zX*m)%!weX@^pv95z}gaD_gRdd4kGa9&#KJn$%;Q+81z51%E-PCSZ?b1{&?fjW6I8J z${%O!EvD6YLu>l3|e*A8Iu@&;nffdX33O|FAjioJh@GB7# zKuafUnPpg8`#HAXfeSRgN`Hgt@j#IJA?H>vD?;^sc;;^gzBg)-s6}md2L}nh67LS3 zR*Pp&)H7qh4qeH@Y0c}cHzDA=X>p`!c4GRUkW}BhU1(XxBtBTR%rJq ztxsdY(W9eJ=(mM>^ZQnU$O&E=GNoHJze4=D&K4nHXmr?R%hq9QhLH?vcWM1>hMiz*TxU)sb*L-?j zx>f!H1?|QN_Sng1fs@#TU5r_gkzpe=g8m2ExJx9-t!-G~oA7wP(_^dj+-3t^L1<@^<{qW0EgXHAHe zchSR``{S!kn=-GtIRZ$bv`KkXkHb4vx3)O(tr*^*FL00%FKv_AN9t71qV zcNpY^0}Hq0DC%a&u12X707`-Y1yq0zc^?JANyK`pU|%sp%d&D{i?ivJ#i=mG7+ZD# zr}!JrT1#>m zh&>x^Q)ee5NEaJYyZzJ0tsb2#C(XYe7+ihk3pW)!97;ql9g;{|E3GN}qIqtOYD;Cq zRvPXzt6PwODP%OJWEnf$*x#=vBveDoR|XY|7h0q`B2E~C5_53G^tCgF zF$QLH+Suz`wlsjUV2%3;0*HmhU;rQ9PRP#=6{5Lw>(!ly#zZP_Z`ev=5*4xR7X_y6 zq-40iV0`2vxj{B!DeFzt*1s?Ed=g$vRXW<3jTY!#dhDEBZ3q3Tg6*Z1VcvRea&&|L zJU5(nvYw`ZoF;khgObyy0k5RAs{++a!vU|C4Pk1vO04Cbdc6CE5>)auE-z0s4)V~# z1(yYe2*8NOyfqNyVtf59`uoyHFA0e;3>qgy-UvXhZK(fF8;@NemoDazwB!1l!@=2C zk>q*?tV`IoR=SBuBKs0e9vQGk3RO%2j*EeAV!&S)%QZ|A=TNomS2gW*{}BJx+RSa) zwJL?-!KBCjLosT9jfY8073eo}qdsVwpT3mqYuJ|fj=87QZqzAe=*}dkZjN^wjWfLz6{a#X{ ztkPV2q_vR7L6|>{^5a8dO%5CUBONj0Q|1FSp`^16prV;R@>foacHdl>t-t7nRjtTa3l9v;l1ydVivN-+)o9Vhsc z{c`_Gdq{rJgvtEl;mapf`g-{sy>Ej;&mt`_T|MeK+FE*2`K6+3!wzX_z1|%}9XzYN zpPw3q_mJmsY`)%!?pq8)CoG`0G>X^Nok2KXA?$VnL{-D}n<^^SuY^*&D^sJOs{^l< zfw&2@vLtrLLSb~>$+VM#xB~LmWIUI!*K%yK7`7cR!e*{lQNT^jwNQBT6UuiW1%3CqHJC4r4 zrBI?#5tE7X0bN(@2I|fD%NrR;vLzA?V1pe$hLoitaUavDGUlFtUsEXez`xJY!_pq* zmb-58cN2TvTajqitXGq73q)Y8n)S&Y_EEA%WX^Wr7f*|A6(2@#(fgFqt;041q??DMQ8&^!V`M({8Iwm}_F{;wzjkg!sLQlzc&#{2G*EDK zb1(lz*OWUlKXip~k=PXT`PLNcIHKz%W&V%C^_|!6otMzn@aHNmm}}pVK9`?fQkC6< zN+pi+9S$%OuEfRq_UwMuV6G-rF~;uXnpj*%wRl6+>gK5bxpq-)(wG@N$Xa)Kz<*W6 zAC2wA-kz7P2@rt-?30Chbv}l*c?e?@qoE_80MXAU8#;8p^lgsd$62X6vW)k*pb&CV zhi_^Oz!#?O`1rTC$Yw&7!M4Hrcj&48pDHXyMM#2Sc1-IiH*8%Dd-Y{~#wHDyRr*o+ zSx)AxP2;%*uIm>g+`V+z9&6VcMZ<;0gLKJnqkhpUnsdG-6rI)fPgSyD{UFR_BOo9= zq7-fSIq=*W|HM@7i*zt2r)RNFhjL#}dKyNaLjJmNq%KN`91kJKLrLWPlic;56V6@dr2h()@Cy5;nKAp^9M*+G?FoJtRpgL>=>k%S$w9H%y8|^#y?kr}hzdSYh;G0C$GI$}xjDIJ{gzQ zdA~u3^!hecIVB%2qT+DIqGb7U)UVF2uXMA_g+Dd-%|5^CppF;KK#=SQfv561t}@=) z*uCeuoptodXVruwQM^wbDEPHji~==RY_xTbdx%&s_)~@m1I?hj7K^H?A6`s?&z;b| zH_e(Hj68(Wnih@YOb%oYWXKrh+{|Kkj+XGWF%Pt{wK$LpOf$l#eykYrn8`vPHU z1C{lq6$WM~DN*t|ho1}EI8ngMk5a(hFr@uzXNWQb^#zQG~1y6#uNcFsnKBGz~ZA?$nf4`pn1$T?E`X^rQJyNVSBI zl+LIZh-n}4I1O3E1l!=#KJ}O(xW&jrKb=21E>3VKv_YieC_6Nc?qH5h*^~=rjRhys z+&Vwp(4{~n-K@OE9Vbo*6O*0)CH4`HZQFk%6&!;8DcKl3O=&T59x>l~(!jh`K(@0g zEz~w(QN5!RS7c|9x`;YJ3)3mB(?4jn#RVt3g0tFYNm#5agUda!pR#}n3W`<;z8$>P zO1ghA6y+@Dsis)|xLe-Vc=p`1#W|ZPmiB2wmcQ=Dc+tnT4yOSo=r#F_0oKE)N&83Z zmair_@cdoA>P-j)yig~8D|qAhJtAP^OS^&1tIe$kJ+M#>VcJJLK0I)#??P{@`MfsX z*u>?FCJ7)Q!?dB(RLz!u$b2u&LuS>9*aw8ZN%?s&pOhCI`p-_}Hw(I^${Ma%vai=Z zXc17cdXreHd*t!WRB$zxyCfZdpxF*xxf~2q;nN#2%~qo86>>uqlswu$Yl8S zSAKfUsPgCRcN4O_`|bxDt8%ZacI zsuVjWamt5Z6l!$FryQPNs`T$^>^!^&j7MCf%}`HF$b9lItUPb9p}&6Yvb>l4ykz|7 z%TZW81t#n7hg23}9c=h9j53uChFUo#%>-VqhFf_?l6K}FF?@!*DKjfCYb?sTMv*(D zuQPYGA6Umcee68fOX6YhoQ10}Jn=}oW#OBq5!Br2WAXl<)8u>P#RItI#_zv!XZKXP zslU(S;8iVLcJ^SsT-?!Jjxo@Wpf5z zk&vBrvicqjR+3@F6GSXM!8TaVv|6gT_fkupi}CjMv=V2spnNu5^>ZfWp0xRLSg16jH&Z5`wHf&D z%?NGC-`$A2R~^9r1OO-rUFRe1?CBop@9*jv?(ZKN>FfD8@NuBCkJhGON1k=(PS*EY{g|{^N~?6y3NdnLmaK44(j2!a;s+dD#xg zybi0V$oHcPBI-BPF($Bht#7~NotmmRPqh0nsq+5LUX;k%ro4}cXWzctrAV^%iVU0I zi_)UZ`B2wlU$2t9b(;riT61|vgFZm#+n3CHF2v8}-`oRYt}1@=0JcgREGfmZ+-R4}fo5 zp4oU0eYyPOZ#}K!8T4G*8*_w*iG%ZVCXHrgbQFDt@>Gxr_`Sf}hX?FiDW1<@KP7gT zWF$8=L-CAb(v<5wI^8mUDdu4v?H?8l_UPTiX7}*l`Xg*=SpB2Ai zWY{4~)ly=xyIlzZCZ<$M9>^wRs9xaa?bj$`I^hg z=;U_nUT&>Z-}=RJaL{}!7PeQ`mz>VA$e{GJ$h z<&B)*Q@WvXc{3sVZE%KCu~Z=5f0&@4hN^@tRdEtOeUKr(YVEL%HClr(KH67w1|ns1 zy0JBFGeMTAwUN&(ib?fYW(D;lSEW6P1CEA;6Ezh?Joq-owui(`uc)rbIx=X)5= zsSy-siu6aTFJhqs@1jr~W-)*LvQ;9N7auzzBNJJj@ii$Nm8qVTQ3ErU@IOA|?RK$Y zORw-AzNzTO$Wge@Q_bOUNP_;jw9zWTK2jtza*0-=60eBHlP-YW5a0U`flLytL9_P? z6H)O#0*&)03kK7ium)WdTT>vx$R;wzP;FP5rK^t(SSDu?IOfxZ3hj^i6w^H%!TJ(Q zNGjl}kn<$@N5=G8bh1O1u2E$At&b6*b zlkh!8c{bmIl?Z)a>{Z;{$Dv<&d6`7v)94-V8+zZ;uy$Ho?f#JrNaVp>Hc+pr=Tg)J zz|R7dIn(CE9TY=U&IfXAyDf@X`@@EIUk{Gh^$Y2~Luu5LL0Pe%3Nd8`L<#sJP)zx2 z$GgWym)}Iy_ff3qeE0wV0`CnF@({}0^W>yCt*3K@)-Q@|O7Yq<-PM~Y7KdK^n%u^D z*`nFiS_+thD9y{v?budK)hbaDT))M>Q&Gk!K{CGwuvR$sgy0Mz36D!{^WE5!fp=s$ zSUg26q_%$6LG4KmR#2pfkoaS6zcU$Fwp|LB=Wz-Kc&G)KveyvEQJ6rgILEJ<*Ngfb4ITz;xPM zYbae5sgSY$W-x2pY^|6*!9fPa##GlT6S}!HSM?rH;O^8K2%+!KUJ2Be!H`Zn8!}qc zg*{Lebi+??W(1QN0Dfg;>3ZrOwCstv9Keo56#!h=0Lu6=aYU^=3V51}A1*wdHdmX% zKfi8SqTkkIPJ}ERwTG_?q#-o$SX5dAfc+9mRbSNpbkC$CQ489U+(Bqs)=z};)(==g zC3p4mvmH0-y%=gB;y$t*BhWS$>|4HYox!dx%-JB5ve*FqhtoL0#f$7SS?&mVk9quIy&*G*lbAfIiN^8FT>N zWpwTOlQSs2ja$zEN6JqGYBr!rW2{ON?HmRAljH-!&4FuSb>~h7Q(-rmwx1g5)PZyW zAX2Q$D`>2N{_O&{nv}WU6t@1gyWZp2Q?R;`B;|Jq`Gr)h3EkmWhPv&+hb6-pT02SF=fr5$&*x zatH)GZF9Z`B9(eDQo$EgUd~DJlq3>|gKD9quGePxdbv9oW z&Gpl|;BJ%IOw*h0JYUXF6I{{?3GCNtY<5$r5n~HszMhZY&>mnSlY(EAF~h zYS%o(+F=_joG&;su%okg?AI7VDVnXd0lsC_%k~ma5>_+QT_SSKak>i2p>745aQS{Y zt&OI@t9g49^Y6Otr^n~p^V^&*^7(NnK?KIZ4uTLPv`)PTfH`I8<5N-HkIa)G5=_55 zscYKzLmg5YF;J%QaoO`60^)+>orqB4zQXn~H z{c_XS8CJ`sn?ZA}&r;i_GObkIEEes-T->VOg;LylS42nxevdg31}VbB)Kt#2AjbgvCjXke2Wf=VHe)j}c{agTRD9RM0Y?V1&)6gFQ8@viq=<&=R4;q3M{AHh4KA( zvnlJBkGsv6;g0=TVo9}TN(~1!2qMzDRCN#M?xd9O2|dX|uf03x9!5~cu*S7C-`vQE z$4;rQSIzMPaW}qq-qfmgbzt>NKPrn49L*F6%kv!0h-TM~biK`Hs%>_N^gQx=n6n&F zi2@TTQM*ho@f7Bh%A&J0rfG#DaP_zbh@_Dl{|A4{#yyTsXU@~{7bPI9ho9K|bv=ZMW&SOo1F(xj|Ke%a}&-`le_52L8wY-|1 z1{BOUhqd)3lgIf%0-5h*+5%oORMixAT|u(@PSdUidtuQQNe&ZR7xHH)d=9b{C5rgR zNb)k27kQvpt5wvx(lQgu<~38mYvOhJo(p22vJs?9#~2zRyCqJ zzq$grnv%VxxDE_QK{BTBQ&*;bFC9D*PADbML=Cx0_M!{bp@f=OUQ~lbA}aw>0wFz$ z8!$%+|HoEjtUid-xS{$q)*I-9yv*%uuPNB}-&tkeD$J!z}fgnGkEoH#Hj6sTJO zg&&(T&RVM|FnxY*Brnc+OAgF$-}AI)#^WoiHPe*%?qK1)BeBb9L=R7tW;zupl}9y6 zqB=)?-p|L{F&$62l%SsqiwUULx+VXKr^>eJ(83o2zd!3Wje6o?jfm{~ltSL**HGurH}2o7b=V-0N!ORb^m!4WibnJdI*lq%%nikre5NEiDT9jSdEAF z|9rT6`^%}rS=m~#=D+7RPvHbV%ZTFcTY}!R>D)jB+c6y}j%**&)(t1q%do#fqYwRe zC)-e3^~cg8ek(V9Dx1yz&_!s$n{DSVRNchd?)Dq5r6_2GL|!-}C2p=@BIo|YF%7Gl zK4`eMO+3<^0^&0D!al*-oouCZGh2C~1Q}bkIab9|uPmJANpZ}$ZklPf!#;N}j3gJK zY_OI8L_BOl0N!Ox{rE7GQEkL|1P8t25;ZH(q}r6$QEN?swRO0$Ww-IFr}HtF&RH7y z;z!1-t}*o6TT7)C+ErK4W9>K4I;+xoXlNSqTt@|$|I_~hU!2-fztSTyZ|JW;WR+ZN z{U!$J_7ZQ4OT$9XJCkZULC!zW;*oi6lP)PNi^9X9`_I;UAA$Gg82LH7`?7Da6BCqI zO;4BvHQ1g-`u3@80!jbBJ_ygHDf%t_dC|FvHchE`B^iQ4DHx&e7RH1?hwh+=yQh`_ zo@LbI<%yY6SZtDRdNLfz>l0L^X*AkIZ3I(bv>&(I4SJT{G=KSd?0lVhY-rdFHmtGQ zay8P)E+6$Os2*j~lX?;#s{-bIVEoe^+l^;PYKbs1 zIc>7?nX*0pGNxsQc<)<=GWoevs-sL+=@SHbIY#b)ZUrfbbXQa@I5?lvqcO{AX~_Sy zu|+Ld9p9-aWUl~L@{DuC1M6pXz6G1}z6aW1_SAgrAOSvRZ0m7p3rc4O;b%k6?65?W z0)PT5P^416AC=NtQDB{2WuA2FKW*mWw^Qn@O}X>QS=%~81-*esh-*?rD(unaXK+o8 zxSDuIO?1(+s+q>KAdw|Ip*|}=Wb{%%zsxy$)6yBCu|yi7u^~O-R%>6OgW07>3 zzFm|HS5Ae}_0K7V+6pIjAtV9kR(iSGD#dl>Hn-iUjLQs^Q3sBT{s&s8*5gj+bl#kF zmMSn2C?K&4e)e8fwm$6JJiw}mU+25dsZ8)>y_%N?Qo2W{+MB}c0TEHMm@@+&*6{y3 zWFzH4$QOkkAX9qyH6Rm%F{LQ`y`+Q)bwxpcrt)RsjqcvgaBQoTP@U2U06u1%mi-P% z=^@lOo#Bv7Bwx$}$lAzq^rFxdIJk?}$@^o6Yn(|C*!J9a zk)+nYLC9e}6C=Cg&Nry_q`{KXJz9{%ERal^H1gVv%;_+rdYmh819CQHID8fKWV!$anMt*A$Qd D9-Lj7 literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Fn4.ogg b/sound/instruments/banjo/Fn4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..78d5454f186699ff8ff33ca5538b697aa4f1f077 GIT binary patch literal 20228 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 literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Fn5.ogg b/sound/instruments/banjo/Fn5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..b21559b4656ea3a9c18e7ebf088c2ac9b346bc3e GIT binary patch literal 12854 zcmaiZ2Ut|gvTo0iGm=CF84!daNt9qB3Jf4Hq80|EjDd_B0&Is2XWzI)fVrdO}7)zw{9e^poa=v=#|50K#RYxC5fN?a@7D&iy} zz|+Up*_YUaP^td=lR(5_r46A&?D_AD*po;>RsP;$Joo$mx&}%9FcN}v6K5|cQ5~Oa zC^u(YqeJ#64U~kKxP+L5m?TO-$KAu(%g4dj!NU(tBfHuza?4=f zQMr}8zYD5EIZ$veO614v8I>rB>|@YnSw4`}AF)sX2gL+xsVo`|EW-^PPse$6z6$Fx zOOH#c>KkYq!pq;%IKW{xz<)L%#560?ye-7EEz*20(sDP_hCS-DUP!4-`)4HhK}_L$RL)q=)>Aq9oTY*amfXpnSc6>t_KK|B zLkqf%9$SRAL=R>66=aX)_>OAO=9K=a-C)Y4sHvEMZO2yf==+b^!0((Vawsb1O<-Ts zv7F`db{1HR#pm+3v>W{4_ctsmuI7#Q$i0Or>9iJw*Q8Y0<@dW z9DDzrFjPnqxh)HK8F%_gzhwIK0`UQK$;rf|%b1FAUFBd_*^@YAnSI$KiX%&K})+WM@PS?6^@tgvIq<6AOr!>-dP18=_$h;PtQ;~i5Lq!qwe|e5m z+`X*0doghzyR(cvMVrX#TfA$ziotDy`l!A)Q0N@w^r=XD| z7~_0Wlsqn&P>L_}k`>C47d~c>xW_0-D@VuUm!imjp)F1B5$)CjR)AGSD?E`;CJ9B? zTV|oLBufdy9x2cR04F{m{+QioRAaC}WmKH%4t_w6zchV911*xtE{WzVW3pS!E1u98 zEWxvD#@#7lvWu;Ood5;=(G-rQup$�I;RSQllgB*irOy3U)|*i35v~yO*awDo4o~ zF(giYC!7&o%Ar4se!>wkqPUb7KBg!D7bXG%{*(ly>{S6HKUnbMeU>hz$-<|}ton?_ zVU}5YHbd&El(e3K;V`q|w1MFZHf_UJK5b@g?QH`?W>rI0!^uo-!xr~vQV#P5hOgKR zr&}Ffu-!7w^nW9%Z3y8R{82m>L+G1~{1R z8XC`pXhN#K_B^YhVXNW%j=N!I$Xh={OJj%mT|-m0TjsNoZ@-1SWhZi;o%V-Rn;8e2 z`~GhPoO7IAipnc<1S%^lDqGzvYirDlRx67thZ?U{)>aQS)>YNItwU;Ud1a$;Wu?SWJG?4uYpWVJh}4dn^?vX54zb`e^l(|#T1Q1k zhsSz{_eiTdM{(s^x8QJZ{ZQlQ^^P;m{@i+o{;%+si^fn6cdNj==DU%N?&luX{1}1^ zCidi>d2+PFZcQF1U|au|&?Ot$q|$3SaHf?txs_GxjUGaes@IkD3_~n49Nx%SnjZCd zBa>u4n^;u2)*(3D4F?i`+3(5mK#ark#aT$W(^x|jVmGi$_007}zxNOM#c%$_b+lAZ zk|8z_L~Jk*DHL)GA#t(@K+e6wqR%MUhw@{@uAxc{#L2mRuVDH(@VXcmZv2#BKgu9U zV<0b`3FCyuPhcquOLZ}>h4>k)YeU(T?MGAz8^&1#KVjxl(LZIDaKw&LVx`1>RD-It znMi=FRtie!l`y3xESeY*qY((?;t56diV`M$jfxh?sWrV(uY6!vTAgFqvzh z`&sneMf!72^`juGLE_+tV=QIiA*<~0Gz_LDBMm!}mri6Ao`lgrx29pV;H)s1hDfZL zoA^u~)=e7D3bIPWxQXsOe0pfC}{DeiV#5iO4*@ZN?GinZrOe5 zl?0F3jVcPDBXlu>=txG4245*maH%<9KIb-uH{pO2`V&X2X>Do6qfmYZ5`sq}v@rY? zp-`hW{tybKeIsTrHO+Ghlr@nv5}JGv3XV08v&>)yy8$P(aTrJVKnev=U@wN_%3Wi$ z9g$n*kb;qsBZ6MAKQEkKiINpg1FlsgaEU@;$1unk@6M~1iaY>3PQt8 zI)D+vs^3f*Q`2YSTFYHJV_Pjf3qjnnoa2gt1lOnS0K6ol0QDp%RL}CWQwd7h9}0m( zK{Y0bN3qz(iLc}-Q=*nR7aQ2n8k}gm&3qU+XU$-Ec~Qz&bC^-WC9EQ zlijWwI*^$woVu$Bx@E>Tp#|z6Mu-{PcFt&Mz|xO8UD0Ir2M;$QGVqQv>>2X{(OhmRXT(gWg%=sb3%{_ z9MG^CYZ|MA?H7BcqTZ;VS0zh5)lbiLnItR^{__8O;p$6$J~GV5_3Ta zQ4(SlKDEkQJjCNB^|qHp*J%I)aI^q;&$+ClX9iGxc@deK5h*^5wxUO{adK)64(iAH z*r)O0r7Zeb*VR1R1U;QQb{O$T)p#R}Kx){8PjySc2;5PkD1jIww`8aSf`xqm4irI( z1_kwmF>wo0()Uaf)U?!3B77&DNdRNS0BvfF2`v+IWoVJDJTS4a9-zR{CMGt=)2vDm z$Shy_qaskG+%bI!mK0n#v&Z#!bUJN4RPw5&^nW(M2yhaBG&&RyPmWv?eKJD|W9pGK zrgUaJgf9RK2pj{z@sh>F#5g7uKUyT=Rk4pKdHkM~?~qI^C@KGJRY(u(e>TVjtv_Vq z2AMdFN3A;cxB!}8TuSoy@wJ7){{Dvpj|ZMkJbOGa*xUbvlqzuJf^x+*%+Uv?C)*;b z&a5n3nF#4^K9T%gXzpI+{iSIP(SxdM!auNf?A}bSL;TB!F1Y(i@u6O z@-=to6Yo1c*QqIt1O^DrqpeguIV(HfjieUH&sUcc*uALg?xD(qNuP-bzpSCVBxY)9 zBm8UVwDX9{g@xaIxW?c%^Ns$RBgUmx-&351RC6l=S$dCVQ=GVjc=Y~P`dtAh*=oep zharC*zf$rdgOTswtVII#>sII}KJ&G1>94z)2|RszD}dzt_Kmyb!4E@U{XVPjs`bmB zLgj3Hlsm4I&7kV0My!dNcdMRQoX;Je)*6iB{?F0$GI#&)QP1ldcE&@}8SiU{p0yoK!^~H1Y>nzP7g6g2A;?)AkT7e zRELHu9IXeVb+HPhGYcQAKYz0pZKPJ7NCJH^7Nr`B?L1IE~M3wh;D^l6D;wmJ|GCm09@kA zfw?~5@`Q^4@XB~m2_GIoedTs90xlmDK9zySJ@Y*RfXi=IfZM%&1}Y8zGcAOpZH0AqhTeyQ6Y1WR{>XW)MEoaQk1ioCGK%}sp z1Vb&a1u*_Nq?c|%S0J1us6KD10!4VV9Ha*NdAOLdgM6|SXY(_&JcCi*_-H&uJN7f7!5^UkB^pHJ=|=^T2nnm^X1 zO7f#Hl;8=+`AiFfJ4rzBCtjdyKnC(xB*6kJ$fJ_AwvIuu6B=!i05|=!Dde8NdzY?i z{f;U0Z+HL)K*}bo2$=%hzm>bw6O|5zh7Xj8Pu#{ZQTt#+7p^k!^)=CcKkaV8^19Xw z*cZ1;$DvR#jXD8n$*)uX?1Z6t!4-ky_h+=OE9JAet=$~`AdSS{DfMBYXltpO8~YvY ztk3$K;9})(WLU#5s{8AQ)9cnPg0<#Y=69{RF116$^rKw1uxvGNX(b(C2NdNXr1;>XPG zsUrT@M+RK`Y)ucI^=*(BBb$2^wOEfhNF%!a4d%?#T3-Ab7FOQpTFz4p`$bU15kd9) z3S_qck8Te#z(OsepKt>Qdi)AZ#3ey)Sr6UGNwJa(&2QN5o&;Z74`-iZi2!Bf5kx=( z4_Z?;;xnd+6Ka^9A6BP6CBc&M>sOfKlV#((kkt5Fv)r($Hs5fZ9tRVz>?soP_R1bo z;Qox3DJ|!7f%#in`s<=`V&q4!eP?fSDKp<63>GpQovox!KVI1^{g@5BcHn)lnKoFt zD7l*a^%7nvYo39L2qaGqK=6GC2-j%AocJ z641Io(UAxsR;KiZL~qP;q)}ZfHon24q}Io)$myDcP_rDT^%CMCo=Rtn4U9W}eXMdiPy^uZG7%>!P^HOFG)95LIam(*s}dV=4Mc}l zZ-7}5&gTp>s3g(!gE=HP+w-gQLSZcFa=sE{>XiaXk(D9ca~gX+r$f)Aw#ztdmj4i> zplIwEtauz}6m-qk@yg9qfrB+u+WgbsH7r7n5+9MiI)A@bJMKb8NYH0A(H5`%QZe(p zsBmeIzw%W#{ufFeISD|wGZN^KfiLX{(1-+i#|yv-g{w2YVkD^Jehg9bo5h!3#Kk%Y z0$eRTsfTgWII4*F1b%sk54SflM2WzymmaXZ-XSjw6h7GIt5^_@yvIVnVZ^0rcg|8y zx`}<4p%ue8q)GR@+3_5|o$XR3BNHsn?L%e7=UPsgBlAtVPxxYH@3~*+-=$F{8-|cH zncVHzl`*i$ld~WCC7i zVVnivE)oc{SW6x`hCBrxRd?2! zX&3_;^KLvLQS!VeH5;U_5)^x-XVvHPc(Qd|p2TyvPZ3WMUF##9;cp5zwjZAUW@fLa zBf#iXNev}p`LKVlXi;WNy7Xbk!#?z{Fim)j(0vpTS^(h_;wlq(i2ylFRC-MSHDA5I zW4$Pz_-QHCaM6zhuDpm86e^*c+Jx(Tw z@+_C3_5`u(G$1q?5!C59m(9(e`u>XLgGp%y(cR~n4wr=NW}3n8*0 z0mH8lgSflo3Y!4;P_z-CM69WB9d0x%INgP8UxXTh!ut7UrFvvh(-q!SKn@muhB*t# zBJKzUt(Q8TUuZgNpjIH7K`O6-5}v;5L_fI`GO}?~4QD0%>ua~!=?ghG3p#n7a=KWK zHRRmY4xVH)8<%+CW+AK@b4E~K=&O{n-kG2mnr;&uHf;qyH<$s8UQ!35<2RotTj}ms z{b1QbjL>xdhO3$-YXK?nK+=z8m)IJFp$U}}`R&y0*VQ49XA{LrMJO%wkH`4364sd8>%N>?>BD zYLqG$dq47+@hs8AHRz8r1dlmgN~t|fKr846k>0COh(`9+x0D!C*;nS__CMd7UtoQr z=fAr8Gu-Q7edTVr56--OyE}A3DEM|`Xfn66c!$A4%$3Zy3Wqe!%2UUj|@oouobl4CkI%wOe6>~FDAts zpm3ya0o^4Wj4#PPhIbT$CEWMG=j6a|=d`_B&aWv7v^u|7B56VAJjHp-Rk=?yM_-^F zZQh7y_fl{_zfwGZu6;BOOKi@mY8#b2^bLwXM2;J?bp7Xok;epf5+I66{a=Q;QuXxTqIHN70{``gYT)QvDnnp^jEDeD^SZLM@d@!U^YXzPNpch0p?QP*4_T8 z!GJ$?)xWAR(96G@viJfR6Px=0T-#X?k8pG7PqkIm=v=e z6My+_LRB;vLt~Z__gqckV)1?SJte(cJL`RFx!0T*a!noIcrMR<{dSRau>nB_W7YP@ z@4J|fi~3GKr>PNKY}5;jzmdR0K!M^Vg0~)1uqhV9eTvQZqp6LILh$Xas9$>R`1mI6p*6IOP@#Qyinm&-)6hfZ zg@l1gy53OlhU&^$e(AX6r3C*YbY%LD*9*FG-rltxtql1 zu~Tm)j7K>yr>rvN+ri8}NOfS=P;xn})y3o7>T?1~r|$-%Vdf z((RDo@T1OjVn@??$oQ6_{UuU~9vMJ5%YxcNxTo<(wb%hhwW_CTU1}#p=-km|BQUS2 zkHubpDg(a%sMb~R6I4o~>+0QoUdiJ?RmxQ)RH^YOw+*dV8YzQ)!T!AHJ-X7Q7%=K+ zj!^IxGVdK&qMgBt`qvI#4J3(|oQY%Jp3Y^Yd6`M`sQ6zcB$o1O+}Ca8`8+#&Txedd zwdob9<*$$!^9j_r+LJnx6n^Y)eSy1DX^J|HtV#`y<9>2q>vCM%{jZAWa}GG1Sm1vL$DHp)LEct3zz#{$E8We+p$Y79_ZZW8>Ez{>1U0=U)qp zKv7E-&w%|^JGLsBV(tW4ys zWt5BNbsWTAb9X!6CUE|By3?7@fuULZlIiy4mMa`==Cs4xug^sHhDaGM?TvJ(bBNkl z3w#%GwZ~?u>_u>DocK{Je{El+rAwzK!TyrIZB>3T;=sY}Bi=-$WIZr(DEyl8!}`fA z0M^-45MH+yrOp|#l*?{@S3m!AY2g^%#w>(cW+BRQSeb=4s5v=u;Ur?${#a?E!Zh{S ziImE!f&$&R66s5y>&~&!?WL$mdvs|dUYO4BM%UtbNxC$FTvUk-p!8DI0WAQ=w|+{<)fEjd^GFJq;Sqm8^n`W z+si3iSGioL2gKih!i)OD^j>Q-_*ur#qD<;gK1Xjbj=VG283C#d6^!>K^du$8p7Y)) zu=H>b?3Fx+$(MMbVxWEsyPes4kKrj2?=#3lpOiMX`cCWtVP!53C=BNBc-(YKRt>Dy z^1SD0d9_YP6pIzxQbc@CH_lk=>a1WR3F~~I`g?y$L%KQ1WlT+0hhK|YV1lrlRHZ(5 zm4$Vx>6EV0GO6Ch(F=2Vzn$lg^&cs>A!N_>RGM3e1&*}54$A+2ql*1(Utg>wzhHp% z)(HrrADbfDOPdcYuA|Ij7{+kxw*k&wK%t=G@$40$GTeP9){(ELj#t%kx^R9Yg?~BI z<&m?oG0-6cIjf`*d-SB;-UhQXqQA?E7@W51l#!|o${@9u%qPTY=)=tsJ*GZ^NQF1I zDPJRNBK9ssk=jXhr8Qp2@Ok=bfWfk4yT{wWePbR^$ehEiJ?Z88@s_e`oZ*2%j}V?- zY+uVbF5YGmZM?%nGI|wB;ZJF)e=$n8KX7Ak<62Jq`2^R~$6+|i8#>6n3k@LPU{Gk~ z<^K(Uc=B?UOiO1+%}{DTIS0pEeQ}Nw>jr?(dcO3*ngC608N=XFQ%vNQ$RRGXK&Q@lq&_l~!PYkf-JNK01E> zht_aFL(JXzE$3(bvSun5di7Gr^-(JJ9oGbLRaRrD3G15f_vvyjrfLS~hQ+l9gtVV= z2ujCje!FPi}kPhN2X5=G>)BV6NEWQA8CSN_t9+oGFR4j?;`Wf{JcJ6?+@nZSxLUy^&4k)n|C`^HQTPnsNVD)&se<6#=l#E zGprV7lbY@Ar~Oo1exX-lrA2(m%l*at8O&eXr9(!}@fkIw_?@@)jXS^OUd_|o@mcd0 z{UM}-yz5}`^XHx8oJSSp^sOnRKOIE?b3}r;cUhie86gW_Tz35SvWK@?=3=h@T;nTE zI!<#5mUqi6UzB<)RZ=Pws%xZv$^K}36@a1g9MLecr9fOV2$8W7t}#wKJ0~XdmmjZk zs&jlLeF1WyHf_0SJRUu~ykkh^Y8_<0^zFF>VY_kTIlXR2=5@M2X$k!!Omc7L0MpYz z6)W{iOW}4W{7N^Jm^9GrVqZTsvvdWrgv4LUwWWL)92P|dai6y?Xrn4H%#RoP!mSv# zG7E5Y1^(lEa#b-}2zX_0dB?O5U%?vnXT`YOYzMSNKD% zZkqVT>eP6hrfrQM+j*$RO6g~N`?_-!>v2iNMu)rrQWf@?y1w%rIu|XRJ?=D~Wi9!! z@uB0 zm8>CpY6Ykt2YIjv+#!dUIlunXs>CM*C$aHGZf6&s9-Jtk>wBDR=1k6**ka`|87P@} z<3ZD!Rgx%vOHgY|<<9jYx9+e84Sb@Y(l+h9`^FSQ<3_z~RD}5BQWHzd6>Z-W+OxOgWDW+&a3y&S~>pLB8Fjan1EoJeljPrWRlO;D_qc%BC*? zt<+>#Yh@*0{dy}Awv3D?rbVVTb_O9;k_hDo{g&IwiTr~J6bD<#=-^#bc3zNpagP~q^LGVVs_1l{|tdR!XwK&){I|VLFcY+lbr|CleGgc`mpn>D`lym?v7abBhLi8Tar63iE(H0dx&7d zI(ob@woqP(>d8Q zvT>Ep1DDn1^F5f-FFq3plsH2%EmWnPXB?hr8&Us=f0q@EC7Kya^@@|A zKIC;>GC=EVMX87RDlqhR2M|@A28wJozugf5hg{?w=`2;&eX#GPw(lIWeNO?4%(( z=JPI>l<2kJ>!@u$C`xa9>CvGDCTA54t2AA!Sjd92+PD_KPCJGt81zTa?qIYq%88~- z!`D>*5E83;Y2!ZeZ)9vcQF_uWf7WgAqMJb!B_(_T0Jm0etg2Kp_*pLBWI2&5f+49-ZlU3Q)LdLdbj^6gEX}8rakuf_u1|n33<91 zuer-Gly9&e7gZFhJ|Y_s2L5XvcV#9E2Jg`%us5hJThs}eNPE-@UcixdJG^|c?MXUJ zgX4T+&je3XGZHseOijxaL@wm+cXo?xrO#^VU#)s-U$JzQ%8DX`QM&T@+=BbaS#^CE zUp8x3?PApT{C2B0cb-!IcBcY5llJ86DRd%>$>CeZlwG({QT<0}xAUC%BIIhhukuQL z?43a-nbya$e14>{-*%#+zl!&6+5`SejMEO^m>#`x>5Yp+cZD&kNp+8Zl$YWu{p=t! zqnG|`WcFj^3DJjBO);%Tdq^_S4dHU&%K`QPP1}Juuol66wKViI5(jP96FH>OBKm?+ zEiE!O4=6teT9?Yk?s?kjQseAq8avna@AXRI4jHqc3u^wD6)JBG?F89{+hW@z5FH@ zK?Y&-g6C~cpAVwGSmQtv6u1iQ*s9YwQkQQZEW9q;;@b8asLtNfB9T;mcOgJkuP8Of z?ESQE{9CPtRU5AC=*0Y&4Cfmr?c0SHZ|cYIPl>q=I1ja%4e^Z)4bQ2v8B<sZ(QleuqN}uy1lmMnRJ(y!&l8WCksekJG^|dUzOu`6r2m5ct#GK zUa&i)Usn<*3$hYTmiUDAS#dsU8uH5JQw*z!w72M)3Z^)&#$z9_G9M|$y>q(;MZe{D zC)os?05woU|_RD6;LYD)|{J455xZFGD4ye3L0~gDOFZZ2GJ|%m_i4p_n_$Z1_us(BfQIpKId zk=0y4&}`$S`a9sYvwHNT+C1gF}gW*^RqFyF5|-RSO-81o_aL`u(X)v1%LBo&!8pT2)SaB+G6 zUB54#PvZA1 ztEqsnG*zMDyDH7jW5!AxJdSpGXVs01n}$MycE7EfVN>edkegoPFWc1j9L&adl4=z5 zyapa#EQ{(=e4KR5VXiD_b3ZV8`aGwS9BFTde$}&6dt;r`d6+X_7e7ANW|DvU`~B5l zdS7qO+HjW44EraUCB|RAGi6}wIyU`j>Uut2lH_Jsy`#9-r?K5QEQ>9_4}rhO)7c%| zb?6jcxki?oPf23Di?|ho+i2)#XBJ^00}E?`$*1ozJkzR6e)a1&Cg8lRej>Z8|J(fO z5yZy&j{Moc-HHnI{``f3mfFT2YQ{=xAJ^G$XbigT#K*@kXqJsqz5UE~HIGpk)8j}1 z^8eZu;;uYdt}qzxf7Lpy4_>O@Tmzg5>)8d`G)?hVLSaAlO&_t4Jm;xDI5zb=%K&HE i7yr}bnFF=Y=3?2#;(Me=TYf%F4w_>vvg#0G$o~VEy2|bV literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Gb3.ogg b/sound/instruments/banjo/Gb3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..fd055b747175f65014e429f816a2d3c69d24e9b4 GIT binary patch literal 22079 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%0DI8zPp<{wlrXKQ+ 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 DVM_+} literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Gb4.ogg b/sound/instruments/banjo/Gb4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f2c62510ed0398a3fba7bab2a979fe0251b0b303 GIT binary patch literal 24998 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%0A>6NtL z@?iz6j81?4{B!+YM|?tB{%_+RGG@V|FyRuB6DdBDVeX1=XS_3YKuQDfpz15=lR zd&hjo;6*~bO^e=M6p6f3Ua#%GgvOmmtybF^X;ta(%G(7JKC05V7tkpp1;Zp>Jpamj zk-DE=_?%6_fbG=Y_1zPU;>p_s9ew5!9djHQTa#lhCx z;rCm=MZqO;&3)p(*6+r?ui(wBNdF*uK0HQ4a)aEM-=T}Jb9m8f{8d;}KCxlbT@&A> z49g2zGI!y?EveNL5mX98(umDXQ{KHIs^epj;TgHTwR5XQbFkE;OACoyhQKNC5bv?Ffsottsc_lNV=ucqm6 z5k3%G0R7e&biT^C%#c{vX5$*)V1zzbS^i-dFvUq=XZoCJ9pAeqaGCV{Ja)fm-oWSC jae}%r?AP%(^}6p=eb-GulJFgcRrNf4P(NZchY9{49I&Jp literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Gn3.ogg b/sound/instruments/banjo/Gn3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ad52ef85c0871a5df23acd8623f417d166f991f0 GIT binary patch literal 24891 zcmagF2UJwgvM=0|2t$S;iZJ9MX9WZqa+V-jkReBvEGpoT6cLduk|bwvK%yuNAUS7H zlo3HuP%t4T{5Jm2x%Yhcy>;JSn_fL#-PK)Hzp7o`dt>hHeHy^Qzb+qpU)SNtLrP?Wk~{N>KmWgL81WAyNr-Om8|Wir z9_)<`@O88O%N}clRgjZckW-LT#Ny1)o%an4_6+enA1Z#x8;1I4sJOO{Eey~=E%K(= ze&STB4FJpl5QN1UGrWw%%QK5{mvS-<4{QB$H*zv>^mDl<%Mbj!z$$sL1AqiX9BoSJ zYa_o2Rc|h_l;9#&-%~1;Sn4E8iYjgIS5f!#70ng?=O@HPXc!z&0MZNIP#^(gby&D1 z3S8rYitD_=Ljslg!Dxx9qFA)T5H`+K;cZ#QDYds%r73FfaLrTNbkfZ;#-{S~w(bp& zshlH2CRE?#|Er+=D+d-@i#8Rv2eUTKA^Sw}ikx7G)jwik0TB`t7^Gp08Zo1dyyMft z=AWc2*_5Xh^-f!x*+5sAvt797VtCkMc$7m>{2#ZML$>Gt`^NhWNdP>g%fTSt!60EhE8)RlDeAu(9s-a}@m5m( z!Ab@pN`oQl&}|T^JDh1c{>7B(-$pnzI{GpP8TziN)*K+^O8p52K!rdCU+8Vdj3W6V@iM+!Df-6MaTZqGV&$Q+efgmny^Weu-S~%_$MXv&q~v5dX`FNr`esS*~4ZzJWn5Uo>lgoweg$} z_grrEJku8C(E2Zj`NwTm7sLL;a}HfZP&MV1VLI}^J*NnlvZj(EWRx!KkS=;D+xtdt z_1(g^)g|cv;W<7@l{rb3iAiq~Q*bx3eQ)H}bd&^)G;BTmf8PJ)IR?SP&<%NxUa;_g zcn(>fR|oQ@CMmPe|H!B@4JkBKkMlnb0023a-sEo_v9yw&w^E+BlD4td_}@JSqRuOs z%_>2P%>sZM03pc8@ytoVsoLi?>}lj*3!{ovsfwR)#aA*b(yKBEhNfzXX|$)S_R)W) zSmD@pP2+Bf98bYA^j0_-ZK%*dVGju`0U*i`$v@!=o-i6N(w&f}Eyx^F6)Vq}F%p-~ z=28?FsbF<~m0vnzG+dU+Ws+1-#_E2f9vTFwp+CCfsZ@3t9s__Iy%kzKA=7F?{B^3; zi2Mexm9c7N{^B(J%;M#|rzgY*dE>{lHuB@9v~U1m$uQ_o8>i%<2bjeG zB~W-WL&*dqV#203iSb-yGh5738dp-bw6+;#vzfQHdB$O8(<)-dW@h%q+J;TfhTUd1 z+svlr+@zA{vbD`~4x9N_&u1LbcG+R8ie?Vb&jpAYwwN8|vT)8h=U=SMFn?Jcvsr9a zwhXngwDEMXws8pebogdtw-99lQBRvKv)kCT+AM!PXOkWEGStS|&U5*jjRQyYnZ<;c zdr>dB4mmH*he1@=1y9$uuvMIIuCHH7RZT9grlz{4^;}Iu{h5-@nv$B4ChwYtx{;>) zwG9DV5VfJIrb()%Myj@{?q`kER%=zw!}^gXQeH#tR_hL3pVZdFz?z1J+NSM8>cjf2 zfuOC2a*-9{qZPI99#%hmcz)|)&{*p^-qM-kbt%tJBVFH#mVb3$2U)e!& zoO8KYc;;I|)43Df^*=`-1~dDrlNWe9pkWWrAA#BiK1*u4s-%>A=Rzy3sn4sa-D)~7 z*;luvZD|wboaMQC+}VNi{Oa+PGmE!MYTiAR80~^4l3y9Pz}qRu>-_8(L?~#gr;BnQ z`bInH|7;-Wr`oH%u+sbVw1c-HY`_k&!8U>~7LbG!RbYTh;0@+9vqV2Ol-cSXw#-_d zN+9HvaX)XSg|VMN=A6U;);h&#C_jVM*hf5b#)`VQ+``zuICH_uzp-M@?LD@P!`N3k zbH>rHdSK2mnZ=!1;Z2#xgb{6d^C1CZ^`@wdQQNq@3}a#}Z94`5xpYR$u)2)(v{7{n z#HzfE!^Bv=6?5ji`~ojDqKx&7k@x`S^f~E)T%iFh#A^6(^1pLzc9<4g)P`DuUUiUq$z!kKd#3%Mc2^$T-W zw;+Q1xySRlS9bm_xtpK#z=B)-;p7sHS?SQ^ub(<5t7gu)L9EiPlA#f20y-+P{UAcF z)y)7TxA${X2EhU$S&m=cSyHfA&lA*-0l-vIPrK3V+rvDW@96fawx$? z^FsMtz*MF^FSMY4;s}A>jb8p5Hq=@{f+gP6Sgbk*(rA4c1cmbcF-O1p<|RB$eZqo* zi3kJ*ulgrBj!*`>4J~Ndovnrn>0eI&NbjXap#SGefW%aMUrb@3;4F5GY@8 zt5aTtK-}^=*WVZ-_>Xr0u!5onB*YQDV`5yi5=tI_g&<-fH73hn!?-2Mzsc935%14| za-0gT!_)(M$R6e&$q)hhIRFt<-|!w5`5`I)otXT0jrRW{L^YIWvDiXS>jADKH2-Af z`mBF{x(EC#NzeJ`=YQnv|DC=6Z?!Z2^$_I#vjF&RG&T4`eZQF{zMkvwi z%Yjx*bu|8(_-0u=WS(LjV^y38gc5Oa2tJTUXF3|+4Y9J45Gl_-3>|Zh#?laPYLW5< zD?ex!HJb9~xx=ZJv<$_|7aVU&LoR0w{d7xKzGek=>0ffIlP{aGg8Y-qy$*69M}KJP z{?g(t3vS6Rkp7_vvEX)7dBKqmP|gPeq9G~hT2|SE-f7BTTMIzRw)S6bA8rh+AX^k2 zqD4U07(&${Mg-y^GyKyQpZZ^I%xZ7`fffX)H~;j@w9x(wEt+DeP5dYXGTh&q2vno} zCxQD5#&}jJmCJ-U|I?Pq3eE91z00&ZL?on|L&9IE{;kmp9IESYXMuml9_E4&L=lHk zSZGtYbVM*f>18j%!e_`B5a|I3TJqZxUl_vn=f`K8#HR)`yUDOvC8-)TdKz-~bIoVU zmt#&_`ETaCC0m*oxEss&)n(cmxoVoKc9fV~r8h?+=$>sIqkx=jT#%6TOW z8;?Z_B=*BFsl+(8^AT$d=IuSSYI^02|7?I^fDeFl2CSf9u4)S7ZKhP_G?sMM47N-N zz5q~QL?%EKMkOXDdZm>1y+R1DKSx5eB&kS{;q4{U4g8WE_Jsb?c;Rg9| z8k$C1YChbMsEC}LjEIDkxP*f2AL@foyIX6U8N zo4ALRG=Q1AGno2YpSrr=Q9e^KyKH`LC;7%bPpJ^x^C{%XtoiqkFWTt&I^T>863_>T z&{>HvsakC7d)J+N-_SZ|W2_faJ}^>!RWLp!S>y-LO!f_`urja8+i1sBmnuKXb^2M( zACbytFvM_zC8T{UU?-DpLKYtKD6jdgwC6pXkaMtEdFFeQvad?GFqOHrekG3j_s3W= zGvboA6(x7uPZo&yTzS%h=u0Q;iR@ot@XRy}$UQ{JZ^n za5J(wjnS0$;>tFa(HBmgexGa|HbS>ZXPE0;@p@I$mlnPrmLNS-3oG+{+MBBy#qsu^ z2F^qk$0jOzRlLLW3B`)GeDuElZNM?=smyBKhh+JOkC(4T!bWw#HcN}Snf-#T(d^5w z^_CN!5f=+GZf47@yq&o-yXkbz$G%37FXh!1$@Sg&P*biW)N{1`vt7b7(Y*Kn@G`d$ z?2qT(Uv{g|u+;QeGJW2gfswze`>605BdvOloWAuDBs^>~iHmFNORXh5CGO=tvk|>= zIjz-g+Y)%eM7T@MeglmSTjuYEmF*<<_Y({+Oznt5eb18C6@}Bhw$==qDx}b7ZmHB! z{Y+!HREPnY-y5Qq&OMh4)%}sIsa#}GanCQ&xL@}P|2Ny>$7ufJ7y0Qni>dWScO>wz zvERnuMou;L)zI$d3iML;DJ|5Bclg8ue#m`8>6#nb+6=!4wf-cof+_nRKDPI>sPq1g zDN74?(=|!=?kMZQlzh6g1t;bQnff07lzS|J{`k||n`*U(pHh%-BlQ-bjy293Gz3=e&6T4*cNcJs@=Od*^ESzSOraw$2xi4(h_5Vqm_r z$1mO!Ja3v`j|Kr(A{QT6-=COD4gu}$Ht7RI(G;D%S4^;r;1RTg@_B!s!OLX~c7$T2 zMuZ)3mBXO$NY0)5bfE_JE;${JIYxMlZdU>aoGo)(<;%L5Y}}nE4nL?t5jq7Hx?`ocRMgWg8mB+@8bwlF;J-Mig)%n&Y73B?#k=$h}bVPPNL0kx+>S z_OL4YOE=1Tt+2*S;pj^bD)E79G*2%u&Q;PV<&HM2`D{KxtF5wc!lk~!!ddWgMG+Tt zItnF;`y=`>$6-12a6A<1iU5dUdfESTEBnam0nYLD^T0hK z90Y(v6&QbkamH!8A(nu!DkI+m6y?-(%>CG3k!60((F6A182xW%7HyBh*QruH;Xjn- z`md9_V{G_H8n^?OllxhWfU0zZ1r-=THFS)w{Sx(CaYBJ0sf`7WV-$YSUgoE8`bNrqnnXXC z>3r880c4@9*scN*iT`tCb-I_#K%w0Pnb*KQICu;TQ)4A7M#ce9xJcje?D_=KBHWb1$xLGPVqq;kJTQNl`CtOiO% z>2R{x5oU{Ee5J|~Q3gv(79!A*Z%?7r2UCJ^Rwi(=LESDvTZdY6s{gbt~@oKgissrffF;=Sqz!wP?Y1mh}$%+w({*fH>K82 zU~x6f4;a2kCM>=ubTC9K>s9^M+TA}v_PkR50i!+&w~r0~AWBz+qr~tW4j*kT`CGFr44i5V) zc-zPpLH_h0Rr_`cUS3S<5=#V|dKz+=dhERRb5&oe6-otj8sx`KcuHCs2i5c3jZ{ct*gZ-gWJ?KeeWh7*PTc^YFh< zC%Kg&lrgXsJ|GEvVAaux%6I27S5YC345;l@z-AX-gB&^{e zaLv^wO$Yv~6~&7JIO6Vm;v+;VQ#CMr+Zmu@s`TwFlG^K!h^r;Isgyk4cmMnB3}*_J zE{B}BRdV*Z3auMP1nO+tfum3BZ+Oq1h96|D;J>HjBHZrfza>22|6tT${L2b@Z*mqq zB**5OcS@*`En$I93^{U4sRLcHFs4h{7GoG@5oKA-llkbhmP}r-52w?GcWTG@O#%U? zIp%jSMFWT6x6Lzoo+9q3<$EDO;6)c+a1W>ySv<@0xr;sl%T_{9Pb3KWvQPX#4pap; zSw=dDZy&(9us>R~r5ym9%1@Ta&wFTn19XIL7Zsqa&eDSjG^q-GGSsllw#Vd?6tzeR zCvfpG8qm`y>Z~bIOCv`}R%krQ`PMybQNL-D9Od}K#KJ^R7({3Du6OYb7qfSWUcX4( z&;%gnxCrY{c;L9bh11i7w;+-e@LRx%W;9NWsiLktyK+nv;T|ngIcVa+^=o9*)AS4} z@!(!a*xL%HGNuNnk{SEq_o%xr#JI>~PZ$sy5z%nj_W&fnUWG9WaS#zxoqX_e8f+Nx z@oNjBzHkQb2Ey$rIg#u}eel9otCeQ+7)l0w?cwkNG-NlHa_7_WY67vE!?YHn@iHIo z%ih?q_Dt!HBhmrlPO1R=uK2Cx8ku_q3L`FMDUCmhPRP}_epuJ`FOQ!obCYWMG=jg1b(H?V=NH{-U5u%l$fcVd@NiLGEWaq}mrubuH*u+c{uk zpRKM~=5Kgi;N|!|ye@>R^NeUqG$ZKpTp|9U5B5zpEw21<{mMs;fld@4QpYqTF>L~!g@vJ}Bo?nEAupjMJWXZ|1nI{i;q3l;>!r=`7O=d!o_ec#C_ zp3$*DZQGd`?tFh0-y-t-e8A^7zdwJr^;Mbb_ z?c@x5f06@t61I_r+@vS&0Xj(~#15(Mb|pMsNW@%A%?3?-@mUTOL`1xv}7lurMrfoqvR2h?@8G z{4P>^A}IV#?b_sAKOQau{)Ej+(%cjppAmR-UiFSe+V|F4;}*d#Tf2dlz*>tY(-F>7>;g%EIb>*y}4iq70EU|zH$80Ge67vXqmm91M zloKndyp2gtbzl*lDRMhjO1w^^m?%JHjchg58E?7%@lR}gHRW?^1ho`RI{#77ge2V- zB+ZNgS|AK=!~8;<4;~SnIpADhL5})qoRnlk#zO1W_t|K7M)fqrH02UeQ%H*~r|_U& z@5IX!00!c8!Kx6~x^@o#SjB!MLt^m*yBLGtdzNPHtur$mTssYC8=Bu`%{j%dQ9>RF zCa%5FDi1jD2G&*$t(`z(uezh7PEcOxOS?(Y&Y<04W?3UZ~Dk;z{9@ zFp9!ni}XfO%-|g5Mc!aVEhbdiHeQy^yv!h*C<+c=ns zbg0$1F{KrrO~QviB@Q<+k=EmrKeqKoJqpY8hg&|cC^=pI)^$!%U-q%BQ>;KhbM4KJ zqfX&-%|zKJD?10J6hYU z8n6ElWLI}_Ol_uUN~1N2Z+!u{aQ!AAz)Ty^^jGOJ;fy3ysa5e0V^?7>zVrS*rC@Qt{e^WNG&x?d-+CZwVKE9>l& z3B>!IPFvd%&7UhY)P=2gLZvxX(sXxUzR^aNmlT5o&oS|CzD2h$!B`!qC)D03ez9NL zH^`Ih#Ap#lB`2c00SwxLQD7o~>@!vTIde7%g;EboP-|QIz-WQ|D32|r)&G(RkQS=y z=*#BBFPy2xG?9p1aIyg2=}ms5L2{r-u>s76F&i)h_HYYM42hM9AvA*X{AV`O=i0tN(IGW)eX&Hmeo z$?)p7)Aq349;mN!H=d4D0M{N9)Ux#Ook92Rzq`_{H zOiBxlya%E9eMdm(ZBKQLg3C<{T-7M_*@52f3eK2tftL6Oe2c&AM}WQ1a_A~ASmmG8waG~8`7sZn_P zT3%|4LrQb4IG)C;o`KQdzn*Z$e3$RU#&pxk!a|#nKiP&QPV+zds{IrXe*dyCtbNvK zg3VTML35VuKY1r-O1-oGyTYxow6UIPZ+RxM%3v6oHU5y1=7r~&M0dk(nKOqIS!yHh zO0nZFO%!Xl1$$uB4TP~eU?Ltxfo?Vm3jHW}YeBW& zRy}tQV>c;#7U-VHT+wh^!ruZN8_Da>n$5qD^)4=jdY;{r`r*F*^?Q#LN5W?IZ}#xo z&L@I3)2h)kpF2nJZe&$d$H4TZ4f@Y^)bd;9beE1)wxT?;OmCH=Nk!P&JngVLeg%F1S&jNkiN{l+o#w zl^8iFhS2Z3+?(-mX%Gld(vkT4K$Hz6yrhbdVJEU|tI+};nVC>*n!Df;J(x<5$VVMS zA$5@hb{<4LE-^f4E)pd>#++y+{n6G6ArlfhuY;oP_kf46F8<{wS_XR8s6zZD%n{6A za^VsY=!M)#W8W~mJ~J$vnSAo9d~wq1f?Uu@x>%j zr^Jl0i{4U{qAMVCU@XCR(m?Cx@WNXrNX#sk?&{%4`=qJk`T_16OaNHh!kjoI^iNJX zJ+uZqE5ZP4Pi?wZH_NTY#+HI#HoSP`(+9`2JJBm+_$XBxQcO}suRn*1Mp64Z z@h&izh2u3EVTr^Ga9bBp3a267qOf&dyE=jG;@4HhC-C*RHkId#Ux*B3`;zjDfz2;o zX~Y)Z7V#F*b{Y5c;2K96_tO}@nBTwW9~XruD6cIHqFjDkMV#64pR?n0m8?NF6Ro(E7~ zvdEfxAFhn#Q5uY+1NQOW#Yo`8`qbuyj~Q%# z{k)l?y<*y!@LdWZ8wk1pA`_e$lWs=m$m<3p0W5IXJumKepo+xD&A)*oAfAjY_u@>xsef+?r{fE4RbJAr<-r*NlyAzu3tbbHW z@|;}3o6thO*6wm|Irh6n97#Hu`2jzb6MI#~AsVMPpTG;)Igze6y^iyw$+3l%_8oA5U4#)49tbb`{GON& zhfW*LE@~LZ5d<>c?KTMuI{&@8uEOOo8P!J`bv6ddeRb3 zUoq&5k-_}vP~5GwW}XdEGAaJd`!>6fap0E&rgyRAyK>oBRFnTKso!bzs`A8e(~QH- zVb;SC`Q7E-eEPIv{L?j#&ycAG*oixI<6q=72C-x;FDuX+xg9N7R{^AW5wcW-7H+(Wfgfg6y)W` z!!$LXzd>Vf7|1YtokW(dkSz17T|}+ZPT&0;x%1nV!Lvblx{%ATZPWij=7W2j{F%q~ z?2T;)hMIFi4}DBxbtgLabh-BRm%_)cLJ6`aV)q-aB2I56P6m)INX0;&5bvgC1$YLZ zTu^*tPx129W=j9HwnLH(z#dfM=2&%~8Z1Tqj;e5fK?h+_y4IRXb~=>mV;w1Q!e z2!)j?+`4tAZ#$!a21XNc3j3<`IB&`%W92y&?k?o>M(wcf9yx@4L3@R=slh`Jb5@#|^hy$~#U>SzDGf zlEsfe!a!Cs&+9ph(+$}kqo!_Pb#WA-n2S(4=9IQlMYp+-WCVp7P*^*f7lctsh68f~ z9cq4o z)3f)-%EuL*t=Ln=EQL%m78|+qA;op%JL%cY>KyM9Maf)rYr(h5N|bPCL(gdtxauzk zWxl*@%44Z%lO&q>T^IR{-mwSVEpO4jy>g#-< zSy}w{SsveY>9mg>S;9^yvA&vLvY$V`a{trT5r>P7M=Wm+$PH6}zDrmL$t36M)Q(%~ zH!5uXZt@z_KIdieK;P;mE#cUqSc&&9)_ORZ7JL2;@!eoAi-txQ-a8E&Ac8 z`kBBCacisnvPWnd)yW?%0tQ^j#lTb3B>zF>{|OIjtQ9|5zg^5Ex_B zJ_SQdF=LNt^3+SAbd_1T&#yEDSlxa5T_hEbkIn^L9JH+{Ckr^G<`kBRjdCW&3-Re3 zlK^MY8PuN8kP_H8MFXM>bHpQQilORT27Wo&OOF;l=`CMRQC8@@;WD{oP{JH=5 zN-&d4o2T!Ubn8@hj3Ru{S`6_iUAffM*pafr@{l53x!l$1S1_bN5?(t#s*ekroKHmh zWMGeX`-pRR3Wm6d^{-lbn=Eh7sr~yzfdXw=pzH99iNh}`{FIM2U}l~z%}>sbPESru zjgL)__DzqDkh?ss+jkVbQe`AtCHPl%H7KL(hL5OW^j+Yw>&%9qxX^BB!YZH;>9W5OLD(~Rn~S7M8~ZOO{2MyZ za90pmFwxTgxx+|fO&EQ-B-h)|ds(|I;%z57?d6-;N3)mTF-tEM9~0Auzuf0o;^}bI zDRIsJGH4yUy}|K|_+yy)c~O3o?-SyevAe6>cbjBhGQ9QX`=b#==d4$K1fJsi+WGkU zL^$KmlfJ=PM#X=iCxCV0j(L7jGvOQ6e(XR{Vp{58PNh|Aj>`?TPZ9ss%*o82D^8rT{fv?TakfJT zB7>GaHc!6xzp$Py2)j@7y#AyXUQ}o{Fe(&$xc{s=OfJXjW5M?KhZ(gywvH0QEuAS< z4W~kuP>!&K*G6A9SX~!6{GANawQ8AJC2~BeH+9tLJH@~8Dly`Y2t|kozwA5crSiB- z?>yvHr&6$?^30A=Q~!z;r(>bu1Rb;~UGJFmFDTQf%V-&c&ZF^`H^^b)rqmhD2~@8w zvG;PG_?F{WnwnPYD$DO^2e9lg{+tN2t5-2U5$===w5aFa;*m(uwQhbg`S;FPZ zDMCrslba?lkhg{uw<3&~qUluAUq#T9pN=_SYu&oJIn_=7#Vw*xXlhl`%uM!$ZvfV& zTP7*z!)YU3^`^C0=E)WQ=9n|J!Q}>?$#PxXW0&T?F4p(I#6J^y781)_NuuW@`P}I@ zx4714ZnD$5bo_WOYxTUn#)h!W+$7WX&G~!T2vJc8go(GE?|G1v;^F+ilIvsrBz@Xh zcYjvpF{-3cfju~iDEx60SBztxEAT4TGRoT^@Aks48zA3zsi%f=*w+NBTLz-hd$d)^ z-5!nz)7}r!m|InlLXTl)v8TuY$-0C4q?5_)EvTYd*M|_qlIL%*pTJDK&XI)5qY}H5SD-Rm>4C|$1o=SPCX_Vc)VD&LfF+@En zr@g(TlO0<+f0pO|22@*ZLYnJTGgk>P0*N-7_Pj9Q^(Kx%eoVWF=sbWWO-HtwecZYVnw3Ayol}a-> zN@L}dY3rVP7h(TnW)t5>XAdcU*KdaFO?>QCL%^!+1m`(Z(V?Sl+>W^UQI(b&T8BX^kBo7@EUWdF4p@XfAFV z4<yrAby+^GMvu)UjCW=!I1tyIRSeluj1 zsS6T4*Jr#^>m*mlqPvKef7TQ*0&7`g`z8i@8;+SDf>VA9V&^aCCpRk$FxyRkfivFX zv$%8h=aq=H#E2rR)<%Z(TMwV4eno6r7+r8ShmNEmuuXqkegROFo~VyO6n+s`tq2qc zoFVCr4?w-1CTHE-*FS=;%DvW2h;3~ztNL-fr`>^2tMQZx;j5Z##v`3-0slTs3__i( z(5^>2#hk`1aVF9M3G<^km>hcfr*^6grr4AYde_^;lNxu&;ET$eBKeaK+b(wAMrxFK zC!F_;yp(*@N&Z*4*fGi*f9u!UU#iB7!^~`F7oU}1;9y_+`SC~>uV7)f1C^U_#|s4> z8dNsU%+%F0(~{P;n8&tce>ws`+`=~|4i(TuEsK+nk(tt8 z{8gSNzGEe=5{ps&%qVTebj&E%HX4cd;zG^A{A>G0&2AaQm_$*_%~4 z4+Iv1#6_#KLgJuid&2Y12)D>I>t}U4}kOgT%T2I7&-^Q2VKezo>SNlTP>~*kiX> z0)~Tv__#>ZntWFi*wg8^(_pWR9WR}a~4p4X0@|t2gzRE_iaKe2+iHqUqf!jHa+V(KdzWBF{E2Nn1o&w z=VLru^7Uuw=$s{Mk&JFrvWdrezCEC$x*_6n%HE?z@|ov5l1Pf}j_j{nWWUq?IXr_PMmR{2D3M6xEb{~G&G5*IUY1I0c5z+QUb#JUcNPT2Y z75rN1*2tg84HcXUd_RSLp-ih?W^wc4mE~KhE5-_;-=AEi8%&7S{S>+o=Ig9qX%n_a zGv?A@t1HhNXKhc@PaowOc*pjWFC@=81h&V+SokmKA0#7nC>>L#MJlawJ?ccWb)}|C zKxUB9Q;%sBX)w6B`>%>IlrJ*k`a1cRYMh87Q>joQXevw8#L^Xe0mvL^4^=p23SelHe#eEmhA zr5DBm)jO4TUdVbE~m zDfcwbr&fK%r`J_^m7=&BO`xc@-t*?HSPa8a{$GfLW6_Lc6L{e*x9Mj&*wu$gmUJdD z@~*^g3yA#|?;eXOg8XLXN(ml2n#<3N<`UF zRWa3k*QA$kbGHjAk^;&V4l*tL!iqwDGf5q|y_jEnl+R>o#J+2ci1btdMlD4}1bv?0 zsc24~?p?PHNPTi9=}Q|zH<0tbRI`bx5&x^NC4^col0a^^hJx0O@MlO{{kIRy@&FG$ zY0)P7)9X8nW_LEjFxR49%woSOjJZOuz(1TzSDwxMYNZu??QOs-#8=7$>hjx;%;hrG zw8#5=^;Fbvd;d&KoXbN(FG_SNE%%R$-{JF@=YMpw5`9pgw$DJiQ=`wAXZy_B)QBaDpAD;wl#xy4r#wDEvJDrrFg(TNaP=-UOAQYX!Lr26mo*${A&oDeHpejS=ruWG$;E4b$?qjt4g^VLAFveLe}( zn&xFt$-SalTX%1&UhG=2%!{5{TZ1|Dpa#8O*7<4SZLzj6nGv}PReIU&*6TwWjknLJ z;<7wmRP%1SXB}&ZfSg9S=jYR%GATYEOZtxjqG?s4``7XAIM7+1`yuSsjo=|3TTsR> z#6X`mLu<*wYtelbF>|_}#sN7(k7eS>kF{_)Lxlh02HipeOk{^lFJB*at zb)msKY+^pj#miW4@y;Q9p~J?IdOGNs(iQ5*LmukKH9R<&{Z8a@mQHf>*S{yu2ZdZAY4TN+7% z|3`yh$kmf84zDoDW;BOl^n1>IUrvEOxFEMntCH?w)2&Mx7Z(>o&jg+kF;)24xS${Rkomx~ zjMBK6K`*#q#TQ9?lJOVK%v8Ib;Pg~cpFZq+QnZq`BzjJ|SF+yhgK)pcWuBTmtpjD| zN!WKdZBzj$xCpw{Ex5_))GJFc1Vy^LR3f6NbEcVJ43n2W9{8gyoxP(jYyK8L-IE>K z${S*}Q+3&AI5UKs6~5w%`R?72?bTitkXm7kukJcA#u#Xrom)>I9$9t#_ChOig7EmM z*VWxC>U^T37t!lUFB`9>7k8Nu`dyVY+mSDA2iAL~H)j`K$mjMi=?OH#3O$9VL+ZpD z;S&76$M5RpJy)jUKAkvfz_dIr;jrCntdIXB zsXih3^;uEeMI_onF;$jq5RXkJemU3i<3mwU(M6fleFqjRR2fxU0JAZ|uE)+v@U=!=lvvH?yNhN>l%RqM!u(uM-6nRFiq9s?0t$Fg`;b z8JHM)GB!NkKQJ~j);~BLeVDpE{tXi)A8t{pDGxJ6$q%fEt3PZCZIj@;Fy|yT(hh39 zjhVxYG;GbG#4lIVE5athp3{nGE*6FzM~cq(7_j-KW5 z!NEU+*7_f zYi@N#k=)k*h1X}2b*a)m4NGZ=WBMnox`oZfeCO`- z)$sLWzGC8G2;%ec7IZ~hQmI;feeu1kB2=lE@c8#7+#}xOI(r{~@>Q?%#lG|Kes$(x z`-3Bz$`$^?Q+K~(QWG|{Pr0|YgR~ZoqQLf-w4V#wqKEdPoC_CH;N?O+lSTY4AstWp zb7QwJi2OQtloW+GSl0Pfg5#$z|d8?K}maF(?{=YlcG71CLwYeP&cS z2HUp7=vfIRuG+_#p9;cP<;50q_;64-h>m$?Nl2czUYqTu3Hka@Ig5q&$7!}>EsSsN zihSzjEWK%$ZBDIp$L}p`a-Lx^~v~`N!&c zdu#0ykB^B*7dTlrtu0tRJ2~+Oh5sS?nEUL~#h0VT8`Y|GPozHk(fj+$^m;?^il;MQlDZ81>cyuj9|fl6SzplLHSxLy6Z4}c z{;6Qs1-2W23H2?&FW~e}@@l})BSZSyv)I^1P5O~Z7b;yJY zz?(pwSw*p<P*gr68g8N{#0jBcOM9W+Ycmoge;EmQ9ZnRWWyb5Vv_ZbVpbKvI^>T<_Gm411`_B`DA}N!zYUc%soIn!Mw>0wL0zIZ2 z_7Lm+(BP~5PQS`+!)d91f-T3kGZGT5h^}I%SWG*Nor?ngWt8x?w>_~~(8_u~_(%Ad zaVL?GfM*M#IBnu8mZy!NKtf@(y_jSd`y~;lB(Pug)*i)B>Ua|6jV;JagxUb+Q-J~h z293RngzLrPI~sr>T@PLzQQulubdof|u=b0!u;Wx#1*Oq2xx77>$h2^YusLG-H4{Em zfxcquBj~D$C>mVrj~XL@ZpvDIFRUfWU~{@Wh;yewu{a9bkkw#ITQHO(EDLi1>34wSAPJ0}TNMC)Wkke1^#wW=iZYZ@R5qEQ7IZc19cj-6;4$Fsnd z;PyWZQdWvu=NUgfG#Iz9JH^~&;NH1w>x=SG?y7Th5xBlJ6;X;llImcDBMd7s*wR91 zhbiNyKJ0GJV^2AARbv7kWklRH@g$9iVVOSw00kQ0dv7A3#1e=}-Z^CyQve>&MZ6+r z8W^fKiiEg+$PvTy5L+PS6^{i{V42#CXuHWWW}cGrI=>25fd4|sTL7&XBqd0zmrC-h zk(8%ZRu*HW8d`MKZ=+9_|HOMyeooDjW=a}2{1cA%1|N~AQu5i=MIWt1-AlyO;(Ppv zy8GI>L`j4?t&ch+Z$J1AOUCvyE*Msb-dqXCxO0r*WLwc#`y-_vtAs{=o{!Y` z?#1}3`r>_QCKCYOWn}nz#*-j|ls^D~UI2I&DNVF7CcZOT8w$X)MiGYzQ&$wEIf}pv zAnl1g67x6elvKzx>2Hh-KZO}rNR`w&okeq$=e9<#0pDJNP}?nCE4SlU2g6wT8zyt0 zEMH#^#lw>kZV?zQ@W*uY$7~w0U&{)cK?mt>8+P#I9F>MAlWOsDBUp$g!p_i>S;l1- zq@oP{)BtDyUPiZi<03mO4$+jSI|ampsiahX7wRoqsyVQgP>IF3>bHu$F0j_6@M&x{ zW4jDGUS&k+k$DFm5~zHQpRtvgxIl>o*ewO9Sg!K2b_oSulTwZ6P`W-Y@n1rUn?(c4 zy|txS1ndTi%vShL2W~4kg#8=BCSk%>VR!~)pf|s*y5{RMyVMT@;}|?%UDkW*n*+4? zTLI7oENVI_ccx%V^iq-!s?X3wb-0RaE~*^vx%`$+5mqwFG(@0Eqt#!Oa2x?OZGzLf z=sF(6y&EmAIjzK4AI>luV30YG%1cy2DA6RQbl0SeWhum~Y6-sbEj~)DMKr@7h(zQ- z2YzKF&?EIG04gtW2T$Tp=@ZynBC!C!Dv2?1f+-LqfZfS=zVD8Oi#Y=~2h387Z5PrZ z+JS|72gNc05E8I6;2s)%8!*&9m0j1Dq28?(CvtMpekND-Xswx<&UmWWCCRY#CF=*( ze7h+iuE(_tGKN!rD>E_<>36B?`vg9(^XJGSNNIY9^2i2S)6TqZ~}g1gz%oY9S;E` z_yGX;ih|n`;789@LOQD`08_ExS>om&3;rXuDJkH;421_GJZ1=-b-q^GnU)$#&MYlu z<5MTtWCIpyh>nDGEQ-^u{+3AKVck_^cc&GyT)5|>_{*Q!Q_rj1J9DV<`-tjyc4M^u zxvt?qk(cw!Je(2u$@Ol(a(ANjy&`9a zi6=RF)CFvz-CQ2Lo-d^^EavFfQ0LR`i&`prY*L^Bo@Hds=IM7Z%-7Joo0$R;B6);BAFiVeT6`*x z)C|icmZfjDq3u_sB|RiSE`PI!tT^4=f?;=ks5NTrgX@9B)2At^Qo1onYMs3~q~A9j zQKfejWektaE>2KP7!&0j`ar zqmAW~lASUX=<0gQ4_BhAb6k+A6O4vJi**JB#uUk$73!G_qg7yEU>Be$QKke%s6-Z+ z>AF-D_3sUL{j+h{UkJwfW<8{9zM!E5ypU$CN+ORY^RX;!8LoWzr2Z^o`ne@egpXOY zdL{w$<5{eXc0}1VY^JAL2ZaTS6#1XAFy9%jqvnO3lLV89KtJ#B@#_u{FDQi(i zpI+pW;Iv(*3foXYj`9Fe5?qteZhu~n#>mxZfj zQs8hxdGO|TxDeeN$sMe%wx-wf9cyh-)k^?W-|0=2o(9~vWuQ7V%Uq-!$zRiI1zBk@ zGWuIOu2YEJrj_Xj?p<6b4Fz6h#Nd+tB;f_XgD=p5UkqQsZJ~e~{gR!ILQ$X-0qxx( z@y{tj{KXm7y5Q)YRIS|^go&+Czk#ucWfXLqevWZP$wq$rDr5NcI#+!{i@3dKU8A(j* z)e!$?n4%oYT+|qymB`AwYzHK3?*&~%JYkwkjW~iWHG%X`c4U(XY>!stgZkBxp3w&N z6nH7^RpAyCu^32ZG&1wja`_Ev?c>$y+P8uCI+VWX0=F#hPPbBO#b9t((#P>tCIEhA zlz4mf6?o_{(D(rWxEip9G|^TiQc;tnq5ynv8g5f{UtQJCeSQ`&V+cHiv)iOF5mMM2 zGe4^vPj`*T+;o(HAmJl4V8~<8ncd}3RaxUS(*4rL5UyjFIPwWiM$S~{eF08842z^+ zq|{HR#thQ6E!>G{p*D6wd#5e8CZT%j2y=B0i5k6C%>y9)QTlpB76FIqhYPh})!$*i zR!chg$IKc!uWUIk@9TGS^uMjPfjPF9Ar4XIH35vQ)HBIISwyqOd2|3zXJ=CY1OS8q z000000B9uu00sa60QsYWzZAd3zRAbI#lz9a(8kZg$jiaV$-CZVbmH9lOgvOj`QSg% z@PB8z!~*OV!t^RN&eKM-qQIms+2|A14(ADVeQOH)Hvm^w*<=d9gGKPIlwv4+tN;ey z4VGE1735HZPBH5!W*V?t)zV-=&Yzr5T96!+$R*OWPQ$#VNCUQ?UDN|Q8po`)HA`1x z<4Hb-LbAtF-FFg<_4_vQKC1Rt9ZE=lWU|+SRFWVl*Tv_OUMe1IRr|C~(V*Je&}fnu z+)Ycav)h{B5YTv%wzOu-_9g740-j}*dYf2Ddm|nv;J-)XcY=Ql@L+*43p$kDqUga9uhq~26s+WOZFua z{$6PxHjw6-A*@IE>VJj3OiBryz13@3rc>fc^R#>Tp%HM@Jj-TFTz*AZ_u3bQ|%j1X{G>clibg9w)1EXkrwRI z+JDwO?o`e7ETO*biW&^{HXY$PfgIF#fbfu8+?XUVC-_NFNd0&){FstA7fi3F+YTm? zGC}6wX+beZtR9EJl~aCa=?9*p`92J?@x;oyllsGogZ{4BferxPWt955_dN+& zL*gPnxF1O;{yWnJ0DO1VMn9$@<0%RxNi|pI1oXF=R_yK*{P+)6bpvbTQx;_#C@(|* zMGt-{;RwpRz~3a#c-keHQs7g|Ik?6gs=9H*>bjFK5;6u*X(oPL-ul8voEI zrta_0s!^UnlFl0{MfBp59H$Mw0AtUdhB_!00hdq`0NLHnBom)CD*zU4XKV|oV0&we zKEA3};BM&{>QFFf(z$q5V9sF11}XtCeJR`=X7U0TTfJWsL0D_m!lVh86hW{>dip1}Xty*94UF zL5pY&ji&fB9&1++|U7mQjC~pnh>5saeA=V z^?tkxKm07U;$eHxTR4(^l|A2n#1S+)KL4`0Y^Pdd>U_(q8I|Mm4NfNtYKFi48?sNc zNQbnB0O_#Yxaz{VC8DS4-KGsKCEHKxl0FD>o+l(tj^N7F{S1qe$}^PiF4iwXr#cn{ z(?+0)A*&VyCuR)*K4oO$Or6965|eqzFTp1MyS@N>O8|gezMp8LSy2E*v)|#1z^71rPm9q-fqFb*|NdupK8{A*!QkAVZBET3_v=Ia#jfKuB))R z0Ul)(aL-yvcmVLhALD^L$&LUL)&xjZ;%V(`Ehr$(HfP|}+UtHo;?W7n?U$zr8Oy-L zN_lUu9s!?h66zUfJ9XlV2Wd2U^-rE^+kNGbUwC)#v8=8NZ6pBI>!ugAWh&*02)7K=L(IiT_~zl8E=V}>Aw z9mMsM+bLyDn8fc@h(@DEuYE)7K=4Fk`jgTdwd8zn?z}iG^DT`5-evUceD0ZekjRi- z`2hg98n`t9X*l{-MjJ%|_!uiNQcu1Zld^WEWiR?m1N(^^;m)r>>|#*y&xITH-6S7w;SuDz|Lpv(6#WmPmT zGGfc@;`w%$ZnHtVvSeq(<60>_N-}al9!!#1Gi$k0cMr|YM@rc zgTL4Uf4Mri4M2{*^J3J_P~bd=Xlie?tagl~eJ+BhI|4V274xd&0ejU3EsQx}8b*gb z5z*UAuMnQx>O1YDZsrt)CugPmpWaGrWgBuBCXWnHXUOBSo>N!)D~H8{1QweV8Ar}U z40-i#@DGl_lJj#yi|t5EnMzd{bm~r`HzCga=HJ6xF#%7tjFyTk|UDY%J=l$&`@50U4?=Z<6%%VD}Y8*O@=g z$mJ`f?TF|Y%4`QF#%T4|BVto|(5Lxy!&x}F`R4>C1V3CGurg{ouKH^6)A22XQ_v3| zs&%8;HIT_!fHEq^7L`xYuWj95sm$Jsmol+E7Us$a0DfgGc*)YhOGLs_KKL13filM>9erg>PYG-P-9vMIWLj>y(#GJA2X{4MRgBQU=Uw%| z=4HGi<=#U;%m=fH9V?#6{&O zP@kgU7*8eo6R~A(t1InbAMBcr(i6~l-4qy7T}}5Wsx~@feGp{+047pr>C!eDct*N! zN|>`bQk6#3beEP@auLclW7Q`2vN7g+rOI}N<$wO{#0V>gC9*SiL0A3yef7(mHeZRX zzqMCzOKBpDj_w%hYEDaGDT-j?mKk1Vmsx1?$Ouj&=&DSUC+=2O4%pB=cDhTk^sj;G zIlB;J(G-iHdiH+D|BY#9Nsl<+V-G@_c~5y0tSWnU$WJ zr=@SFY5?j_=M{zw^if@zP(%1%W60PR|JPkvD4m9NF`oLNu;tm{l36FKZ*;*DWJYul zVOMyTn<7E#$?cIUAp8^!sDwe0wX8Z!XA#=C;JL2*d!d!ZOR@?h!?8@HECeMqQ2tQ)Rtz>ce51}rh4@r!IYFXl7Xk1q@24?jgrWcqQ~pK2>iPqNB=IO(7vFCt_v)dR zHA5(F=ZA1XycHmWRk5D)dg!;=9gp0Pd&?GxX$7nKgw0jIOx26+Qygy^s9s@WkPk1B z*K;{rx-gJ8x~p!CHyCL>=eB1)AvV5VCuy#jz-q!IxJUD`=B&$9&9#-mz$87u$TNns zolD#!!|zyL^dnN~d1&b64PR!^z9`!0o$&XwmM9hy&^N^c)na{8%sF-`Q3n9tWh`>t z+Dri8gD;8&?@tp740Q{tGwDp7}AZnKAn*53< zeXJi0z=8^A0yYbLOhJ4b5o9m#eHGq~KtT^OsS2B?%%V)=goRl3zM*tgr@gWdp99ME zO09r1;}93eVVQ^A8m00_OA_yP-N>fpgi0#Tf64;{-epYe7;j5F6eI)>zQ8la5d`>^ z0CG~E9JSUS1&YPW(k&wD{{|>wqnOmy{CwW6{F+=Qo%)#o2I=Ss&XR>f*gES+9K~IJ z#YOKmnp8zvL~TF9Z~9lfVGL3IchiJ!el_y^Pb9giH4O39J-U-DI?$KLcxaVU{jR5a zASHbxOq43I7800IvOu3pr$wl+RNQD79U}Yq z(1uK!-^Knpmx13yZ3@a9n*K`h64G2vFlg)&k0hGN@6^Yh|35>pc4!^#Jl8Eaag z?mPAq-ycxMC+^;vtO}+{0N!O>(K23*N+twOpPOR=L$ppzXv0;ZkanyXKuJ>WP1_AR zZh_LTcF literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Gn4.ogg b/sound/instruments/banjo/Gn4.ogg new file mode 100644 index 0000000000000000000000000000000000000000..2ddb13b86b3ee78d8e0acac44c21ffed2b37d280 GIT binary patch literal 25131 zcmagF2Urx%vp(9h%aU`B5(LQ#2uc!`oF!*bvg8aV!Vo1WA_5X+$r%v|62v7VAd*3p zpn@WxV8#Tu@%zp>zkBX|{{MZ3VRm|^L-kwLZ&mdgpFeL7FyP;*)h{0e}RcA{415 zZ}hyz6wb2?rv?!eJWtD4@R22(t|(CSd_CggSKd_a?KdVWL{4Li15hq_UH*7xvxAd! zB7XuqJYD4u8se|W526&SB*ak44DrPp%DgMRbz1RVWl5^yhDg)6I+bM8q`sl_jFn6M zLsEzE;4y`_`Tw3M{*HqW_C=kP!DQyhwt%D>=R*MDutL^r(P9D4;#UgA*tmpR3~)UV2_HqefM|M&Ub(why=PvFM@@_GNTb9^ zBlX`$;GB{i^ac<-bIbofhr4Z-+yDK*dkl#IJe1{NAopOPpq827V2}jaUkMKZIH!0s ziT)s2onYC)U}bpdglIm_FnsdGknX=G;b7VUz)N%Y2Xa4#(lC>p3X-!9J~bC?GzUd- zAd&y`C;Bg5;6V5b+_St;^5bbvf5n2rYT1j(HK_k-2|kcmw91z|p8NTU0&VUZp^7!y?ZkLD0WQeVlZ9@a}2v`s&9 zDeHVvZdJ~mcU8rd|4VZ`k}I;4D-x66CZ>ucWqBs$R<{-V4A*bA|6h;))*PK6L3lvT z(Fzj$56vM;b8A3tYLqbg{LdIqO+bN$XtDk01OPxxqc-?!M@-EmXUybg%p@%>PW_)X z2A0mq8coSU!Da%$0l;B6$#L|_L22rKr)k9 zuFy;UdBseGMbj|$y3ol~KAN8LGkRMTN>4U0&yxOzJ%@&0sf3E+}PmNveY{0W$bURWzQ)g5a3}aHck+6pha? z8xwt#W;QIn#%-prP?2vwra;aUH!MwB5KAvw#%(?(I>;S2srf2temNZo)<#YVbdL((q>{JA@%xE-FKfCUAO zbyN{9L*FT$dOsfs{H6H%TWHB$YKp-d5F5w=HkgL-Mf~CzR2~7O{BN1f>Bai_Lg>vl z_)0CLN%@0M>-TeKnCN@)XH1I?@L8nl4dvfr)b|k0m^33RDl^gdF3OlS^S)O;?fjmv zlvUqTGGo%tt7>4{?izy&z0BKE*D*bcvZjLqSk+rXDXqGGSt+xDzNFPC1airwnr>Ao zqq$yHGpwqtl+{3Ax`o-^PkNRczER3(uO~XdZ0;*Lkb8K54_5W~pz*(LtYv4ws&Zn} z_4VsA)6GWnZyi(>o2suT+LEqs2z#Zke=pw5&PRGS-^@o2_6k;&uJ0o`U}taG97=CT z^|x1b%~sxCbpx<*p)z&@{d>)<-hR?=IQ2d24jQlOXSGj-jhlPRmCt$|6xjQon#~Q? zubZ7VyABInd>_u_UfKSykvn@y4$L~&9W*X>FEbrB{$|1MnnK2;Gps7z>>7N--lwfR z%L^9dnx!s4gmMIjTl3)I6pjD%wA*KrU3qY9J=rZ{;m23P&LcdB+1=X zL4r%k4f&kUc!mu(?9e}U#F5&WS~`I*#6m`lAQFxusJxSsvv48yMC*Kf(*MYJ_rpTxiESNs{uO={knb|?|S~S zS?5~0ISAtBH@V*Wu)zCC8vrkGWS{}drFBA>okC33_3t21J}Aa((h1DY$96mUqM6&qC`{_!Ut+}hMj&+u$h^dP+8W2>6o_DmxOhb36;&7 zdBIi`$;+Ci51N`+(-ke7wM&tNDyI*>I$x7ZFoTcu&pX#jmrj~N{bYBkg$iWn4ZH3w zDcU^ie61PEA6kf6=M=eFJ1Vf^7XVP*hQNf(()&FVD}U#jAChhLztTQ%49wtM5Dw77 zuc;4Fb$}86I5-Xe+>1;5?|bx$Z~uW71k~Gqp35*%{|hbhB6v@f2ZBuG@0Ad|qWFiv z{RLwjBcyT}u;zd6WiY}v{?fY)vjapz(Hs=~h3elc3jPCe{e77KpLY+qAcQFPzzQE; z7c3bT@R5DlgEjFO(g!Ft0D<#fo1(KreEs=xSq5=wLG;c?8O)Lubndz7a`dy$WJs4W zo11yB=R03BH7;<`m+r02u+kT~88aDF+Z;9uJxV@uAVtrAJQ|NMvk$?B;z&dRp@BFq zeTIZ&l~IP0nsP8Mc+wLK=;MZ{ZzkGMGcr|27dtBgn=_6>WGMCZ>rE+C>oP=~!;4V9 zI6e~o#D0W14UJ{;yZDO6_(3;?qE;F0KMpVg4gru(!zUn+tB^{2gD#E!CPO;oEv5_z zUjSARln$VRxWvRn_tcW!*H}SK*SONYRg!;wX7~s>`9H1-$=~aL9Au)y!OH*~ILHUh zB%9UC@E(~G5f>Gckvi5}OSqGlU2v=7_U+8_0z%pS=9b!)nlJ2Bg(3+rjnLgncN`;w z*)ipehR31%74~7bGL}}q4E!|1@pb^26RYn;MRS1Xwn@%}^2U6s(gm+lZVX?CapTsc z$UL1X-`J0+1sRS*snXTKgGT7LtnD!{JD5u@a3;+oXX8fpXii&4w7pWBUT*_Qs2p5pF!AN$Jn1{D;ocH z5oZ-@3CT>qnK($ztN$$eA|DcmyCC^ZsjBc8r-h!cHRbrrZk4#6rsAyQpH8t!8n?R3 z{yw_;=?49iiW%TabNAtuEwNkYeBSze3vla!13?trq;A zYn@YN^A4)14>&5$O>N$KYW$>f@7w(Bb!v_TDcb8)>#Q%@#XEnh+8~0oU+=$Fa&dgw z{Kttw_L07KVdL%Vsv3v7)p;MjPp)sMXB>RI-Q>>JF=1)kAt(rxSyR4;l}MXiYT@Xu z6EIr3`h(`#xzwiK*KBvJ+VYK~G@7K2e(Y> z6#hV$>*)7av>_4#_F>9&v91C(#Up35*Zn&6PvVGQL$QwC%2**l0(NLXY&HM_-2+B! z_%$bKv5+XLVSmKLl^8;l1ZQ;?H9vj5aK-d`-pRq6?7M{0s8h&}A*skpC5Bl(8_bJ1 zQYi-+v0{DR0ukUCEPP5if@yX{bUVU<+6T+-lLM8ZTu=7jJL@la*e8uLHza2-+Eo)5HS#LqLUs9-yii zyf!(`hX(Ab0#u8_5~Y~NR5FKLT$kcrI=N_bd4J%GNkr04nrm3Ya8d!He{lx`h`ffn zhODyV&yJ>G!E*^SK9AJs)CrdnL5EM?fUo;_jD^Pp5R>kezh0Vc;ECVQE{*VJBb?g#$nnH4YRVj=puf z=Q1XM6Ip5NXZrKy{JOiC2^yy6fdCpGXu}2+0a!PI{h$IFnqWl|2W%3+${8}SJ4_E6 z0D1wS1#DpDBw%+E1_A(lSSbRsBgEr45-`sO()c0!V?n^qF+g+?0m9`ajvV7){@D#c zLSzI>-(Ku~`APR~YSXY&EsoA(|1uKJ1H@i-i-YkUG9Jf9Q=$MkF>Z{4DG4*Yo#6TA z<>x;GmS`NzGC2)xD8PCJHzkx4bm`Iz0BB_fi44GI5&@jx!4d-q2nCJ|?pW{wikTgt zhj_peH0zy+$ci9%nkIs2Ap?Z~FMvnxo&diozz#bnQR6C(+-({Ln6P^-FZh;(nqJ$` z;M{goEoNSm)t)Ov`o!@#?r5^zSlaP-?fJL+Q_bE1`HXt&Gt2Xy^x+Ct8H@Yukqqe= znj%_|#>E7@wg7RM6?nY`#Cj@V0cYwh0RE>i;35EwVC9cE0wMtz13(1mGRl}x`%pXZXFj=&qAp}RDgdh=ni2(dH96;^g0U{S5KBoYDl7J`yP-6u^5H&*3 zUw}SZX8!KNN38y{AkwYxeoPfez$zOs!KmD{IRNAnbLnV$5FiMCTQy+8mM^f80%zrr z6)afc5}ArL=g$ERB$z`jFZy-^-FkZ~M1KTc*5BQS{P;Ft4ww!w*&$;h+$W#|mnTC< zsevO6)-f`J41}A|0gtOefC#y*ssfmP1&BurG3Z?cJfj2w{1o89WTj^IknNMV34NEG zAA@Pq@O=spKnBt=;h1byR7iQ6)DgLe10G9&1}eZ|C{F|^_zFf zKi9WRt&J%5TTfqjz&pOT1VZIdQXK?U%?7uwlLR9}Yj4uV??H))+sP&m{tCQaR!t>1 zapn#wE$Ztn3U+G%V8em=Rs>zZ0fG!O5aR)kw1CJBg~_i9h_V1xhl=~57>o-bs51xP zyMX{_yfZ2I#08FZVFB#~AYOpMYd#XNw5$k-;(&4gta`(~p(4APSGz{G`cGfS$14_8lAH~D(ezn$@9}$*r_8-kzTW~9zyCo1 z^$aGz*A#Ge<&~gXm^Xm)U3Ly+Vx)XgHW0_1f1obj)dG&j2tfo?@(^1>05QIs5{$x@ zz5!5W;q$s`;|rm`Eo|=QS|+r!#@rwcnvqHbT+jq(FsHkXp^pG|AmcNJDk^U{T|41J zut0dFl+q@5uTateD6Q$;r*~JA@3(faZyc*_qB2<~3os&8<^?Od0BR?Ngl^jX6Dfkn z&G{tNliiwgZG!+s#%H5+3`l2!jGGr4cOL*)uYgJiO0e<+2V}Jn6oCqH0#Y-2>@rkS zZY-K$j;heh29W8YZ+Nm1Fs}ruAJs($;>*(pwt1i1e#k1EKYUhJhQ;0A9;$G{i;Ry^ zU59T?c65wO>|0KY$Nbp`V8aUx1dtq}jKtcE6S?tYBgMkZSny>EC$gUhtw0=x0;Gkv z023wz_%ndv;{aV$2Hd>?Sm7AL;30t)ASN6Es0-j$M}|_N zl8~11k5v^WpM5cBXzi=9dAX1!*wrkom$Cbf&)Td{EKqTO@!-^y6KtN=|0s>~<6ak34l3Rq z8U!mo(#u9?-Y|ZcqWdoO)deMxYWm0d&h;-;9tWKq`tr1J)Vftr%S$Y3o|niAP%prk znn1RTpIXcKsw*i1cGk$}uWKCQLrkWUad0UDWRzfN0RxmqjysHoE{=!z)Yg5orpaCe*xibs^ zj2 z!I*irTX;O}Q8%0S>HE7v{OZitEYy=Fdu`=?o_U3&ZQ8`y)@KqzMAXEX%m zpaljD-Nu0<81Ui*KzT-_0m=cXs4c+LxDGFPeQojlWzcvLyaFiHe|lWkQvgl_&~?CO ze1P%QsYCXm0y1)g8@+rKw6AOp15*jE;IU>(czrJVu8F) zl6x|ToZp7uxyz~JW3!h#Wv{wF*6tUDOj7lq#+n7sy?9d0ym)-cdshE#*Ub9+ifCQ% zZ&;!kN&|il!V=Jn0FQ67y<=@^=xl3kec0LlsI|AFQgU<>5SXq2?zaKMGoQJ4=r$pTOsfLd^Y9dj|TGkply2mq-i z4A^jj@gQ^rIM!^GckV?hy-t6TOwG8GK@T2Ko6z`l!nmO@S32JE%Yc1g;2F8e*z$XJ z9nY(Bbx#pe4C7Q4bxxC;8g{gKH;dK05c&GN%|^K5l1wgtlX|?&Wb?d~+aJ4`%j$!J z`ekjWXGpu;Uf}o5i=T}2W?Vk1ZXbP$mw24ihsK0>_9DolLP<_gHe6zfXH3SVd&x%# zcw0xo$f!aI^jpHeT!#E;1G4Lo1{NTKfS=p|g>mR(JRkr8r>Vd$DS&jZi6q<D{|>-^49ikDHnzqg+A!E~D?l?N=RA3>W6f-2@LmZ)%Cz zd8E-ln7(v>CXcfbMQfe4YVy+$`s?v0YQL@=_h&e7BJvVkpC7Rio|1x8%s8KcHlU#5 z99j#VwiBhaxqB*mWJ}zL2?yHp#a5vWX=9Cg7Ffp-||pC%tFh97Gdn!)6@;)G>l9gAYd)d-3S44AaCt6 z0@Ch_f-eLN5QXkJc!c2BOSXb88NONk6AFO*4FtUlouX5uK$!vH4!whexJ5ZD@!YL z`ncH5X6uo-TfVz)Ul+GLd{d|OyK=W#S-)7WcnRMp1qWF99ks6+|H8P4bFW*M_xw@1 z6&INu7H%#g4o{d0Db7#LEkz65(+2Lp>WzB~(P4<7gPTXeZWsdgr0TwDy`~RjjYJkb?<7--3$3(@ix#S zH<&~)*`rO_E#`)lb)L|xo;({zYMzuYTSHp2`7d=^Ru7YJoMe~d6wJ~Kf!u{;U>V?` zv=f--Z(myxsVqwKVzi%Sa9pedF6_0v&`UPF6C~t0S5G1BKRj}VCP37 z4=|wx*PwGC2e!2R6-pLvH}B`mq{C(28-`?e;pkxO1LYP1L{&93x_fc;v@}m#=_Rkv zh1S1r?#Jr=I(ehRa(7g%?a~w8ZuOxx)WKQw{=1dDohWqScSpI*D!0NDa%Gmuj#ic= z+Y=tQQ}C0EZg~1qbo#g3_Snl^qooECuip z(A3#No58dG0(+L{*)&4$$6WSEYfQQHVm!-m=ac)F!3(Cj zuX3@|1R~c>gFwPJAz8nZ6-jHa@PvHWb8fMH`&YA53ybPgXWNPh^(Jdb_>JhhfQyKL z(Fr0c8IwzKMlmY<>B0muO>X2K~8ZH;;xI0@gc{y-?1~EHsve&7SUpun(T1=CLg_v zAqVu!p^gU9MJ&qM3U#VFNsOLjpcS6EI~g_b*q zONoDDEZic}oo6m}LeIdt<7cj;*p#BGyorOmXDM0QXs@9=de0^O*?CWUhp+D~R1$h( z(7X%wbG4jTEsj5oNwv)U$yg@QQjYmo>OG^kx;*0Z90T8cBm?8ZC|W`ajsnb15Py}7 zIu#{2a|C<}fq@7UUj=~DZ5(8HSFS?Ye*<_S1i*M)IjGH0Si8Q-@oR(ku^Blq=Ex?| zm4J>S;Q~5gm*ZU*>VCD%dN+w~ts?p}i}q;sFh1;AV?93d+U;vjH#Ap`0)%5JdxqNz zxf!n9opsGIr?xDnjylnH?)=n`=QrH0yc0{wG%MKVx^iRljlFl@vXTCnAV1H%~b1;$^vO~5en z+X^LXc#TlMNMIKd)re-xd^o0cC*tad=LVhKXBH>udv5D7x|S+Pn@7Sa;4EgYoP zythF0E$cn~u`3^3ZL@BuQcUV+Rs|T%tzCX}{mE~E#}xG&+Bu82uS~wg9iRR}qT;?f zyuDnh_g=!t{4HY?14_4YZX0u%vZ28=-~>2UIAnUl&V;aTCj78#^aXn*2^t>`xnd^~ z;)e{JQwjqp7bKw-hXI;WKn8=K7(5fZ7h}+mmREtuI-_a?T6}GVsA<3_nP&9aZ0T2n z293zE4~FMx*k(5}>D=Gi*jiYGH*ohp)L~piz~k_!DMe!@|e&z)S$>y0Zba zodrP+nSMgxE1_=rq0T=}g}qBG?Y;`B4Grkjfjhonasu6Fa?E}e^QIrHM$(}U_3LFz zf=#>8ix1MB9Y<&zdBO+nRpX?loAI~u`+q7-shlDI{Slow990*Sa(4T~blzThh)zL( z2i^Gqt2%Bmmv5bYZeggXo4&>ndF5`l&)VVU2dy=t#R5K)~pVJ38AV^wde@h zj-aCsSn-etu|WC!f+mCxk?~57*}VsyWiYh!V;BZE-y$FY2B>ZTB1}#!rBMJAUIZp0 z!~jaHmtec+U5NGA!C7zYJ~JG=sA&;(mJr|A^PaQ)E8RsoQ`3^RKgBZi;i+8_x$__K z`yE|BOw`h!bQQ-pwOVkVFf^v8&Sn1ebL5+YcC@mt=gIrn`_#JfKXt}7 z&3ul7uElK_RVyb4KCEDc0GFvJA5Mam+du-LMRkedXktv&o!4ffQWsvwg{|9Ou5bDQ zW*@$P#iCvnN-bGC93HHpl=J4!J?R+rXAyJ{E!xBE->aqaZsx|wo)ly7lO>nCqx+z9 z0cn#f3-xVV(kD4r%7cxSPdS#{T_f?Gk8GV_!`9{2w6MKBjp zYtqvmEq3O_%Up7wgCg#p6k(pt(`<6e(hYsZ`R%l0o5zNLj)w?_2BK#A>sMY)3+%|O z#oo*EQL>$1G>*aueE{^+OOYtLJI;6*3-aA}^`Ix3T#CS8}XNC9s>cR>7sm;M}1Q9ll#l$_E z`Nd~eIJ2>LlBdKQpC4`xc(R?C&zqxFS5}v3P*SEbNM94t>2mV?iQx^mPbrvjljrqc zYg0?c*sdu4Jeb%-{h;Umo0)@rx4hL0e^gJZ+VCv(qv^$7#q@T0X>s;2mx8(?F7> z{Mhe1$Agu%sx12|X3TcT)!gQ@xzI`$y}|qI+1O$1_?M$+T$g?oY@W|p*hlK8l2+;y z@hTtbsI%TVMBJF{i_i2#ZsztMUsx2Y(;!=NV_y65R5sAIu(OI9a>w=K=tIX6T2f>; z$>-A;g&Km^W3r#G*#qJX3>dudhD+Gt3lJ=Kc9c*B|SgPXhEM42K0t> zVZ5p0G`cBK|@7uhm}v@jvnS*e`*P4+!5>y3z<^Yh@|y-TM8W? zywx+{xsgaW;0=g7#{r))3%CeFX$2Ut%~6O2u3!d$ViHi#{_U6&GNAm9MlQkqMdj*^ zsfDI1qdX?zGxxi{>z}ipI6ivUOmi^Dt9t4fqwn{JHI|562pdag<(ss2S_b;NgA#~11Xx=_F+afBA9NlWC zsNfTvyT~o~(C5oh7m}>eMy-8^%dfTvZ&r`mWuz=}1v{3l>qrmo&xp=S~44zy5LRx(y{&Ktg4)}G7A%I4l8!_Rt0TVY^GRKoKmN#AN ziZ}bSD+L7arM%|`j$a26e5x3bf!dCgJiw*Nn!p4L!^9592M(*-+uCX_k}*p6 zv<)4>jr1|^bk?JGrB_o1j{atv9E+?>uwxi<7mOb66_e}Zefro*|61kpu`5?*KU(lI z4A?H@e%w3K+D;Wr+){S(kf4ruam{bW`e}KOqT`w8P04IOCb1Z3OoyLZe<%EA^gBdp z;Mm6t@YYn|#0m|Fw4{D)=Sc}fs7x*e>mryYRRlOHLC!;j$X3RA^l?6Mb@OeDK*_WQ zV1yk8lk1rdeg!npz4y9{;?>u0XT&{DUH7v^NtZu-d#+N`!mUQ9%X&31FP^6F?g*z% zM~x@L^X#xI9Mp`;G4i|ITo0jpZW(wP9q9GTNgXIGidz)DGLy#kPD)JfBIB}k ztk}@VQBSus{<-f>Ue-x+W|b%44?GsZk+~Zzco(KhW%Py~HoQCcFyQ2dKTgmSQ>@6w zbbYX4Ys{@n=hdZ3yLTExd<_%zB`^|Y1*1?fTfKz<7#jP*2r9V(IUkIl$;^-Udt^V} zn!akv_5LG8_L8-^LCg6uE|3kQRmrPp(z?*UGW^W(-q?M97|U6m zeEZbcjFndBX%gM|BRZlLlI?_LCt0~|ENgd!1=ns?s;Nz@D10`HB*g71Zy9$P<7y6! z?ZGfMAD#{D2%{Kc6e-wa7Xo;4ur>N-@s{xJ4<&7LXWW#M_B_id0sV02$>)fwUZu?7 zH4h=2+Pav25k|bPK&!0$L!A4aY76gUnc6xVnkFopi{udwo_xQqMcJ_(Cc`ajCgkWk z2N|n)St}AMzvSMW$hZBJd(>l?OD}3UWp1@-6RIqmQE`uAe%rY8;a+(Dsh!RlBhk&igD@dC>VvQc7Tgu=dA` zE%eWQokvJ*@Z}C8tQjVB^B45&#bJP3915zPdj zVLpAI1;k-fPr)n?kl^h`)ZHg2EW>gom^v(nA`Zuq0~H+j%|WiPzZ#wYB_I+!^B#?p zFnnhByY$y*eO&Fe0!3xRPb3tP7p!9my~≫Kb)Q?Nf=tN2;SL*Wlz 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 literal 0 HcmV?d00001 diff --git a/sound/instruments/banjo/Gn5.ogg b/sound/instruments/banjo/Gn5.ogg new file mode 100644 index 0000000000000000000000000000000000000000..d5a7886c4cff81fc5ad346b589bb7fab17573467 GIT binary patch literal 12438 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 literal 0 HcmV?d00001 diff --git a/sound/instruments/bikehorn/Ab2.ogg b/sound/instruments/bikehorn/Ab2.ogg index cc33da35f457cbfba350a2f287dc240a75ec2f6e..516dc5f1a51b6ab4535fe3c3a3de7c85bc81e77c 100644 GIT binary patch delta 4750 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 diff --git a/sound/instruments/bikehorn/Ab3.ogg b/sound/instruments/bikehorn/Ab3.ogg index b046ed2e74af9ee0359fac0fb1c92253ae410b8f..6110ccc005bf9082a89dc90322122c283a18960d 100644 GIT binary patch delta 5349 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 LQ2;jVB?JEtLhmMH literal 10824 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 diff --git a/sound/instruments/bikehorn/Ab4.ogg b/sound/instruments/bikehorn/Ab4.ogg index ba50324d626d16d3016b3fb672df3300d970430e..b69bc30a425fbc2985f81fa93501e99e10b51617 100644 GIT binary patch delta 5152 zcmZ8_3pkWp)c+pF7)*>y8W}ajVMrO5G?a#P%E*afToaLsF(cPHiJ6X3ohY|4bxP$n zVi+Wx(uI;C_v;{vj-pUbH+1#iqw{~B@B7~8nf$I#Y_wG*qLpwoCu( zc`W(j zm&+rg@*d&1*Rd8D@(R6}bbG_Cw=&6%m=EJLqm_=klg=4fpC_z%ShUyaBh=U`-cUzJtD!-p6;L*D$**Lxw%*Pc`WSwIL&#iC+BJF$)(T z_$q;D>>xiOK*IFD_@6Bojb&S#=!3OZZZUK>dWeq)-6t-@XMye|NpOa!yUXxOI=z-Y z{E12DCp?d#`+J29FVKB76a5C0pU)>e$3e?%m%)Kp2=AAK?EgD<%qa9yXjp!+@RE^G zSR$-t3d==)`LBfe!q%!o!t%1#s*2L`@EM4f7YnP_3x(@TtIEC#*U!`z3+qI!Rh5^^ zOJ{25lp5F1)EyC)mzP$}O3^yej5u5n&D3qIj@5Oe$3ErxPk6zVFawTW^;<};V%pY=zP3UOy^G|o2>fk0?ck&R zw(Z}1UU29V3{@z)EG(U=Vwp6S%{aKx6a2G7#;pB)Rcy0y#L6i^K8GtD^((;gy5D1g)YX3IP$B_#C&W)1xBGc4H5()5BZ_qO3BkTk>PAc z0F>^OhC9}{i4cROO%n<|NGRRt->6M^o+~v>m)CDBCU~58YRSn`qaG&mdTH``0#_;{ zk0+rqZWQ$gy&)88QbSF7y}n^3;(p&$)nF{!e5&w3r;~!9T8cnhQ@Mr84pc#*hBMXF zvmMg8px1s^Nuip%Q%Mc9B`DN%rjlwk{8%Ij9?mFK^K&AKHQbq|;!Eqq1Ze89)cdlN zmlt`^)L%)NRH`UDlh&S-B{h|Fp6W!b&7|&zVNt2<8_6`^aFQg47H$ROg0?cL;ih6= zzuh&lSYM^(utYVUj4+WHdN&Z@oT)czG#M`JeBzr*=Jf_aTbZ;}IK?mg zb`d`e0+(nhHIq-G!>#7~eaoayoNFY$(P_6oc>>VDkp&cvLP&0RdNz<&ul*TXr&B04 zs-0}C;LuJsEQ#9fKqS)J?a>A`on#`hNkT>&2sE9IO`AL!L?T>8Fjh~1gIgoe2!`p!MJqcPYXx`O8xgs#RAXW?mg;06 zfbCQf4}eT~H_sanBl_7-0x>}t(kViWhqGK|(A4f5CaNA{Q_!Mh ziMg`@;K0L;ROW|td^0Z5kz6kGvxOg@ASYA3(KTf!cR=PDbEbCQ%D&?{ja zXkBhQ84g$n2w)x1c}Z{(@Oq^Hjry7Zbwojo6yVVm0WdxS0J_rcK=dCOxenXeo-*Kf zY5Sy-<@0#I62$~wCJp+7iz1Q;E+0T`8&2bHqgJ2n~O6pSqoEU$t?fQd{coze(8OPb2rjwUu;jP4{B zv2f9yWGjX-jdTG#DWdLxE7hwb_ z9quXOt3obJc;0p@*~kEHJdp?)0qd0KOZ_XFMl&`L@TDE0-uoOJ|nc2!26$}YV5uxA_|elkE80gw*M>4RIWOM}_Xl@dVLkqU_- z-F96r%dhA3$vH05yl&fN4UY|sW(+FA0>8zH;2ns5U=l0d_q#(0$zlROznAT)3-&=D6&1i6(B-K4#2B=Uutxgtif znH$|3DhsgO7EHz&Z;YC{@MM0F4e;I@*doutoI6*YqV&qVLC$|PmcS(-b*G}1Xq z>a1h`tk`qwfr8Brf%4B=6auUPAaeylPwx`>ymFdKIyOT!Q!PuKC%xr>aRf&NaP;NQ zoH=vwd_m&`TUOuk0Jreb3#7p^E*;Ql^s9@lL}AP}>-w)sDq1-gkxE5(}!?D^jetXPg~VJ-<)~diPt8b?e7HP&L`OP_OBU&2(k?e2$%o3@MCy zyXnD*uM_wZG73^t-mOjB5t?G+rE%q2T_WpfT5huz4iyfx_Xf-2?)?&`w@b13g7&9K zeE8PT`)8b@&ykNEo9-G89pQ)E|BQir{xtY~9pc|&<^WQGz58QR*rJ^r_Uw-;QVzEPO}2XB6K;B+yF7+bpS zj|6goI;=Kui|wa*)zc%tqOnQQ%LB!>cVA;?trVjlo`?Xp7#UD66OSP9uEJtd{3r{` z0}pdpvL?IKD9viUi1|(XbXv!H%s=BNkv`@Gy&vm?qfK3 zYA&$l5Ni%;xHRw6U{ol53(=AN?R!<}et3Sy;bcL8M&&Btm|U?90mfrdm5mYGz_=zp z5H${fG9Y-%Xv+*`DHm5nOu0LU>D{ec_|h1!I1`JYcnsgF`Qa7$??G>GB?^^}H94-( zur8Z3fPEAo76u+p$%7|P12N=vb-*3Asty3JT>T}d$-gQogFq45p{R@eq2y@n5h37T zU)r+8-9g@0L;iy7>Ctkqw?u-Np8ZJ9AJ@xWv7>Mg zfY~_AVV*1UL(mM+^8Dc2jqje?ez-jFUFl$2)yT2>$1NTbaws+aY`4Q_fW|ACew!b`UCzls15j)ZpIx#@lS|4395m%PYp%Y2Pwlx{ zK)5ISeQt1V+FG)_(UI4;o}a$I<^2J50_e7Sq1KE5f%k4!Y+FGkJkjV8h3qrupnNC> zZ)4N}u(*YC%X;kqXh)2PEDnACrGYud`2J->&1x_o;Psr10$T#t=vx|3ksZfo+C`^5z`d_IW)D#bJRHlZ3E%v`<~WxJE^~++@c9WhF30e_-lBuM!;j+@f zM12J4AKT6zQO?nit&M{%?afW=`L9f!u0VZo#}3=^!lnnQ_G9}kOzPVQt1>`Y`}=Xj z5L;FfV3sn{!_bQN)-T3%hdEy$nQgt6QKXMjOlOVto_L;#{5^&%2+L0jSU0mE+n&)9)}Tz?X7?lC5>p1IwNxfi*{~Q_&-;DMPms_bblEFnB*y zf>E3+FTq~08O)lz5+fQITa=IaAa{NBx_&5bgf+&R^1Ax%nAhud`eJwBYMb0WD@#}3w8Dth*`j?O-mBWbf9e@wS0=7zMf@07 zxxRwJzxj35C`ua)w@mE#+i(#(lQ+Kk>NuZiR`Wb?(5~`%ih9Q7MI_*aEuKbjo_%mi z&H06K=wrG2^bD4_|L9?t(J2;-5?soPsA}3{Ko^6-* z5T75O`0jSJ_0vmfW^-8|o<655_3S-#|LHeFMax0+C&MYC{BxJypvzWgy*R+U(6L_C zaB-GNJ7uHL5~MGSvY#EzIAuG3Z{DJ+yTSXTh8lkZ$?S8c&48rCLH&KETAu=D@m1-z zYPPcHeC&%h8u(Z9LjG>r``;hck3Pfzwffqt+pe&Nk*RTBaTK$Y{yJLob(pB~FUh)K zJrnFZSlzMr>r1Qh(>Zr*s_;>v2`^6bHXSh?I8MUF34_jdFi$PDa$d{85v{2 zK74d2auwVf{fWCZZKeM8yay^3-YXYRtOWKd0wm|Aj|^V934y40Ddb`K#6V_2$KAg1 z4KCMR=8XH4vLtp`>xvpnmdSMS&4jiIiVO%1F4!ax>TR5oC%WeAMjTH_viq#F7Jz`U z(b|ooUu-1LQ*ztlDTB{yeLSw&x3E#&Mzolm=+;DMS_WJ}~em8UNTHanlOJyke7baDb=ga?$%U;Z@Y)qo%0;eS6rzFlL>H+ytF z(?{uiVUJASGdHmIc~j)2wt_#9tkQQA$*DRv_ouHmZ*GY(M=7*g=^WsDziNwPNO5a<|vg7UIBa$`Wm5z$Z7X#vkj1*O{L+ z`crSV1=?!;A=49Cf9!;iN$TogJE9SYEKi^PIL@T0R`}%MCRw1gVNua>C}V%yqu;>& z5d4DA9gr!WP}}*z-8dj)#_qy)M+?WmGQ}pEgN59YxRAxU?K2a83t94O+wU#5PR?}P z{F|MlbBOwnzV*hQ8`~r!J_w3t$E||=mqGr8=?l&?-})#_wsymX_Xg}Y?DZQCM%vxk zxuZkV`2x@TT-EBvs83?O#fc-O{smQ<14DuU&D*2NS+<`Qvw1vA&7#>=!>1_odS#S~ zCpXryH5&%O2R^yeWSme{^wvJkWQF%&Q_7<>QmY(z7V>RweLxv_GcL!?&V>yYIHGVD xlH)7ir*81mviLr{QXGrde*R_md})E*MChKt*uw*pcTjYJbLtkWgeQ zBG?!Rh5!l(IJCWu3Wzha5nJm#lnzuo*h$|BSZ{CNUH87V?t5#!byrW$f7TiHIr~4~ z-uvu*{={wAkO0u&cj*V|mqOGM)b`D}B1xWM49)C-=NM2TDZV~5x)06QmqO*{=WY>ZpKZxK+ma=b zZ1ONH8VsMX&6{&pax*1)l)TNGHc&E!c@&XYyos_=m@cN|=Sg5+v}9BM4oXaZ&NfMm zI9(#7By7u1muyC1=9znhh9#l^7Oq8$rVJt@l{^4&0HnHjSXXC6dZ=p-QFqqYL>Ov= zK4tYaWrO52Ic@0Ifafs#!(zgUGBaK^w^K6}ieFNo?R@im8l!E6D83w{B^h zT6lIq0&Ix{kdJplt^d2Xx2 zxvefNj?1}RFVi`MhXIr+gX1-rOJAKwKbN-x=GEJn=WC)be-pjnS0Nb04giDZFu2v> zJVb-zJ)Y~oHgDy%yqIec3IihlJQd983*3lfQ$}4Dg7vEu&cTAfWyy!IVV3ipAc6GI zJxaq!!_&(_)(!WSZG;2kr^~np+)uXEADEM1&K0}6P?jDS_75uek2K_6iL`7`&)0U^ z95C%{8-smz4;!tA?1Yd`GS*<)cAXFBCXF;a(3~W|T3O8j_r85X4rHZ%17UVRu)ZbChIsHu>$r@}-;aBOv~Ub5{S>uM!!*rR2M zq9Q!1ttg&j=dRvXIJa{O0L8dDE&jEbQ{{OrZmE)aUZ5VkEa=sk(*}<)NOpC@54)dS!@--JFq>*5_XEI1H`gw}P8> zxr$#r`kQ?9YX`QCE6k(5-U)syd0gJw?HiNc&A)NHBt@V9>9swdUQ@iWu=Mwe^~!Pp zG@9Z$o2(JZY3CY?Vnfa51^lb!Y$crA=Wu?X%bFgSm@%)*Pv~(^>7%wRHa#YRm@-Pt zA18?u0#e5P#p68jJ zXLYU%%+PXJxh}u4939Oe3|do;Sme(mJur+D23vR2GtnjT~?oTo?Sfv3Z^R?MmnH$S)id zF5!&(>PI3=2orY%S&Q?y<%-Vqh!F4oA&%pHjVV0#u;7p#us(-!h%s_lV+1YFkRr!H z3;}i7*5D~%(v8v?wksL7toi1@S3*W~wlT~vmw}8%xu{Y4OJ0zR&X2{QLr?PWr+>hU z?T?E44KD^ghQW>b_c{Hs!XF6yO9Y^bqpaaW3O(ew6paL;z}t5jRg}nCI+B(&yJClZ zwCycEX~lvD)A3)e13K6z^c_o9ENC^Wq%SyVdbLRMx6qQZ6Am1N#1V#pho^tlYxp9w z(YCE-qs3Y1730N{GjyT$AHN&|0D>|F2(Z1tc=b-r5jFq>R;4Gw_#&c8i~@)_>7Xe9 zRpOmX{_!&Z^WNVvL?KiF-d6ERTO2N;E7Fn}RbCdUNg&2(hdqOUG7zH;Z?}lRWrh{B+9MW_a-1FmDX(EvnGLONTIfj_bA*%m zDGQ~BJ}vYvXaf;1cKeQCc`04-7yS2f~MsEh+6V22WtLmsTUX6!g#~G>Z11G0(@}*+OnKj z9~`MgX zD&aT0^nV(D&rD4%$OOwauAl zOA@>xaW>Qi=X6EekN_%yk4so~Rk%Y}=3zr~sf;kEAkWlr8 z3>s$8D^3eJ52_iZ*l-hT!OjhY!0-~v%r5QMfkVYroC|PY5tP++6HjhzzfyhDg;0>TV4O&MSdD=3{3Fh&kjjHxLD{tb|ar`GJ}$NT+@|02#sc zUk*Svv=YdNsi}nlWdy@P>vn?e3itw99iZL`HUoh1)++w&){G9sBre#FUT=kx@;B zSPzr761k_kzPc{-Vm-%Fw3N0@PFo#xpBs9P43F$W0F3aywpaqApuiFYG9oI`z}&)e z@mUswvCOeqr`!@9=-w0nK#24bu1q>ep&hcPdbS!NgP79YV0c6y@%{;9nbEqD!4%U_ zY$&df@4!Hr1qR+Ob-y`Vyr@x`!2OH?`2es4+=9o~b>QTr+JE=a>@#47w{!HM1%=?} zhF=HI0EplqQfcOcz~B|D7@^GYh^Xk;czC>_<~$(-ps?8a3#Xxt#m;{!VXU5;KUWys zV)dW0R#QI=3 zhtD?Nz5el~cknwkc9y=DD9|Ok+|VRU&DtIO^XyMG{;oz|FP47nF#fsv(T^edd-I}? z9Z=1fPOi=^W?2_mIs-4!2EmNuFFV9nywBItc1iuJI(j$i-EDq$xG(hAEqW*WmtQOD z^m@xQkRy~x{H7*);*n16_|NO(J`^0{uXJ?=Bi-(*q?J^18W@XxR-e<)s z(xF-Gv4aKHn|nBMO&w*IE@?;s(~DN%)lr}L8VwZEJHeq|)V`kzBU^AHQEX#i*GxT` zVH0iwG{kaVHqVFOp0&AKGZ}xD(5?!fNLBE&S@Ar=_-J23v@PhOb$my%5N+5%Rr63I z8fmviQ!kRKtrEL4BodRawhO!fwy+>4DtdGAaugfqKVc%5rxwMKG#VK^NC2f(=wBWn zIOZTG7d0fFyUAhcKzVl}dm)Q!yfoPO3mqNgOozoAj}MQP=5X2ey444ntZP>B_E&)Gh>{)A+?tZ|&G=ior9iFntF#!e$;G#UkDuAO#zpDA1!3 z%&56K-J%4o>tYTx6lgqisy;T-$Ye52{#lzvEF-`NAw%_*GS8e4lU+l7?qYm3`#oHYrt|5kfcYMab(s(yMG%Ey)Ao}_&{SARt0uC6va>l1n_=&8(v+>jU)E(&@~ilFM1-R_SRDuG)w0#>C|FLjx%$-6o?b>Ci2|;CdZnhm+&eb<57$#K%(( zMct>0q1Tg3VZTo1&v^PTLy(8!o6z$?2F*$W&had?aJ z=u(LWm`kxzRXp4HD|in8%uywe$U1CrF8)XVd~^)x`+1!*Rj)Njyob8-0|w}xucP;% zu#=qa=)K`gMSMTQ`W@5ikF-a}cF#B6-g!6hhxQ*mkGxBiFGm3qssGbEUN;cxFMHpz zbvlko{!+Sl-CBec_xUYu72<{hdi|THr`B(b86R4YnT~0loDD5KbQ9% zKX$CUzP3p*$+J*R_jE|Ns*)aaoWyJ{D-r6wBBj30FpFzv%`l!F9-6jJz; zw{3M6fHywI>FzpzrYVnz2EK3G1wO|VO^g3qA24;gNX}I|3X8EhAsT}pZ)Kal*VD{>c5AW%|{hIm|Hoch7ukP40 zTrhK&o$;1T({`DI_MJQvx}a?t<4qe2jpnwsYh5&>UKA^aM!@7%^SjZhiZW^aclg!^`Lk3^zfPUWmFXp4|Fnk#4V5Sbut0S zku$*yp?^Od&H~`M_);@%&(rQz>FbCKBmXMjNpIb_YHH08Z|lB$F%!;c595)Ups%o7 zc2#9LyTO#b73w zoXRYFYE-TOGl`@#81ELKH`=a3+ZbVl&@~xK&4Y zovGbv=^Oj!hdjrMJ*}Gpe4A#BqdKdO{aKM{iN%`mk4>6=egMbVF}YjkzwnMJ+&(}i zlR+mQtk2+n68z)0qw7~GTE{krmvS%2waMWh*?)0AVUg!A87(fG53R=+$}24f68816 zWS+V+Hb!mzk4uyoXS~s3Ge6NAyO@OR-i!j630z+mU#f6YWySl;Fd;N}3gX)M?FbDU z;c>{z2)Qp5hp4JFrQBBY=MJ|Vy`h*r}o=tgIj@SZn^i3?~+fN zMog45?6!M#`tq86Hhl1Kof=+>miD{_mSnh$fBfx}hNGrMYyE7Ed@@`vtoY_tb2fCP z*tjKK*tcExSTda|Tgvl9p-i_vB5YUI???9gz;6ncO&ML`Jh_Y&{bu$DojjItPIUY@ zdm{kx9Zsc^Fp`#c_7s10&&NNAjY=<*G(^kxsZI}2AJ^0XT6sf{fGbNnlhcpw} z+@u16+VXO%_T4A|lkfyOm;*RcsVC>-&jEekW!4L9BKZ#U1;I;uL;#_ca$=$&zi$=;5! zO;6vi!;h{Dz>%iX7c_pE8JvsD!{OdYbL6_xA}_g^L5&*{>9u;nKyRPmi;bUmB=&Xl zUbkde4H#SYWm&BuW(VYba`V9$yHHkNC|qfgBZ(n`DfaS|cdC3u-Qfl&&G!-UiabRG zBhk!=6JYFCWm@F5E;vC$3x9Jf~uEU0i0if$=T^* zIpwdJXWV>F3Q}$=j@ts{t5{@R{qYc6a8vyA_g-({a2Fg4ANxLkvu-&Sdmncih^qB? zKZD;jB<9Q!x1dycDxS#d3-2RG4Qhu-a^3D7*s70OvMIN}{Lw#?$i~abv^ZVK>h;nE zF>6uQhBQC>kMe&Bfj{v4Ujp*~$ue^ve2ih>`zjg!thBctvp0D$YWV#j@K?zEM^yfh T=YND4Uv1(KdA@?;KcezqQqo)_ diff --git a/sound/instruments/bikehorn/An2.ogg b/sound/instruments/bikehorn/An2.ogg index ddfbe21910bf6753146756fbcc04e53bca7ad597..29c97fc38e2f9a9478fde02f51128b55fc6be001 100644 GIT binary patch delta 4945 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

    =@ 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 diff --git a/sound/instruments/bikehorn/An3.ogg b/sound/instruments/bikehorn/An3.ogg index c69e59a8da0032061076e832fd64d501c239e7d3..f9f67aaa53015d82105e0a4065776eb6347cf94c 100644 GIT binary patch delta 5421 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 DdG#1k literal 10823 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 X*$dEG`wzcAd4G*Xea4U!(8K;8zj^yo literal 10760 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 literal 10465 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 Ar~m)} diff --git a/sound/instruments/bikehorn/Bb3.ogg b/sound/instruments/bikehorn/Bb3.ogg index 2055984a86caff380889ec26f58d2562a3e1fa2a..f655ba973cee67ad38624157763f5f89fcefa636 100644 GIT binary patch delta 5484 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 literal 10823 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

    Y;32Gp`2OWYGjtGv9V4nbM!^zEml^ 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 z%0A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 Yss0ar{-Mv`7XrVp)%@X~zb}3M4?E^mumAu6 diff --git a/sound/instruments/bikehorn/Bn2.ogg b/sound/instruments/bikehorn/Bn2.ogg index 17532a6a7c98193fd5816b2ba14e998239fbe733..ff86ec97190870e1fc21e6a4fc0e697757b5a75d 100644 GIT binary patch delta 4914 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 literal 10702 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 P=2hdOb{3LH=)dDXu93kT literal 10765 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 literal 10640 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 diff --git a/sound/instruments/bikehorn/Cn4.ogg b/sound/instruments/bikehorn/Cn4.ogg index e5889f04bce696110625b2294ec1ebdd758bf449..e02a4fa8d22851775130e8a6966baa219bba0ac4 100644 GIT binary patch delta 5525 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 P=)3mz^3K*OxcL7AnHg?c literal 10817 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 YeT^?wN@y^8k@e*p_S+5|!2GBE50bD>hyVZp literal 10641 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 diff --git a/sound/instruments/bikehorn/Db3.ogg b/sound/instruments/bikehorn/Db3.ogg index 3c3e8d10305e215b8eac97564c66cd5b77f4ee71..000c38fb67a24214c9255a5bd1e788904901ca66 100644 GIT binary patch delta 5483 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 literal 10484 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 diff --git a/sound/instruments/bikehorn/Db4.ogg b/sound/instruments/bikehorn/Db4.ogg index 35dd47df4754ca50407d97a0aa050fe1b16430cc..2f9423914a1c6183e6710e21f85c592013c6d9ee 100644 GIT binary patch delta 5497 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 literal 10759 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 diff --git a/sound/instruments/bikehorn/Db5.ogg b/sound/instruments/bikehorn/Db5.ogg index 54c10b54c541422e223b0c1dd8548a2ce23712e4..e65b43a2882382406047a649628f3ef6c5f5cd3f 100644 GIT binary patch delta 4533 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 diff --git a/sound/instruments/bikehorn/Dn3.ogg b/sound/instruments/bikehorn/Dn3.ogg index 33a863c84269632bbf228fdc829572dfaf6a3631..f132cd6ba55e5d32b28f95c70b6a2b40f0268386 100644 GIT binary patch delta 5456 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 DI?`z} literal 10786 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 diff --git a/sound/instruments/bikehorn/Dn4.ogg b/sound/instruments/bikehorn/Dn4.ogg index bd4c353e625d967be22efa880a78eac7016d9344..196100f483a81796b9be99a7f8b8596941f8b980 100644 GIT binary patch delta 5170 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 E4}X@ycmMzZ literal 10875 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 diff --git a/sound/instruments/bikehorn/Eb3.ogg b/sound/instruments/bikehorn/Eb3.ogg index 367cc5456dc7b87fa303697dabe8757bb54672d3..8fd4306ae39b904b2f2b8614cf1b1625a7462f93 100644 GIT binary patch delta 5150 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 XKg=Bc-{k#tfC4!l{N|7ocOd@{e|GMu literal 10480 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 literal 10759 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 F{|PVSQjGur diff --git a/sound/instruments/bikehorn/Eb5.ogg b/sound/instruments/bikehorn/Eb5.ogg index c94b994d1997bf53f162af286eb1ad3dcba8e4cd..d2c050ec09fc1378d74aa396d236c23148af86ad 100644 GIT binary patch delta 4232 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 TmG_Q=;^MCjD<5jT1mJ%Fr}Qi6 literal 10582 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 N)^0xf=ZB@w{{|OZfe`=z diff --git a/sound/instruments/bikehorn/En2.ogg b/sound/instruments/bikehorn/En2.ogg index 6c2e4de57dd3ccb439ae5e733bcfee35a736ab31..ab9bb7dd4524f3d87792165d69c32c470205a1c6 100644 GIT binary patch delta 4782 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 diff --git a/sound/instruments/bikehorn/En3.ogg b/sound/instruments/bikehorn/En3.ogg index 37b96d48518bc37f31848356b0db6984a6f104fb..cac18c0249d964e1f9c627ae1b5756bbeff80452 100644 GIT binary patch delta 5104 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 S7kctSPc|_rPx(atJN^Tz6xpW$ literal 10529 zcmeG?X;_n2*7wZ<0U`!SLRcI2fW#6A7N~Y!f zmbS@Vzi0q_f;Ml?Tp>u54iKsHqIm z_jF!GHI+p=Mp6l9=taZiCer{Q0E}g{ukluB`g#8i47Yt*D*v?AeutTc%E(!Nqrtzr zCT(izZOPbl-ra??D250n2hb3QLaIpLBq|*CFkrLSHfz}7a9x(MN2^M1>^;oP5BI*? zRIxhXZfoPdfP1Xoi#!u{?nOV z_m-M0xYWY7m;i&@1grK_L%XS?-L_-n&TAffMq2oe`|zX05fWH(-8hq^wdI_2M2Gxm+m76bgBavYqQUXl53k6 zdOOSy8g{l_f-tMwb*4jB36L)BQmtXzm1sCO=3?!w))Q3NE2=!`)^|d@u- zN)VX?t=Q8ST5)OLt@`XE{vjF7ebcc^nkz*D_vQtUf=Xp3mjxPF%{$4SnyeA`!_X^! zt++?d7tHL&e^oDhV;gDi0_(UpJIZH;L@ZgmZDY*4xt|;>jGxK9etGxx%cXBv?)j}@ z{o*+QI!(d6PgW+Da6YcfU(GXGQ1A=S*-HI*zwO!m&S5>y5tls29&^_`;f`DIBe@Y# zwD@sa?gTw0YFYe*Z_0!uWolc>mHw2tW4mMepF7Ng+g!h#`zz1UyNILzz8fLsgui)? zinZ?xzkN=j<<2qXt~;tX6xFsJsK48$HvWz0q$&^BC=V-?w-x(XMb&9VwVD&^%#kDa zPyXBbi|4G$a)uRp4nNEJSDvHg*aksw>hX+tvarV$<4~YEe9K=e003S{jnSW7WDk=1gt!`bw-MYqgC40-9 zf;V~+$Htbpmqh;0PkHVh9v zPhUbOKm-*Tv(QHhShV9@)M5o{!Cx5ucP(VZjU>SOd>P1ST#Sr!pYwuTv_5>43nR&Y zU;YWNNMB^luXv%{2vi*L-*ft7g+CC>S+2F+fm%Uq!_f^(?k{nBJkU-Q7WP*#_8YAhU-E% zWO0*S0EGxw_$i+x$Dz|&NiIxGN8XQ2Juulma!YL*h_Pnwafo}*7zMp7f9B=PUwh_1d}q-NE& zXihGLj4sTFD45)(*8T$KMo{4?3{T^D%i3E-`V};qBPNh?f*S!TFB8?NwJmKL7)j81 z!l~SNONAb$fzbu0Cz8Zpu1dku;JlMZJn`a%v6V`rxp(r&l2HH?s4G<|F$S~xQI978 zvswf&wWNTvtvw{0h~tj{)w;(KD4;ErBnUXobO39dzt{SW(xowT?x4b73yv+ z40Jesye#05++ogT;Lt?jg}4`%{k{1k7@UJqp5IWGl_WgxZ8iS&t>tg`m;cY+Ol(GH zpA<087vj;Ff>NIj=R>r82A0-6=73}bwH~P8+;Off7YJy)5`UIURduYglc(U2nwutL zGdc7N{)P=rm9a|q{x6_{APjCLcAbesb7gEXyPt6|(*bHN1HzJg1bq+&x02y0I00eZ zIz~n*pLH-!kIm@xb^kIuta~apsiV)ev7}rN>*$+ytQ2_-r+35`aU_Sn2)PQW`P zG`%6ch3V}|)Wpb!X2vYg-^7|o^N2v0UP7H&CA~m26qJib;0!$ivU6#kT$sVqXTpNE zUl7fem7@8%r1=yXUPbkpsyVdXN)en_2ze~z&QKu6kjFei0I#f6p3wrLvK-PiKSw}D zaQ){9$Ota8Favhc+)Lf$`)Eyb_9sEaq` zk$4n&v@MDl`T2dm$L-pq0-HKjl=vPB`2b)KX5sO51vomY58Sx(=ov6FvvP3f_y?NJ zqhAHj00B0Cw=js&EqrJ_v_z!CPU1S8!@O@w>EZuPQ6HzFf8Q8{@|lpMLG;wT4vY1nSIV7EPqHTBV(LqEG&*JN+{P zK~k)m8u~8l^08~ia+1&0-7m%e5BSvTr;3E-+ur_EEt^U^>GQqY>Fp1GJkB4`Ok5NA zj)n)#&6dM-fWz!I)41;XE}{H>&BVI z%N=zsjJ@lAl&4z16VkcFm1+4Avv$ZmW3)i#v^UTgEVFW&PE6A>Om05i;~LQ6=qQ(T zFHJ}ncIcL~J4Ua4fA`IzT{wbASo=?kZ%(BVA94+shG`c1xwRFIQ(;B}11Mk|Id#a6 ze(a;kQ~F))yuNp`XZv)Uqf)W9U#fKq=}eV&tbG42fnaP>zG6@5YKI-nsJzqi_?T@f(*9`)$<^O!b3x$!6anAUU|LwTNo9|0`k{vugV{U+lfls;W?>cyTHc z3-s}gY*N&CJU*JU2`2}h6h&eGyjQwBlqVJn+M?^U>u_Uz(h z^ZHHMU`VZ8>{#K$Tl=+RKJtZk_5L-XKitbC1(DD+{PoA9hNeJ}x6!73nL_C($``wY zcNO%T*)NurY}{*q()PNvlqASwT)axpED7#oIpPHB@XkEa5MUsrko$vOj1n(DmP^vH!*si!Pu~ftTxTUVNG>*=OUQ8+99f>vI_er3yaIq%ik2B`P`Y8$6S>Pvi=&%}NuE@3~E zeNeg7Vs_grKRj3!&w1PRLQ0igK+Dd@$L#3&Pz$xYk-$5VKp>L@@JkDAuuIDqb%ih{uQ);mHSt}i(B=~bg(GHKda!!pKq z@l-_cdaLvP#Rup1P2XQH$>X^c?YjB&qsH8mF_KxUKQWR7jn0GfGTnU?J>Qf^`1g)%kobPNisreF7yzgB3~+B0@Z|I2{!COdE8NW@CG6 z2EB{v!4By((C0m*F_J|qfO=wCv>`|gLv_8{OrptsOqr$wluSYwRvMkZu~>5&D5X>c z1s#zaS#KmAw(WL~siyG!w|@HSIxpg1hhs2HudA1Kc8MPi+`KmQAh^EHm|~435eKo) z`o6%IASF>ho_pmb!gLrg{P39g1a<7^(*V6La){#ouow?65R}8ro_ZXZ#rM!#4O?;d z9REa~wI}39d`fcm+C&hHGIlADRO z))^%#>8U^pQJndZD17jcNGR^4QG7d%6R#3pC3YQ?py6*JLK^TwyeN1yyj`xGx`xA4 zSWP-IiBkCpt*WblSFmB7qCwShoU(W&*Pz4$Cz~3?QTjpw^&m~y*X)b;BG{>ko&ktf z2~+a32nfjl#X1q_Cl$pL?(y6vYkc=Gz(&(12Et{D|gC)hM_Mk z>jrla4TL!gVhdmZwL5tIFqvxc(wvRC;g(~)v_p)!R|Q`f{HXV**C;yYRtY)@rbw6Q zXNkqHGROvxcYkCsa4sP~%rnstcUZ0`6XvzjoXr()f2J<$kENBADp(4JwksPD&kPZ? z*Qi9_ZkEaw=h$zI)i`2TTivm?Ju?SYju=KtA+UmYKMa~-qjuhvfF(cbeY=}wBFwf$ z0&`>_$EIt15KwH$z>8_kVJbCIQ1X=f)BM1Vz3DnCwOftbvq;)utO!}pl3!(EiBlAy z<00fYCU#Y2V9X+Eq@GM=Yhss_2FRE~O71re1WOj7ER*PDa#bUafyiDqpp0?%#D2=` zljfBn+Me~HtFK`=E2py?ADuJ?akn14tVXtlG^OMQ*$|pyi!VA}vY&NAQybQUbfXT0 z3o|4p_8$H9!{;8c9e+yVifJF@j*zcAUiwpPkYwP8aMX(QS1|%!Q;FozUD<)tv#Ld( zc11gz4h#~9^O2{!-#ppKP6_Z+_*aD(zzaw$Ex%7XaJ7|r6g0FcmRU-=U6t}GXBIQP z1UtkhXopNednwZDC!=YpmT31;8Yq^4KAH)p##&3Kj4_86Yw77;x$UywaT%d0<`9ocC0l*4b}tIG)>rDn9J8)qDMPoi;Pt`Q^>SAJp=mUY{9$^ca2%0k#`bU0CVn?1E8X>1ldrp#H+$ zGe!|G0HDi_Y)K@2W()d2DM2nN)?u>D9I{NVWNvGbXuD)U5lt2PyiU}4g(GKz13g<3 za5A@9(QC*XM1YJazxfLRb9l+jhDbTBks#hmV{DNIW4JOCXKB;dm%iCpm3}n_bk!atPg=;S~1p|NRHLbTrW4?QpqGUyOf9- zh-;L?pYjxmTQ{4$9=}N@(PFtuet|hcjck@z$Vo&dU{>2Xi3=lJaaQ4pC)i2cma;`4 zkJu0^D#&bdL}wC6Y`l!YNWj)_L}kRMiDnOOK5>2PTL-Ycl^3;mqqIIf?2U|0A zM+>)IKUY68{+G5ozfit~#nGA?C%14EH4lbPD&s$Rz~0uP<34;y9^iH+%%qx_v`fXE zahypncIKI7Erp2;sf273Nuv=clFg|dkyU)pM8%S9^4p(Z@}N7(5Her^xi4L-o@!Ol z?h~9G@hX6*fNY$l=2K~rv^br@(uHG2M8PnHVt1u%xWF5joRx#cm3 z#nIiA>XdNTrrB`&j`!b04L%Hth$jq+`!0+<>$dqUB6>5yo1W#aQSfP{r6xh1TL8)$ zwH$Oysp#Kq`6!ck75A+b76s}z5V971M;ave2flpGhj(hvE<%FACn}3KW-j)>nssw{ zzu&UDF5uJ6@bN(^pv7?0bgt~DGc!|HG`=?MNiW^7tYJ@Sf7cbBCtKV(lR7361|hWW z^f7b9H~e#tvD^$waiF+ViFNcWCCdh^4_W8yc$K$C;8N3fCb=j23feJRr))q@oIYE% zw%TRyT4Oh5$dm`fp8+zC`kv$f*EnBTO_ce=4~FeAE00~>A6|HWU&VtTd>G^RE-G7b ziDoH_z(MZk4=)we4P1|}8Wu<6pWHn9)&UT)?2vXtHX`dUKORns{wOc5%;Z|ikKcN} zQ435jzUVNG%rIwtAX_My1oVd!RKOH5h2;hGA3y&E>K}>!fc)+yF#p8@0sQL!F!Vo) yeYy5~Q_|e{!rvb%|J`fxKYGDG^!Xo&>vvE5hdzJzD*BIJ@DF|dN8A{nrw|SHDf7b%V@Jy7!<>htr(Pj32o90h7=(Um5^=3SV9Q( zW+IY=q_LzTSt9X|Udmg(XY_v8_5Z$St~u9v&hNR;Irq7L=YH-Pp2MJF(2_GXykDP(6D-E#qk^dS25R4QcLUh&wX7}3vxt*e~>yPqt$cAzbgeN(NgSYIbn!0HFHD&I{=uZ z4$@QXscy^Xc?Y^l=p1$jc{}HNpCwT%6RS(a7t45!XBYNaJ}+Wpt*+!0$#`9^fCd2( z1|-Dtd($?+jO75Ji&I63@oZ{0aWakCNt#fiQpk6+?Yqe+WmYFiI42H6=NC?7<#6p8;8$fegKudir(_v=_3p zHx9J7@;0=3yp61l&5{F+A$yRvf%ZDnhE^BUqvtc^Kzk=odsFZ8R{o+>X5I|xv*skXvb?kAURh<}EQD5;aBDQVT+OnY@>QUL$> zZ2i1gtLAJ|D7Uh*tmcaVZK{}U51Vb$zEDhjQCv3DRNB-OJlho3RUf3pDCEvOR)5h_ z)mbw?+qAPbQq_(Y`Ht;A?gY&w==hmj*X8({pxwXe*4M!gLefuYXeiX2G7s^NzzZAxrgioYtmU%egYkYd@9eO-p)OJw&^Me;ee zlz@CTpBhkI+)tmw70FZlwAg(v{-y2xF3Hkf7>3SNk$1Nxno}!4AYW5?MUtizPLZ4y zMa!`ZqH|%NiA8CVjJ;)P9psBsByU9_)yugCllV%|h$0zROJcj6eUMgr*4B0$;3_VKVo9t|r&vR2Q7DY+c&bYviJwgk)Q9qde5F$Y zwc1@=t?ME&E@JCxRn$2K_*b+;(eWIt6{WgPJ|LJhsX+0o5JWF+lXp#lqT2`P7xVoE zfNRiRepWc8g5OWQ3ISe0f4#|yn*ZOq)BUyD`Sc1wboJ^CMmiLIa@ZxA% zx1}HER2NwtZQ4cNUV6&flt`p?nV|4>-DD!MjZa45Ir3KOT5XO2L?Sc|Ex-VI>+LIS zbGZ#BD&dR<2cT|l$3YvA@Fos6t`}P*=Y`qA!9q*Jk@JGeiw&1FRo~>*Z9*WjY$@u* zcnrl7&w;j6Q6&K2fxYabN>E0B_7e|rx;QBT7vZ3zF3qy0Y%h(0YFZHq(Sg&}<>Fsa zJIF9bRmAgktnd&YPE7oI^7bv4I>l+Flq=^7yY#|hwd=f+NB2O#nL3^YUOH#c( zJ5JIRwE@ZlrON6eLjq$80T@$MejFq?>^=cNrF_OgHXB*#atRe~$P_RQX>$hHke{S1v(yvQP>NBve0TmF9{#yX!W>FEaCZgzQZb(!R(-b6) zkpuwSdK1b(SecbToGxNP1c_f4da`~36?&#^kX}wI>Z3wkhxICl+QKCO zN;g1@SjVR)*FhD98lO*3(&xK~fzjYlz_h3eOUNj?-|}h{dilYDDhwb@*UJYju__g+ zZk~Vuss|_#Q3T7b%7W_p$Hq#7Y>YofjM3B|xvqRECH{Sl957 zhUTy#8)uzhEEz~+L$3eW*fLO%b(BpNuna1W09dErx`tL26m0!rRhA6nUzG#VPDrr7 zZk<*u?A#KlH`XF#>)SyAOmP6h2K{G={0>}OHY?MLm39h4-yu!CLN>4VvDnmxeZwYk z2H9n)`SfBE}_ zx6=DH{I9O8H$RuBt+Riubk{v+a4*kIWZ#De&UHHX4tnJ}@W^rt?RcaMbQl(2M+HEMn}2ON%l2)D#RereB!6 zwRZOO>{$5n`LLjhF`Ju@84HsO5y=Wtl0EmKZX4#(-sr3~DFX|2B8~DYXFMII*CLK=j7(Vbx&1NI>A*pzp{<9Id7?A|JsNdHWMTwqJJy9|`{Izk zep*KLQ4fl@wXeD+!9)H1EwbOLKZk+du?iTxN(l(3TxEo|fo(rWJe*z@jKGOZ{Jh%_!S%`=u z-NHRK^Y}{BOd}DHDlwV|!{N{{*!6<|%nm*1Us5aF4BLZj9Cj%LbtO^8&b`^mo2yPqPTmdSI-d``3T?TwT3h)_vud}b z4PUl*x~S%t8fVzc{ms0!xks)1JVB}P*5*d(GpRY%=)q+}v5;8G=H;gNKJ=CZWAgolaRwvjuqBIO%(){CHp|9dWef&1dD# z9%*mZxAFrmy1a*+hanG-D41pK`K6a@j!1~bhV+SS^qHEJ$`LmiU%SP45)R|4;Or*+ zckdX2;bjc-@`N9>!|uX>2#Cm8RQu-jL!PL>ASH|==%iuWcKUch{y;(FNG zQ(a5kWWV7z^A&PlWGww_QX`;0zV>Pipal7mJRZ zKXqy8Z!e3-ur(FH%g14|$E(`8qrOaptI9SJ5L>zU4-bqwAEoY3>^!%YBl}DPVQ$0J zF(yS$AipHyJ5D5;IKL!a(YzRNzfU3ec8lG4|Ak!m*mv6*bymD{mGhX$qL4nY*-1zxMeg9Tb6OWL}r33Jx4^vi! zio@HMP?%pIiSkret9?E93i`|!WBy5fWll~gyR6_h(q;!9*!G~i7Jg%QoQ&?>GG@K6 z$?UXf<(f+?K&T22evVtfUe zERm%7dGQBOF;|NR2Ae;dxs*Ek|JL?8EVFi;c@bHEO2nd9%#GtEy!(r`vMe%w9A)Hj zN)*J#wIbYv)I5N%un}rX!FQ%@Vvj_*u)(3(`wbkkeVke{LR-`aZ|C;zf-&q&o!H0ev2_+YX^ zWqlCcK33XtUcG7{f8##V!tQMsQ_N-m!L#OC?ClMA@odxbqGMhQjV`XdP3TY0R0t}K zj*+c3vo$_K$bdhPJ1w1#bF7FIW-~`Qj};NeItoqW`WWP-mOvibV!=GmG*@cUm3v*; zA!?&F0f?52^e!1b`SnUsQ#d$pF6qjrfeZ5Sp1oeSWw5PcVsjgr({PVP3Gn;Sr+CnO z0lgD8R35r`>9E2Ahna&N>{M2O6Jj)!Q}so!6y~WmEZ}wX5b~k9Ri#2A%Cc3keL`tc z2k%EjJ6<&Q!;> zw!QLvdgS)rTEcIQmRsXzl#V}nZ}!)+4bH0i3~5S41brP@nxAgXHnjj*m?-@N+E@CX z+Nh3gFw)o@Y}0$vUfl!E89BdU2GNDKPOm)|g=JWsFQHRnn8Mv}J~K^+75~aUz_aH)YqqaK-WyiSIvTuu6uITWg`^z-_d?~}%rFi= z5SI90(w3Jx02T^g|A5WRo(mn*Y`&~6>_2`NaQN_rr3PD>kH(cQ z1Zgdblf`AR4PCJpU)A0g-C=p^B*WAbRviEXlA~i05uX)Iy0iTK7zBOQEu+Ro^S@Je z^j$db0LbZ%u*BE3_2~_*g=Qh(ye^=QN{4Pfc7HBjrqtioGAa!0d_(_rV(V8Xj_}Bx zU~8Mlnus$?=Gu9#RXG{lvCY+;H~;;rIFob3c7lsqnbkmkyr|icHNQ5(2m}^tX<+I1 zY%S1%4L#n|@-ll&5`23Ga6)rZ@*-(waPQBj>8lk4SL@ghF5{T6HpAveGWa(ZkFDKJ zLpEy1Ydq@qeR2J*)2D>X6Ei6PTMp*|0(MXB1UupZJ+SO?!bY=TdePzHWsU>lQ_J9cj0+NtW2o52F62OVUw{|>6z<^*8 zks_!KVGsh?fPm9&8)VQrf(l}-^IWa9wYK)^t=|sV-oE|rdhfT^UEll1UES=n-P766 z*}rGpJ1$(YA|7z~L;6|!CQw^sq9N#+w|aHf99gt4t~#U|J6WA1x)W?OkT=`>a|j&V0e&$wT| zEjHwSQ{9%3ulb#WVb(sKXQQJ1h7*?U{gl4=-JH|GcXz%jEXVf2Mc)!ecTQ!7G0e+r z1&vkNXsPjSae+kJg!x<9k?rgg?XIVWJQsd1lsE(o%@oJWV&o|0Eq-%d+J$v_7uLO( zR8^3C;Ju^+1<9iYi+?Ie;S|2g&)&QGlR1xVor{6aBe?RWK+kj0-w4)I@(WvWNHs&k zwJhfe%IhKgvY-D=$x~O#9cFNI&Kc1j6#@ zTGyj%J;hSbquD}>F@%o+;wd2&_GkOg&+$K+GaKdkxuP#BqEG!0J>gd-nAr|M___A4 zb^QXNA@wWrVN71oM%;HTugoABGs{xOU?I`6oLa^_n{i5L zg0}V+w|cPp$*Eww>f5?zcFnn-B3aGUgUwYnV;syn?R*pQQgD1nzi!81b6;;$s?K&tMU+d!alu!zX^`9Jx&X=DL+hALU)zU$A&I@9Ks3u3jizIKo6$ZD+443oZ&xXGHe7_Ad&#zq4*p z$)+-o@W^l6<4-cFT~&jT1?=-T6d99qWSdLdQX@irx(B50x0@`G*<(PhGuR!)Tw^G% z3n)nQ%qj95#IUhb4rWh*l4;1FaF|0lh{v1%UWo|#OQ3BF3V$N-FA+c@j@hBdDXi9g8cqgbu<0gI&W(KR zPcBP(Jo_z|XoqWwPO~ReTb%nE)6KDM;w}L7g)cRv-GF%6h9e`uN9tnB9gFU;^m7!x|vvc zw@A;gZZsU4jtHF@b5SU`ORxT|+dqbltT3|1izim!DKf8MFzmHPGtc?QpqUqF`t<6? zW&`ph#Ms2)yu}l><~{@RF1UG;eDQ_tX`~vxcWAGWA{%cz>kNjk5AB_H0#E>TaeG=4 z{hGPeAq2Q)!hmaHgnZG|!I%_t;4!dWI(VQ(vQUx|<=0@d%s$MjHYGYN!aY?g^%gW( zg?W2zmxe|()JtbX`7~5YY3|$0qnf$(QmKFja#-uM=qLDUm*>L42W^Gi?d>V?PX(dJA&z&nO(c5BDf>V8`tliisIIc^7`?f>e**rp}&6jD~z)j zBW{?1@;YJWQM18dg<9tjPzC0A*I;;Xq}z=Dg}jtYX7C>zG9lda(wq;N-M7#hVBs17 zZ(~Yc{x*HP2{}64>@V~E7y=Y?(cSBrVG)9Yvi~mr7>V8?nXgVLfh8%gYHO{2e`@*1 z`Q`s-ZB&uj)|CL9(*+bFDZg}PtLHAqE%b>l9rnPmL|hNm`rY%aD36MA3@Zuddu^{& z6t{(G{TL1P=M`CgPG^EGYU?W$#e(h|h(V|iZAG!j+P$GdvDv4aQ4=a|nc1@`(DL41Ec8%~Vq%#KC@u*gv z?>q1lXIZP?UBx#0BhTF8ebD4gBnuv?rOg8hBsi97C8a*Y6*;GAK+FjO!iy6+)miS8 zQfE2QjT~dlL3D;hqBmfcFtc1q>p3|{%((gHlUO}tY#|a^KSzU6&2F4cNt?LGCGQyBUO7OyA@LOUIC&p9y=pItPqW{fhcrj zWrtag4^)(+c@3`y5Fxbws{up^Ei?WGs+dFY?dG}W%2?TKuA%05IX=*U2%*mLE;Aw2 ze6`*fp$e(@coUglirM;kc>DCl&fGg2pU<8VO^oR*I-xNw+B-)SEhX88W1ts1MRog1VPE<*4RMY%&OZ?^s-3Q+EXdglbPRi?sb*zgic*cO!-Drxm^n z#|B3u4j&+=Qx*;OFSZC{gfTUVt^{To6m-3C>Xpa&lXmLjWnUAB4uBh6L+0xu@Ob(i zH}5@u29_*mcY$AUC~Iu^FYpW?LP~12>34!cX3r(UMBx!p(XnyJykTRWkN}Lq7(Z~D z+YH9|Rf!3Ck6)A7EjD@1ZxclFCp0A6qeN0+J} zzjpiWH^Pq(Ep&M?|KJs@Yk0;?noV|zA1qnaGJWwk-@bghbC%$nE9$nVza&NeB7c9k zjT_9iRNws~y5{fh0qWeJJ?nQ(ow@SIc^PM$hR--H@XV*Nj9vTkOuoWc7OPZC#yTeF z7O#|34E_4+Plt+}dWzX?UMIabMO=~8o&%m0UG{Wc@EP^l#QVIZ{g>2prfu|3ICSi4 z2%F_;uTdo0nwrFiIvU-E7{xsOJW6rM`C3+;QgUd?)32w~Hk08VTHb-KBNMvi$t?ka zu;}`_ln;**Sr^H51(youxKY~ED2mVDh~7v2IRfjpY?QZVv|v67^3Xj7?Mg|PHod2s zk#OtgJ~36?%Wqw`!ciqI!4*vT=AlsdQtoscJb z3?qm|TY|jgQ3jgI(~?`ms-QN0IyvFFQt>cr*}AHAQwoQTE{&WFkHCaUprb+sAp=RP zRf5=0EEzhM;TZZ@uP;=$`?aZ>nsDAOL7IdR_g^_3k`QlY&_~WxdtGw2(rcPry1NT8 zj<@%ZPJe0H<)U>lggqntPumElxTp;CVBz~Ei63o}(f1UJj zW~k6u;6o*7NvC(ft%wm1JbBjF8w>`;q>Z7+dtzHM@-pO9Ke{XI%&^YPFjyhky_PKB zgPD*Fh5=ZEQ|^sbLLeZMwJRhcg`p&b2409f;&r1kG%l-@cWcIcJkBw0-f*=dKwXIi zec)b3(jNa}JvaQMHTEoKQU1gU1@eydB~>f%{HuN9x4w%@^s4#r%N`tptU7VH2Axb> z0Euq_wa1w43?oC?fkdOv@gf)y|$F7CJio#St>9oZ^jLj&;jd zSb_FzXP20e_4{YVykm`m3^9!=H!}Cr&2sJAK6| zIu3e`UA?{-h_W=LwR}*GCd*>j1mV-@qtoK_h1$e8`Zd$UDfQ2o&S5AD!6%#87wAaE zdzrNf&qDctA93)#QRM6UXej~9GV=_${lMoNo=o|>1C7M zY?}D&=OI^rxsm!T~b!3YIOOGXFw2iJ31PT}ot2Jf*`uI94oa7g$FuXyRq1eAX zMZnNC6>Aw*-lRb>E0==-lNAZ?Y??VN1qzHbGu~Z&aFGK>h$OjRC)m80?R@=>1)Lv2 zXGjoP6LYsk_nuI{xOD2qOO34F({ZC-n=p+IyTdy%Z0?nci62g>dHcD0DF>*iWr12B zJik5xS*6ECL|I((c^U-deGm1NstWoyYv?t1?)(tEXQRhd!9(KY!?GJhv=BjoEZ%v& zULV=!=bc#Mt+V20)Pc7i%3apsNE*P@~c=oI%Z7oDh!IcVPAVhQg*`TBO8h)QPvjfT9A)J*|$XwxV=KCiHt*5$v4wQ_*C^ZM&2dB!={=DZYF_0r)_8{Fn#sY&SN_=Lh9>-vLgZ}y9VQAliXuK?zmtT26{`7fsRYM zfU=Iy?+yfQ+Xg&*HqZlfS}ZQB0}^CdfEE*f!-N(~?vFqYQ;l!GLope9n4-3C4(4k# zN15|2x9?T&^~AK?i527tN9Og7nvM!ka)rF&MYC<@d z(o8ro>g{df3n?JNz~@EpQW)F-I${Xl=nCm_iVk-z4~qF}8WS=08JM^7nT*BEL+um`pb02yo%E@LSH*ed{A%Yn9z=W38w6WGy*sG0pMq z4-jw2h4fUiBbLTsJe56xl35~6t8K)(*`_I;abNVUta8JvCU&lU%2~7KZyTubiv-Pm zu2OB$6Tx2ga(iGCG*4XtOCo89@Zn-GK!OdOhz4+EwpuCsb)<>~=loSx+6@92Wsn%H zB$Oo^PQZFcI%lz|a?JQ9#pKJ5b4Yd+4;yEm-;DeZcT`hNXEgPz@CFS}Kbx^{Ht6#w zO!wlpGCtH8HH)@cX{+?4S{>8ofMw;PpDGxMdtzx!Kg?8|Cx#j-(dOa=+NT=|o9?`D z?~{wNe6hFyWzw}Jn6^M*m2nwh8I}v&VmrA_x|npnak@!?SSD<3!Sxa!Ivdt>%ysN1 z(`m3!yW-d#*uw8wT0m0a0aypds@r|i&zHoVAAlw7k+^ zeC?Z!yIcKFo#D1Lvuo*KGFz$h@p&*}+fB<#r0TlKsg~M9_RpR1!|8XnG@gqO*0w*m zrhTi}Qo9urM3-6jGZy=717aFzkDw4Nyfu-@n}>;PAV9=sQj%G5VvwI(tx4@$ z@I<3{4~+W8L05x;F$L!}1^D%w3|25w>)0;o3lE6vV%6Bl#2D1H;!W=S$$RTXrjRTT z5*uuuN71q{6iN`&Nbx3CmIRnBfxM<-0|*|gg$f^~(U0Lm1Cfmu0clV%Pa&NuEF!N^ zY>x6OVAygJ${Ly;6y(h2@+hN>6}i)&tObniJ8yRFMN9#4R8lnQ zkxoFwa?E@-;Vlp z7Ei#rcW2qV9oe5J?;U+^zI%Ov9_H8Q?_it>T+p@l*wP1YY9>z~P5s z!aaMk|CU>Ei~xAL0fI5#EhywzAk}A?BYSU)wM5^vS@(CweV12TsR8A z=i-exZwjn4cyJGxv#+~-Kh_E}(SBW55xKVofjLvpju^=G()0PZI@W=GmLXq+suytI~!ju`sYd z+hR&2^k#H*#qW{F$c0Y8O~#0kd*BV>40>E2b&ahkGzRHY+d33~B@U6mK$k^4vWkwY z^m>C!67-!$@XT{$p0~rITQHr5%Tp=DB4OdK$&k^P?8p)(Y);{*it&L&ptc*hPVuz3 zE{TVVO$#;Q8g&=mM2kO#Rix3pIChw*uXA=v7$YSV8+_Pa9L=QApyr`1V5a3WaBsa; zaVg?gDjQf5WcDef3Pde9iWg|t2;un<@UA44rwm#~Q!TDiBvOcIu}HMZiDkryb|V|) za4dZ?#1VZ=#CAIP@W>1Z-ISpk41sp#CBx|>gP0?7LigCFDvP_~s_Tpc_B}gWRtp(q zct4NVO{122<3T6c%y~)HB%KBQR8zIevrrl7d=@+9O3@W;4Dhq#ZNNWEkkR1sFP#%6 zKl({=y+GHvs*w)cAA>zeMnngC z@VB#`zrV~Wf~%m{+kcyWn!Vibj;s$q8I6=pKcx6&j#7blzyhf*Ou8b z5*?4R>Yi&LuG6J0AwUZcXkdjwaD}HY?E!|d+fuBt@IqkZsdIs z4n8hzT%95E!+q0RjDN{h<(nAb6n--EzjnB~%qhq|1y5+c--lOIuB?-{Iyd+R9zIp_AGdaJQT5)qnrS zqaSFh{H@e7OKn!I9M=Vk3Av+KF1BItc&b(}D-y}Ka^i|AbcJAl@nVYsHyEY_CfJ0= zvE`G*A}R*0EE=$St{5F0&U+Xqp6NT?>)7?j&qUR_;P8)F zTl0O>1hfW~{XpKA-77ar`kVCV_BC+%@@YIS@>uucO3~TC2S;=Z3v8F)kq^^>ZQ-P} z84by6qN7`hwgJ#yD^zcj_p)Wc%#`_|->hksOaY5kla+E=CKrp_)gL<6^#dg2W^}56 zxz7$RP1+I91PQZE1x8NYa1pZ1qz~P9VB~AjCSw@;J=|PLr*O32_AWU_@RaXV`jsGk7CL5hlTe=MNb)SBi>kNPR|~8YAoXTd#Q? z7X00C$#TPT>ey8Y6@K?WOU$mudm;N0Yr%r>erznQd^u$PlilBY^T)$skMO^GU(WmL z{Wp&-CNHe6E1ex0OV{q-w|`=9xV1qnr=FW4_MwVrseJSXo`UK#8nxhC{W}_Ot=_Bi z*_%;IU1O4%@WZop*WR{!=gYsfequl8v&lh^-(8se@npIF>VSRfElaBZP^Z7A;u{&( z=D5o$As}2VxxkTRiL-1gFApF7SwNH!Y{_XsUkB-m##QM{a;NxF? z_5JN$+Lvj6UAq5j*w)*b&pVb%{TB~B&wIX--|_CsZ@+s#a)`Nn31(rTQdRb8s3)mP zgb;u+QJ5fW&<|yJ7aLIUfU?ZL@}h@RWztWNoV!+kFd`}B&2JY{DugE_ocvIf`I#+G z22_}_$)zp4<>0Ac3T$0%PU9DwpRGFaFu&#L;lnNXU*EX!?W4Udrsq%Yp85DfavdWv z?dRZ}oChOqvDv5h@82Ihe=AM-Y2Jf`0tqCpzHHbDS*tD|l4Ew`Y3%dk`Jctl{{zU?OZor+ diff --git a/sound/instruments/bikehorn/Fn2.ogg b/sound/instruments/bikehorn/Fn2.ogg index 3ddbcb90339b29e2ed4e764f2496a05c4ae0ae86..9db539508353991daaf0b0b3a55808628e200afa 100644 GIT binary patch delta 4657 zcmZ8j3pms5`~S}Q+;Ut+rYz{c{ueZ08-irUT_5QEx_xtU-c3=1R{yfk9xu5&{d7kgnO&l=^KN1*7gv6kK ze_thkIo(0o#jwq=xX36I}|>?BIv8xIwqx~c4iZbHG&sa)uxp zrW@0Vi0XHETx{Eqk-fp_#_BP11|87Gc?fefszTX!rm$?#;c+P8YA&D13Jqq{We zef!@QCJpS@hahA-4E$~Mclg;sa6RbN3EihTJMgL~yo%jZRsT^Hr_tOUPj*;1yO4TS zNFy$!33Vq@6Us@&$?1~|iK=2pQX>uJIgvQwPj~o_yO3U}lSZ2SC)5*;<;6~!JGp~L z0YGC%^Wwb);a>Uw=5kUM<+3D=Hd#2wkeo^W?k*(vIDhxAq+^13JV1#~<7y;Q6KVW& zI4LiFI)>zR%zykV$z46cV>EgCOZ+qfWTrZej>H1^xWNDT-PkGp;DX?g(kfPgK8sb& zY6@r7vOP-YS*5I=hCo(rO;5w^TeV?}0IjWJH5jp2Mz#y^rd8 z8kQHiCXKN=&ZO8E46m7EU?t(+r;0qjCO3rt*2ezc12PP*V4p^6wt#teA~t~-|D)l) zZnO!6Z& z@0n_PO;~17Jw|Udu;t@@yT8gl4V~bh{BAY#CARFgf^64SAP|@|(1%Kob%~Cl7;P5} zlG2$|CBhAO$QU?b0a@;XkWp zXMj}KlCp6)c5XJIuP{fLDk%f!fNsjhIfAlqIBI<|fgFYr6cWNLKwThLHZIJVPxf%+ z#KOt)qO#Z=*U%6)AF!jC2t2NyqaGT8ncavBW((P?dFmb+fSnj>Q6UHs0v_Re1O?GJ zwqTf$4glZq){%m9%m2T2N{BIEKw%5n4eE2L*?@iaIXMl>7^Hw)*@QGO#UrexA}<60 z1%xY{+2_$=7GH+RH9`_RM?j9g+Va^Ig4$`~kTp%#zjz=s7ZUE?{g(;-4#DuKKCFSP zO&?aTI?B-ojVAT&mqBs*v1l|;fR#Zp)$s<#Jl9Y(8Z5&YqC&-@?JMP!!h^{vy30bg zU^nxT-~f`^z(gbsAj(yJ;aivp@M@Ts8p6-a#tG)nw%8mtcVDkFNA?(I6stJprA}?$Qn@wh_QiiN*{J!a|bvhHR(zQ{K6z98yPiFhl~!r z4+{+31^{pynUW-6n2bRoK)}62f*6_^BLo-(IS4X10YNf#&VJE}S;aO7sIFqr8R7AX z!%CMh?9qHABbxyDz@n<76hQlUu0nu8evbt52(yTT18woi2XJhjTWGBgQ$VS)7zI-1 z%oc>=01*151%f6erJ*|UO?H-g2w8(2exg;-kf4!in2V~ERLorA0U0zeKe``X5rK&A z$IdY*Y1p~K=rn+UM?OHXbDBa^7@Z+BBJV$p?EfwUtfCrxQP#Us(lC6)CK+G=nZ2^; z(KqbZBR`*#vtG%9itq?!0~!6Nfvnr)q@gwGO|A!bp*PAK35$j+K@g%NA5TN=d_5JCWpl?=0SSV%Rt z{}7rfAYU=&Q;&lE$Qh%gSzIK5F}yKK4W@jM0CpY1w+3trawsS_)ELbXP|`S{qhR9; zC|4{5WO?XS#0iLYsP5#&-10k*p1lGeKQTxL21(e6+6P{-4gqwxSSSD;TO1II@U`pE zL0^Bx=$Rl!{S|~;&Ha)K5Xs!HfsCUzBDu(vfEZc}2uEM!p@1jLWPlh`Brv)%@E9QV zuNXrakcdzQL8vm&93dc*pU9Kd5jIRTSck4m{nupz*@+9!*RAuqWj$NMc1%AKKN{4H zgJ=p6baE_Y5iRIO@(SsBczR|OoU(mAAr*VD-v7`B9%6)nVX6`dq4R~5H0L8Xd~ukL z8ip%QKPz!Cs)iHS2W}-u8ORi_V}8LJri$nWM05!>R9x3SfbpbCNW4)tlT(oEqDKz~ zi$idFw?fusHw9%C)`e1v73AjW(=AO?NKbFPB0q1|F6lKHi=-nZbT0E?s+qJTm59@? z6^}GOl(n*BD*d`e!Jy3$l&y%|vZVl

    %a!COm6>wsMXNLwL)9UcqSVAeye^<;#}? zGRit;sN%Y|e)RIrHxeijE;KSSG9q6>knk7=-`utf3TSHY1x6LrI@7Pa?Xx;2?IeHigUy3C9B@Kh9DLW2ms z(TZIgPoh?*X?)7RyH1`Uy)-}FI+B3%-ksZ({Jf=nVS4lSndz5g2Lvk zHCW(g4KJOsSQYC`r2~Q{9KD4>xg7lE~ zp~l|l-=A2yCBK_o_6+`fRzpy+4ewhveW4WQxxIRAXdC}$#}G@*Yw8asvTCk4KS;qzDH|wa6j7IAaR{-TIo~%_t-X7f1}caDO)Ek zy&UG@R71J;HqVza35VNw%jZnGy-rWH-A7G@_dZN_dOQ+2b?llqPx_EvtZH$(J9ST1-B>ghi~YN+P437U-uQ#0`7#Y16o0^Cv{b79*-d;a zi?EB@^sVJ{=ViO%<>v~k@2Q7AjRvTN$$ooaHTZp|W1_96kOcENMx}nXN)Ct4ec2^x zA}6&XB~IUUYCP%Ff+wtExIW&?F0}V*$icJvv_wJK($Bzk?StDHiJbEK*lSAAgYLfe zwMwLB=ELkgFP6Lo0V?Nc4zW2k*^rn{0M!1NTK~bUkhtBqp?^>99m{LuNwSPib^N5#x~yi*_glCh+fgVhL&E=6~ETCTxV=X6zc_acU8=tAiEY0*uWDC5qw?Wp+&G+Ks6CwxBZgz%m`?2@H_>e$=GiI?@}=i!nn@-5Tcn!ooHKiohYnD~c{=Wt>S zPA4P1i$01acl&V=ErVx}B_j_^w=VR)L}l9~1#Mi`Y^hLDutltTV|xYi`=sJ#XW+QG2``ST4OX3l ze(%;4Tf0sF?NZ|>AG?I+AECcr51*0UlI$>Afz9r#mxRvbjuNZd%AbcSrY#is2(H*Gv0It7oH!-~df`v3B>xxmK}u(i9z0G_ms2M6OSk{_s@Lox0(VE1CG| zNxb}p%)S|3phwXDoq=sn=}Pc*D_@t!qVs`l`pVW0(q*@~)Jd#C(4j1iGZ!H1(R6Ie z_RdtX_GdYEO=_VF{nmBkcelsQML(cA-QBQsiXEoS4h$}-DYB2YFuvv%58Y8NQ#T}Y z^}^Reb3Yn;x!??kwXJPayKnAFD_UIG>bt>#ce<3Q8h;~`J7i}U99X#k=W9n@>oOwF zJ)uOeT`$zO=brL}f)u`Qr8H%c0@{u(4z*iB&}IE9T9p};cx{)xbLLDH)rPwL+2NZn z&y^atjbA#Y7jTL8@=HthmFxGD_rkQGqCX~SKd919@DPsA+XM*8xTGeQTds(w=fj|# zMMjNw=d%_rMsRO%o9;i&v#_+SnQLwhYPq}R?eJ6o`nduNZr2J^*5SdWp{TX|AMvVrOoWuzKSQsE40@`h6nqY!ZEua= z802uhue8gbNqdPgDKHDknI%7ZuKdXVL301+Zyg6if>hw!D&vQ0w^?Nu=Sp=@>zCtp z7X>wb*ynrRSxbD&mzvRb{rVNU?SVBPK$Xewq`+2uZ=IMj=TuIaC_SWeo zjm@f((B!I>#%e^!R{?c(!t9I5Ds|KbdheJs?YLvi7%z#Y8>y`Q6XBJKlcUu+N{Z)*xZ@r@QYn sHypm`xS|APstRd(d`7($Z{$I5Z$4{#KE$5(zk5O+Qg1G~mk^}*f1N=iUH||9 literal 10696 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 literal 10529 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 NcYXf4e12=#{|5)E^5Xyi diff --git a/sound/instruments/bikehorn/Fn4.ogg b/sound/instruments/bikehorn/Fn4.ogg index ee330535668791a530b932cdc39df8077ffc3f07..3744a1a3bf7ecf5a880d67c140a2a0c51903c07d 100644 GIT binary patch delta 5943 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 F_;2gwTQlwYK&P3Tm|~$ROH5snw)%?cV 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 VQQ%L0{s%D=ZRJmX{%7&?e*+9PK(hb< diff --git a/sound/instruments/bikehorn/Gb2.ogg b/sound/instruments/bikehorn/Gb2.ogg index e78f9430104e9b5bca80e50b750da3a45eaa644b..6625b93d163f096d95f29dba186dd3db47168223 100644 GIT binary patch delta 4756 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 MY5s`M-kck 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 literal 10593 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 literal 10816 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 HE#*G}vMp^@ diff --git a/sound/instruments/bikehorn/Gn2.ogg b/sound/instruments/bikehorn/Gn2.ogg index 80997735440b9188ae2748643f1dd7519ab058b3..95faf3389d70558f48b96db2ebea55558590d8cd 100644 GIT binary patch delta 4710 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 G75YDK>L%j= literal 10875 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 Z4<-1gJ^xVk|L)BHwCC@x(m#~o{{Yz3%~}8e diff --git a/sound/instruments/bikehorn/Gn3.ogg b/sound/instruments/bikehorn/Gn3.ogg index 1966dfd0e8636ccebd0f73ec2bb70920b1929843..f903ae66156a0ae6f493aa78903e0ce388ebe810 100644 GIT binary patch delta 5491 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 Ee+u$~rvLx| literal 10764 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 H+Rc9fY{l10 diff --git a/sound/instruments/bikehorn/Gn4.ogg b/sound/instruments/bikehorn/Gn4.ogg index 86f81bc1cbb9cbc359db6e5e4e6696df71b72ec8..6631da09e69426f4d082ed45c0c0319ca6e44ebb 100644 GIT binary patch delta 5101 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 literal 10818 zcmeHNdsNd$_Mbcm2?PufVnERFP9RZ&0fAy0AVJ=e5HJL>BoHKkFA!JTssRC$7^ngw z0=f_$LI4*K@X=NS@+#m1kw?|~e$>adRIS_EZuw2XcDw!U+5MgF`JK~0I?Q*@%$+-P zzw^2G&fNKi)$7+s10?uW`cCns7_k_!ZBwR1mZk4Qa#~=y1v0*QP9aw7NB&bnz!qb& z`LX%V*PTGD+;507?kO!=1@;XL@*0sDkXw&EoX)b(!bu z(qyuYH2tK$@Cn?sDPyG|RhC7`+O%;!B~_e7kw~Q*DI3JeQc8A~4AR178?(1lBC<2K z$|9u6GBG83Yj(116T)C#I4vMB76GtuE@n8TUw(Oi3;+ZG5*=x#B`G1a`qCQej`GrA zeXZYJSzfB_Cnu?y13wiMR-Roi8Fx60d}xmK9R34BnrC%GA#DmWDeOKtI9NTZLH2U@))A*3HNwh zR}$&_xUsg#_X)N0a)2?T^Gawqb0RkB_$Qcz53(-$JgRzA;O5prf$tK4u}UTcVD-~0 zXbt6=aH{!bQGgsS6RbKw3~48hwA)-5b6owL&a?0wTh5IZM8v?9ov>z`bZT4n)V7^* z<@xcacE+8`kDty@_*=f1T<|7;yYtrH^m%US6a=Vt@F}}T)7V>U?)qp@c?B&3`1b)FD^EhFA`6 zu^HUr$mKf@X3`Dk5FP?hr))mGKa;g8i#3?#2lJ|}oKH)`FT4z2@RJhsY6pPLwCUes z^C?7w&lu12T$8nODl1|NLZL_G-=~~8dw~nFJCahCCdV${FP?)%4yPs8U<2{a`aKBg59s+)+F<2_12rOWB2^2#|4W?Zzo2X#psKHOh@_;N+o#SnZ&{d{eQ zd8J`%(-lawdQ@dPU?qlpvMUvaO`i$j*tp9T4;xPtVNF?D>C$ytFhAcLvuIjZb+O0i z4jiGpR+)YpmjG+uC0BiU0jH<^+I-khZ{lh4z>!?a&LWJ2XxCs@vUuxoE1isK*FhU$mUR==-$oJRuOz zgjP)VgjQVG_3&ucai8Gy`mRZlTYV`%lvY3QQBbLrja zI!)f3PnJs5%)zQXkpZ}Q1^?tZTZn@PY(72U7}nt!afN>2IcxO`)|dsC$BKxyOc=Aw z9w$koy%NSfrQKRlN5`}Ygx=Iak9aY^#+73b(5>8szf=GKy8ZaDxqXDkXH4)tC-{sQ z!ODN{F|c=n6*10&z#as^3V{1{4OibYHJ9x7QTnH1L;7s`*ZMxLs$HwzyWb%wao`jY}C-585)v65}Uop1hkB^1Qsp<#YA4HPscK#Z~8$bwRI%eib8JW2lh^e<%b zJQ1sZA&bq5U<)Gtdr5!H@CO3_5dmo82vhiw0&48skaBMX*n5v%ObMA`$&=z{{I*+% zTih0s{1#Lgj{oEx@PK{J+P>ItK?80-Yr#>&OM7Jh2rVf)V8>C&9IWqn)bo>F!xxze zw`jnP<)tD0#`9#oEV1@qznmNZIl>UgfyFTU=Xa_NHV44FI5`f+7s16+1dvPPjv4|` zEZwpAUr+OYr~XPHLQVx>uSQ7PY%_u^N{V9_(~T43Km=;LHJgagGb8nHw}|CLGNiJS zodCfA+}=zaxx(Vz_b#iKX@<7Y!^SxWq%a6l+OuHQ?C7H%4Y*4$;JT?QjSLBo7YMt7 z9(J$PP`YVU>QE@4I0D@r@3IFwG*lIgpR~hU=p!#UJYqz2Ov0gi!m>w74Yi^{duAyV zbZPF0g27#C#m{6`1QG7Sa5qj^Sn*J)pFyiVZVWlcSrL$P%0QD^(a@xYCkcCwaUwfm zp+Zm7!qWw*XNpOfIw+OP;J7o#=_tW`+p1cteRAfw+X#RG)Mp2!ahTisRtFt`+d2fG z=&-(@Hg;eaMVy)eMC%TFpn$fZ7KbwH@k!iB$`0g&5z!$*kCFK9u7=P=q!DwT}-JaP;OWj?IRGPkQI!|ei0>XRW~RSDl0(oA8%u@$n^mGT3=sLF!z#}UYa0PK0RRT+`) z=7Kr6ErIT~UR_6BAlxCv4Lgpyz_>N7xNe?O;dki``a6!k!8kJkYC{i{(}-S2Oh*p^7ZkqR{ONKTaW)#w)nap{HJGh5ch1U)hYe)O*aN$^=1HE+r-&W#rNNjBV^>EA2&U!l|7Y_@$l(|{;mr-jOD%p=+hX*~TgyN0FaMvlX;FG>S1cf3 z%tx`~@(P!?I3BSq!Ys7zFb7y1)VjZd`GsR?acHPzfZB)Zbg)dMY7I~@vGsLVMHx)e zB_G3@x>Avf)_oT$2-4tEL~D)h>PtoY7~SN`3_GZ`bVy5D9@+(Ia4G5Z(9@9C-cL?1 zp0o#9VeJ#5q?Rt{T6M9W*3va;U&{9wAV$MlMV|Y>-^fWV%txXU^WJY4 zM>8OEIQIjm6G|$nYwvk5tW}?UwT4xO^yMK6ZwH7(p3x9ii~bN({iwca#=GzWO&EP!OE| zO$QVNrnJb(0HQ1al=R4}5AV{1i=>@^&oB8GhmGWKZn{fL@>32T| zS4Lmt^5cHURYZ?)_MFec8ydl|y>n93tj-(`326-svVK@yHyvVV*Ch;-Qv8QQLXYHP zX_%&bwQGHONm;;1IUg@^V{TP5SNS{;1PqelmYoX#%FM$8OJwKd;DI+gcs~*t8RKow zbJ^^rcD1_d&EeiIN4x;=SBw&rihc^S#+vHdfRgtc6np@NE>8!4bV|Mywf1sJc|o$*nf&QM)@VHT zc5eDh4m+}liDdW1K5I!UP`T%vxO(YpU&#t?sAgHrt5D;YnI(1u z7kPc(@BQe@_51qJLqotlsk`Awd2ABPm(!(z9_!cKLZ!sI1;unJ!bEhVKyXBKAmQ>! zl`-8m?4}>)e2YczgC(|MxBNCJ*BVC7X4>kRPJ12B(VGw9Ev(`GWc%Hjh$b2n&6k&>^}ErbyZcB4QRG& zXzh<|Q3Yl2I1_0MNw$>Nw(02Ernf)(er?N#*WRz{dgsS&nXX{eEG*LGBmCgZiyCa&N40YWj0Yr3bTI+|ENs}T0fooZ4A8=^)$CBM##6Hc0bzknr zGus|FgZHF2&=TePB~wm^8e56TAC9Xl+4QfU-8*x&xT~3Pd$xwEqBb8)t7!>I<}D&h zlasgeOS@?PlALMhJO@d;;F)TnMONTtCV{X&4;ma-ZS6J?pS}{aCtEF4TN+x@H7ZrR zf@g2=RJe~UL%F(kx21(Or`^SN9Dcue(CQ=a=LR!Z4ZjM92$9-?u>>|k7EyWkU*_Jn5j=)}16ujI}aQrz)jmrzH zr4RtZcugkQa?=r-^y{OBuGdk7mrbF(VK# z$9yqBF506I5{w&L#oDf$ZS5qau%j3oH{A2J@Eh4DNQG=PtHq?Zv>eU6VBspEcjiscy}f9Rss!$V1`HKgr`QSdq6?* zP>+*yL$>kwnTkdbL4M|L)5 zx+ZQhab4?)MOM@2(BNBppkt!tiVD#&1R$6Vb#w=_Ie^1!DmdT!{o&hW1kWWWA0;*q zaoqROsb%Hpyc~Ch5B$QJ3@?~XNQpm;Fq@b1m!p9HOqzkQ0;y@t#ZFd}_VsU#aHASg zDE6e<+@4&Z=)WjQ+IyrmM;1-G*2`)w7k1efG&K}97LvSF`PK>*Ggj*ayB5x?wP4X5a`_oPpP_xD&-Su$WkYCDPMk$ElwQ*>ABAq zUtGUcvBC+71&x!Ui5#XEczAY`O_VXSCC*g~J}8gk5_DIzg_G`|wZAQFAF^(+qfm?} z$|L#t(^sO1fE{BQ6PB(4RYCxowUb&5jInk8?7S&Yka)}s=u~(Z?iNCD*9AF#LcJ2> zHnsQicF)=s#gS6ZQk8u|cjiuP;hN>U>>qdTMu9~34O1|KmJ4V;CP1zjQv1dr2xbJ2 zry+#XZRWzIHm$q%5BtmA4XVD}AK)RTIIH2&7=&Q^TN;!6i3ZhZfV9F-Hu7pyfLy|S zVnQ-tb0$<0OMin!?MfIdQ3?{*i~0v{-b88+pNz}s*cj$HG}?PbTVL-a5uNBO6M705 z6RrzD>dt6q+6nvE_*iqN3zTZwAI0#Fy#mCEuGHI^3`fksSQ*Z22qPdZ7klq2>Uh1SAW)DPTyzdNe) z7{Dj6c+W&DP=6k$b>^CEhSwGr4a6t<`ItHh#yRYmvEXq&1Dngx)@9P#b15PJ5V zu|x$Tz+FF!pgv8bCbb{gLdaOugH)wm*qLCEJmqyx=VXX64l(bQta%Vl_A-?{+MU&D z|J??Ru(R$h+3vMAjKPyWx2|XIekXw$FgWJG*xvNPrPKcDlyjoA8z%C^B!^gz+s#II z)F~7m52kY`ktODCBK^mvbqzKe&y|ZFFKgd&XhU&bhL5`I<;$^ms5k15JMO?)We>6A zwriu0ZRF(U<%gjLsT${DHlgb9w!1iwr$)N>Fv{^kWII!-G$>c%P-0&ge>6%y=`m7~ z)j~8XSJ)LhUNKQo*Ky4{jb}ObEcOJIbTx?0=$^i&6mmDnQfLDGj5Y4yH;BNp!*4!uKB@b?Gj3&dPA$$ zwM|FndB9&%6jbZN#zqBD(4H|4aQ56tIQz_E-CG6Hx7CsC+?0p(I@Hl@HkjuX~ zN$O_wr?ZRh&br7~q2raJ=<#<6s{v{5-pLkrFxd!KGzwojN{&6-Cdudnakn4VtS}x?oXTA~BxM zWwbPvyQ&&h7mr^5{Iqq2vB!aXx(-0tloqkD2nWvCr~gNKw-+qie%U(cU@cEYJU4;Yq7#131L_d#OjEvR3Lh}Y?H zDFL6D^%tPaermKXWwhhOslDm1og7Z$)(@z?pRQatzR4r=`V5KZhB`oGzxAStS}R&j zkT0jTCvK!2xGP|;DpDMFT8=mdPaLo%K2V?*as5D|gOJf6X5y3Z7+!jzB5^`+!TD8_ z0TCE9tF+e?V>CdiPG!fSD|yDus{#wAK!r>f6lz5rdM>H3B@rrvfu^^(F*L)HxK6%h z+%*iEO-~i{v!5}Hhl19f2OKwAI}M8zMm0}2GF^q7b}gb=QoRs8Y^u24&=HC72iFzS zheL;2nWW|ckXDlL7SS{@_toiFpLv#@LJ++oN`?pl>XYiYsj;^Ozw8tf$Mc51Fx==ko}-;}k+oe0`%HbzAP zdZvt!UY09|JGMjtsEsPEtCnJ9{nz&~AZGjwHz<(n@4jY<6@kOqmxze^HvBq5oO^IH z{%$r=MxB(ClT1kD6vJ3Wp0um}@)c9&T{EV2y8`>+^wl)Y{o%*MpCA2xt)?T#tH7}) zf2BlDK~t$HQ0Au-W!r#N2mef^;G zFAK6epIcgo45&GxRp+W+eN$5udp4j}S8rIg+}wNT9r?|*{V#$;#9xPxj?xFh&Edr* zJpE(Y`gBpBPOHdioj&Z9rch0*tgBr$^74klPs9@y!kDl{oPI%bcbmJwfY*ae922@? zrc;eu7E!3l&l%o;?rMF6nh2xTyWCnNNJI!sjGtmutVFC$E>-?akb-tcQq;*MFO_N! zVFuT7k*$c}jztly_9dpP4Fvu8J^dOZMeB;7CH%W1#RTChHOm`o0NQGBgYU#A%lPjk zD|V5=*)e);pJ?_%@YCQ)C9eSGrd z?E+T(z`c*3jLWIJlz)3gTDw9vRQO8fu#j&vK-t#cr?4$QOiO{r4_sAZ%YB7MxEUK- zge|5Dankx};j;}_JB0`ycZ{SlT53bUkT7=@?(7(RY^QZRv-frS(=YG4p4 Date: Fri, 10 Jan 2020 20:34:11 +0800 Subject: [PATCH 067/203] banjoslap --- sound/weapons/banjoslap.ogg | Bin 0 -> 19084 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 sound/weapons/banjoslap.ogg diff --git a/sound/weapons/banjoslap.ogg b/sound/weapons/banjoslap.ogg new file mode 100644 index 0000000000000000000000000000000000000000..06a86a535dd36afcbbf917b087287ee5d7120e98 GIT binary patch literal 19084 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 HZUYwrM3c=l literal 0 HcmV?d00001 From c9375a1288afeec899f99448ab21e6b7278e434f Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Fri, 10 Jan 2020 14:19:22 +0100 Subject: [PATCH 068/203] Fixes reagent containers examination. --- code/modules/reagents/reagent_containers.dm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index d869e086a5..97bc054ecd 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -35,9 +35,10 @@ /obj/item/reagent_containers/examine(mob/user) . = ..() - . += "Currently transferring [amount_per_transfer_from_this] units per use." - if(possible_transfer_amounts && user.Adjacent(src)) - . += "Alt-click it to set its transfer amount." + if(length(possible_transfer_amounts) > 1) + . += "Currently transferring [amount_per_transfer_from_this] units per use." + if(APTFT_altclick && user.Adjacent(src)) + . += "Alt-click it to set its transfer amount." /obj/item/reagent_containers/AltClick(mob/user) . = ..() From 7392760f383739d0d87e42fb83d1c071ca422093 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Fri, 10 Jan 2020 12:48:19 -0800 Subject: [PATCH 069/203] Update scanners.dm --- code/game/objects/items/devices/scanners.dm | 23 +++++++++++---------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index ee41307960..7d00967e6d 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -466,17 +466,18 @@ SLIME SCANNER msg += "Subject is not addicted to any reagents.\n" var/datum/reagent/impure/fermiTox/F = M.reagents.has_reagent(/datum/reagent/impure/fermiTox) - switch(F?.volume) - if(5 to 10) - msg += "Subject contains a low amount of toxic isomers.\n" - if(10 to 25) - msg += "Subject contains toxic isomers.\n" - if(25 to 50) - msg += "Subject contains a substantial amount of toxic isomers.\n" - if(50 to 95) - msg += "Subject contains a high amount of toxic isomers.\n" - if(95 to INFINITY) - msg += "Subject contains a extremely dangerous amount of toxic isomers.\n" + if(istype(F) + switch(F.volume) + if(5 to 10) + msg += "Subject contains a low amount of toxic isomers.\n" + if(10 to 25) + msg += "Subject contains toxic isomers.\n" + if(25 to 50) + msg += "Subject contains a substantial amount of toxic isomers.\n" + if(50 to 95) + msg += "Subject contains a high amount of toxic isomers.\n" + if(95 to INFINITY) + msg += "Subject contains a extremely dangerous amount of toxic isomers.\n" msg += "*---------*" to_chat(user, msg) From 9cec806875873a787443f36e9f2085b1b22d649f Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Fri, 10 Jan 2020 12:48:55 -0800 Subject: [PATCH 070/203] Update scanners.dm --- code/game/objects/items/devices/scanners.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 7d00967e6d..069c921914 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -466,7 +466,7 @@ SLIME SCANNER msg += "Subject is not addicted to any reagents.\n" var/datum/reagent/impure/fermiTox/F = M.reagents.has_reagent(/datum/reagent/impure/fermiTox) - if(istype(F) + if(istype(F)) switch(F.volume) if(5 to 10) msg += "Subject contains a low amount of toxic isomers.\n" From 96c75eb5ca1c8987c02fbc9018dabb5d934f0e5d Mon Sep 17 00:00:00 2001 From: r4d6 Date: Fri, 10 Jan 2020 17:01:46 -0500 Subject: [PATCH 071/203] Add a message when pulsing the open wire on airlocks --- code/datums/wires/airlock.dm | 2 ++ tgstation.dme | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm index db6d80f9bb..ac4473845d 100644 --- a/code/datums/wires/airlock.dm +++ b/code/datums/wires/airlock.dm @@ -85,6 +85,8 @@ INVOKE_ASYNC(A, /obj/machinery/door/airlock.proc/open) else INVOKE_ASYNC(A, /obj/machinery/door/airlock.proc/close) + else + holder.visible_message("You hear a a grinding noise coming from the airlock.") if(WIRE_BOLTS) // Pulse to toggle bolts (but only raise if power is on). if(!A.locked) A.bolt() diff --git a/tgstation.dme b/tgstation.dme index 1a79c32dcb..db57c39fac 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -470,8 +470,8 @@ #include "code\datums\elements\_element.dm" #include "code\datums\elements\cleaning.dm" #include "code\datums\elements\earhealing.dm" -#include "code\datums\elements\wuv.dm" #include "code\datums\elements\ghost_role_eligibility.dm" +#include "code\datums\elements\wuv.dm" #include "code\datums\helper_datums\events.dm" #include "code\datums\helper_datums\getrev.dm" #include "code\datums\helper_datums\icon_snapshot.dm" From bb26f21c71d7710bb17f3758acd3ce19322bb14c Mon Sep 17 00:00:00 2001 From: BonniePandora Date: Sat, 11 Jan 2020 02:43:58 +0000 Subject: [PATCH 072/203] I have no idea what I'm doing to be quite honest --- code/modules/admin/verbs/SDQL2/SDQL_2.dm | 7 +++++++ code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm | 3 +++ 2 files changed, 10 insertions(+) diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index f5075b57b7..d2693a83b6 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -95,6 +95,10 @@ Don't crash the server, OK? + "UPDATE /mob/living/carbon/monkey SET #null = forceMove(usr.loc)" + + Writing "#null" in front of the "=" will call the proc and discard the return value. + A quick recommendation: before you run something like a DELETE or another query.. Run it through SELECT first. You'd rather not gib every player on accident. @@ -740,6 +744,9 @@ GLOBAL_DATUM_INIT(sdql2_vv_statobj, /obj/effect/statclick/SDQL2_VV_all, new(null var/datum/temp = d var/i = 0 for(var/v in sets) + if(v == "#null") + SDQL_expression(d, set_list[sets]) + break if(++i == sets.len) if(superuser) if(temp.vars.Find(v)) diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm index 97a799824b..5b6d2155c5 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm @@ -217,6 +217,9 @@ /proc/_step_away(ref, trg, max) step_away(ref, trg, max) +/proc/_file(name) + return file(name) + /proc/_instantiate_at(thing, location) new thing(location) From 2453e95eee75a1884c5c015b1a0743d1fd35ea68 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:16:51 -0500 Subject: [PATCH 073/203] moves this --- code/init.dm | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 code/init.dm diff --git a/code/init.dm b/code/init.dm new file mode 100644 index 0000000000..04dbddc118 --- /dev/null +++ b/code/init.dm @@ -0,0 +1,5 @@ +//init file stolen from hippie but the real question is why + +/proc/cit_initialize() + load_mentors() + initialize_global_loadout_items() From 9f85b541659014c3ca010e1df51e61541eac6071 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:17:52 -0500 Subject: [PATCH 074/203] moves this --- tgstation.dme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tgstation.dme b/tgstation.dme index a6d8501b04..9da63745c9 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -15,6 +15,7 @@ // BEGIN_INCLUDE #include "_maps\_basemap.dm" #include "code\_compile_options.dm" +#include "code\init.dm" #include "code\world.dm" #include "code\__DEFINES\__513_compatibility.dm" #include "code\__DEFINES\_globals.dm" @@ -3061,7 +3062,6 @@ #include "interface\interface.dm" #include "interface\menu.dm" #include "interface\stylesheet.dm" -#include "modular_citadel\code\init.dm" #include "modular_citadel\code\__HELPERS\list2list.dm" #include "modular_citadel\code\__HELPERS\lists.dm" #include "modular_citadel\code\__HELPERS\mobs.dm" From 820eeceb12052d14dcce7527d8599061dcf32cf7 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:18:03 -0500 Subject: [PATCH 075/203] bye --- modular_citadel/code/init.dm | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 modular_citadel/code/init.dm diff --git a/modular_citadel/code/init.dm b/modular_citadel/code/init.dm deleted file mode 100644 index a85c3a249c..0000000000 --- a/modular_citadel/code/init.dm +++ /dev/null @@ -1,5 +0,0 @@ -//init file stolen from hippie - -/proc/cit_initialize() - load_mentors() - initialize_global_loadout_items() From 25422542c9816065c48de6630901591f88e03e3a Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:19:00 -0500 Subject: [PATCH 076/203] this --- code/game/objects/effects/spawners/lootdrop.dm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm index 4540e48ebc..6e3d995edb 100644 --- a/code/game/objects/effects/spawners/lootdrop.dm +++ b/code/game/objects/effects/spawners/lootdrop.dm @@ -378,3 +378,11 @@ /obj/item/circuitboard/computer/apc_control, /obj/item/circuitboard/computer/robotics ) + +/obj/effect/spawner/lootdrop/keg + name = "random keg spawner" + lootcount = 1 + loot = list(/obj/structure/reagent_dispensers/keg/mead = 5, + /obj/structure/reagent_dispensers/keg/aphro = 2, + /obj/structure/reagent_dispensers/keg/aphro/strong = 2, + /obj/structure/reagent_dispensers/keg/gargle = 1) From 0079a5acad02b4f002d4d019cb6ef6971568ae50 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:19:13 -0500 Subject: [PATCH 077/203] byye --- .../code/game/objects/effects/spawner/spawners.dm | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 modular_citadel/code/game/objects/effects/spawner/spawners.dm diff --git a/modular_citadel/code/game/objects/effects/spawner/spawners.dm b/modular_citadel/code/game/objects/effects/spawner/spawners.dm deleted file mode 100644 index b6fbeef4c9..0000000000 --- a/modular_citadel/code/game/objects/effects/spawner/spawners.dm +++ /dev/null @@ -1,7 +0,0 @@ -/obj/effect/spawner/lootdrop/keg - name = "random keg spawner" - lootcount = 1 - loot = list(/obj/structure/reagent_dispensers/keg/mead = 5, - /obj/structure/reagent_dispensers/keg/aphro = 2, - /obj/structure/reagent_dispensers/keg/aphro/strong = 2, - /obj/structure/reagent_dispensers/keg/gargle = 1) \ No newline at end of file From 046c56c194f0916ec9f4ffde2d13b8069942ce3f Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:19:33 -0500 Subject: [PATCH 078/203] cya --- tgstation.dme | 1 - 1 file changed, 1 deletion(-) diff --git a/tgstation.dme b/tgstation.dme index 9da63745c9..4c969e175e 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -3077,7 +3077,6 @@ #include "modular_citadel\code\game\machinery\wishgranter.dm" #include "modular_citadel\code\game\objects\cit_screenshake.dm" #include "modular_citadel\code\game\objects\items.dm" -#include "modular_citadel\code\game\objects\effects\spawner\spawners.dm" #include "modular_citadel\code\game\objects\effects\temporary_visuals\souldeath.dm" #include "modular_citadel\code\game\objects\items\balls.dm" #include "modular_citadel\code\game\objects\items\boombox.dm" From 412b0175b6b9e6edc08eab1095484dd8d0175a09 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:20:53 -0500 Subject: [PATCH 079/203] new file --- code/game/objects/items/balls.dm | 92 ++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 code/game/objects/items/balls.dm diff --git a/code/game/objects/items/balls.dm b/code/game/objects/items/balls.dm new file mode 100644 index 0000000000..59b47bacbd --- /dev/null +++ b/code/game/objects/items/balls.dm @@ -0,0 +1,92 @@ +/* BALLS - GLORIOUS BALLS +// +// Includes:- +// 1) Tennis balls, lines 10 - 92 +// +// +// +*/ + +/obj/item/toy/tennis + name = "tennis ball" + desc = "A classical tennis ball. It appears to have faint bite marks scattered all over its surface." + icon = 'modular_citadel/icons/obj/balls.dmi' + icon_state = "tennis_classic" + lefthand_file = 'modular_citadel/icons/mob/inhands/balls_left.dmi' + righthand_file = 'modular_citadel/icons/mob/inhands/balls_right.dmi' + item_state = "tennis_classic" + alternate_worn_icon = 'modular_citadel/icons/mob/mouthball.dmi' + slot_flags = ITEM_SLOT_HEAD | ITEM_SLOT_NECK | ITEM_SLOT_EARS //Fluff item, put it wherever you want! + throw_range = 14 + w_class = WEIGHT_CLASS_SMALL + +/obj/item/toy/tennis/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes + altafterattack(A, user, TRUE, params) + return TRUE + +/obj/item/toy/tennis/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) //does right click memes + if(istype(user)) + user.visible_message("[user] waggles [src] at [target].", "You waggle [src] at [target].") + return TRUE + +/obj/item/toy/tennis/rainbow + name = "pseudo-euclidean interdimensional tennis sphere" + desc = "A tennis ball from another plane of existance. Really groovy." + icon_state = "tennis_rainbow" + item_state = "tennis_rainbow" + actions_types = list(/datum/action/item_action/squeeze) //Giving the masses easy access to unilimted honks would be annoying + +/obj/item/toy/tennis/rainbow/Initialize() + . = ..() + AddComponent(/datum/component/squeak) + +/obj/item/toy/tennis/rainbow/izzy //izzyinbox's donator item + name = "Katlin's Ball" + desc = "A tennis ball that's seen a good bit of love, being covered in a few black and white hairs and slobber." + icon_state = "tennis_izzy" + item_state = "tennis_izzy" + +/obj/item/toy/tennis/red //da red wuns go fasta + name = "red tennis ball" + desc = "A red tennis ball. It goes three times faster!" + icon_state = "tennis_red" + item_state = "tennis_red" + throw_speed = 9 + +/obj/item/toy/tennis/yellow //because yellow is hot I guess + name = "yellow tennis ball" + desc = "A yellow tennis ball. It seems to have a flame-retardant coating." + icon_state = "tennis_yellow" + item_state = "tennis_yellow" + resistance_flags = FIRE_PROOF + +/obj/item/toy/tennis/green //pestilence + name = "green tennis ball" + desc = "A green tennis ball. It seems to have an impermeable coating." + icon_state = "tennis_green" + item_state = "tennis_green" + permeability_coefficient = 0.9 + +/obj/item/toy/tennis/cyan //electric + name = "cyan tennis ball" + desc = "A cyan tennis ball. It seems to have odd electrical properties." + icon_state = "tennis_cyan" + item_state = "tennis_cyan" + siemens_coefficient = 0.9 + +/obj/item/toy/tennis/blue //reliability + name = "blue tennis ball" + desc = "A blue tennis ball. It seems ever so slightly more robust than normal." + icon_state = "tennis_blue" + item_state = "tennis_blue" + max_integrity = 300 + +/obj/item/toy/tennis/purple //because purple dyes have high pH and would neutralize acids I guess + name = "purple tennis ball" + desc = "A purple tennis ball. It seems to have an acid-resistant coating." + icon_state = "tennis_purple" + item_state = "tennis_purple" + resistance_flags = ACID_PROOF + +/datum/action/item_action/squeeze + name = "Squeak!" From 2f9b6f93bb9289818c66b2723d4f755684da2490 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:21:37 -0500 Subject: [PATCH 080/203] balls.dm --- tgstation.dme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tgstation.dme b/tgstation.dme index 4c969e175e..ea637139ec 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -836,6 +836,7 @@ #include "code\game\objects\items\AI_modules.dm" #include "code\game\objects\items\airlock_painter.dm" #include "code\game\objects\items\apc_frame.dm" +#include "code\game\objects\items\balls.dm" #include "code\game\objects\items\blueprints.dm" #include "code\game\objects\items\body_egg.dm" #include "code\game\objects\items\bodybag.dm" @@ -3078,7 +3079,6 @@ #include "modular_citadel\code\game\objects\cit_screenshake.dm" #include "modular_citadel\code\game\objects\items.dm" #include "modular_citadel\code\game\objects\effects\temporary_visuals\souldeath.dm" -#include "modular_citadel\code\game\objects\items\balls.dm" #include "modular_citadel\code\game\objects\items\boombox.dm" #include "modular_citadel\code\game\objects\items\stunsword.dm" #include "modular_citadel\code\game\objects\items\devices\radio\encryptionkey.dm" From 4ebc80e13755c9fd95c084d8bcd117e1b6536540 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:21:45 -0500 Subject: [PATCH 081/203] bye bye --- .../code/game/objects/items/balls.dm | 92 ------------------- 1 file changed, 92 deletions(-) delete mode 100644 modular_citadel/code/game/objects/items/balls.dm diff --git a/modular_citadel/code/game/objects/items/balls.dm b/modular_citadel/code/game/objects/items/balls.dm deleted file mode 100644 index 79552bff6d..0000000000 --- a/modular_citadel/code/game/objects/items/balls.dm +++ /dev/null @@ -1,92 +0,0 @@ -/* BALLS - GLORIOUS BALLS -// -// Includes:- -// 1) Tennis balls, lines 10 - 92 -// -// -// -*/ - -/obj/item/toy/tennis - name = "tennis ball" - desc = "A classical tennis ball. It appears to have faint bite marks scattered all over its surface." - icon = 'modular_citadel/icons/obj/balls.dmi' - icon_state = "tennis_classic" - lefthand_file = 'modular_citadel/icons/mob/inhands/balls_left.dmi' - righthand_file = 'modular_citadel/icons/mob/inhands/balls_right.dmi' - item_state = "tennis_classic" - alternate_worn_icon = 'modular_citadel/icons/mob/mouthball.dmi' - slot_flags = ITEM_SLOT_HEAD | ITEM_SLOT_NECK | ITEM_SLOT_EARS //Fluff item, put it wherever you want! - throw_range = 14 - w_class = WEIGHT_CLASS_SMALL - -/obj/item/toy/tennis/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes - altafterattack(A, user, TRUE, params) - return TRUE - -/obj/item/toy/tennis/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) //does right click memes - if(istype(user)) - user.visible_message("[user] waggles [src] at [target].", "You waggle [src] at [target].") - return TRUE - -/obj/item/toy/tennis/rainbow - name = "pseudo-euclidean interdimensional tennis sphere" - desc = "A tennis ball from another plane of existance. Really groovy." - icon_state = "tennis_rainbow" - item_state = "tennis_rainbow" - actions_types = list(/datum/action/item_action/squeeze) //Giving the masses easy access to unilimted honks would be annoying - -/obj/item/toy/tennis/rainbow/Initialize() - . = ..() - AddComponent(/datum/component/squeak) - -/obj/item/toy/tennis/rainbow/izzy //izzyinbox's donator item - name = "Katlin's Ball" - desc = "A tennis ball that's seen a good bit of love, being covered in a few black and white hairs and slobber." - icon_state = "tennis_izzy" - item_state = "tennis_izzy" - -/obj/item/toy/tennis/red //da red wuns go fasta - name = "red tennis ball" - desc = "A red tennis ball. It goes three times faster!" - icon_state = "tennis_red" - item_state = "tennis_red" - throw_speed = 9 - -/obj/item/toy/tennis/yellow //because yellow is hot I guess - name = "yellow tennis ball" - desc = "A yellow tennis ball. It seems to have a flame-retardant coating." - icon_state = "tennis_yellow" - item_state = "tennis_yellow" - resistance_flags = FIRE_PROOF - -/obj/item/toy/tennis/green //pestilence - name = "green tennis ball" - desc = "A green tennis ball. It seems to have an impermeable coating." - icon_state = "tennis_green" - item_state = "tennis_green" - permeability_coefficient = 0.9 - -/obj/item/toy/tennis/cyan //electric - name = "cyan tennis ball" - desc = "A cyan tennis ball. It seems to have odd electrical properties." - icon_state = "tennis_cyan" - item_state = "tennis_cyan" - siemens_coefficient = 0.9 - -/obj/item/toy/tennis/blue //reliability - name = "blue tennis ball" - desc = "A blue tennis ball. It seems ever so slightly more robust than normal." - icon_state = "tennis_blue" - item_state = "tennis_blue" - max_integrity = 300 - -/obj/item/toy/tennis/purple //because purple dyes have high pH and would neutralize acids I guess - name = "purple tennis ball" - desc = "A purple tennis ball. It seems to have an acid-resistant coating." - icon_state = "tennis_purple" - item_state = "tennis_purple" - resistance_flags = ACID_PROOF - -/datum/action/item_action/squeeze - name = "Squeak!" \ No newline at end of file From e5e58518e4a9015d70827594c7de2c933c83a412 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:22:44 -0500 Subject: [PATCH 082/203] boomers --- code/game/objects/items/boombox.dm | 61 ++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 code/game/objects/items/boombox.dm diff --git a/code/game/objects/items/boombox.dm b/code/game/objects/items/boombox.dm new file mode 100644 index 0000000000..10d12f1973 --- /dev/null +++ b/code/game/objects/items/boombox.dm @@ -0,0 +1,61 @@ +/obj/item/boombox + name = "boombox" + desc = "A dusty, gray, bulky, battery-powered, auto-looping stereo cassette player. An ancient relic from prehistoric times on that one planet with humans and stuff. Yeah, that one." + icon = 'modular_citadel/icons/obj/boombox.dmi' + icon_state = "raiqbawks_off"//PLACEHOLDER UNTIL SOMEONE SPRITES PLAIN NON-FANCY BOOMBOXES + w_class = WEIGHT_CLASS_NORMAL + force = 3 + var/baseiconstate = "raiqbawks" + var/boomingandboxing = FALSE + var/list/availabletrackids + +/obj/item/boombox/attack_self(mob/user) + . = ..() + if(boomingandboxing) + SSjukeboxes.removejukebox(SSjukeboxes.findjukeboxindex(src)) + boomingandboxing = FALSE + to_chat(user, "You flip a switch on [src], and the music immediately stops.") + update_icon() + return + if(!availabletrackids || !availabletrackids.len) + to_chat(user, "[src] flashes as you prod it senselessly. It doesn't have any songs stored on it.") + return + if(!boomingandboxing) + var/list/tracklist = list() + for(var/datum/track/S in SSjukeboxes.songs) + if(istype(S) && S.song_associated_id in availabletrackids) + tracklist[S.song_name] = S + var/selected = input(user, "Play song", "Track:") as null|anything in tracklist + if(QDELETED(src) || !selected || !istype(tracklist[selected], /datum/track)) + return + var/jukeboxslottotake = SSjukeboxes.addjukebox(src, tracklist[selected]) + if(jukeboxslottotake) + boomingandboxing = TRUE + update_icon() + +/obj/item/boombox/Destroy(mob/user) + SSjukeboxes.removejukebox(SSjukeboxes.findjukeboxindex(src)) + . = ..() + +/obj/item/boombox/update_icon() + icon_state = "[baseiconstate]_[boomingandboxing ? "on" : "off"]" + return + +/obj/item/boombox/raiq + name = "Miami Boomer" + desc = "A shiny, fashionable boombox filled to the brim with neon lights, synthesizers, gang violence, and broken R keys. A worn-out sticker on the back states \"Includes three kickin' beats!\"" + icon_state = "raiqbawks_off" + baseiconstate = "raiqbawks" + availabletrackids = list("hotline.ogg","chiptune.ogg","genesis.ogg") + +/obj/item/boombox/raiq/update_icon() + . = ..() + if(boomingandboxing) + START_PROCESSING(SSobj, src) + else + STOP_PROCESSING(SSobj, src) + set_light(0) + +/obj/item/boombox/raiq/process() + set_light(5,0.95,pick("#d87aff","#7a7aff","#89ecff","#b88eff","#ff59ad")) + return From 0b0b80f1740683341cbdf46eae943f6c15d2af1e Mon Sep 17 00:00:00 2001 From: Seris02 Date: Sat, 11 Jan 2020 11:22:59 +0800 Subject: [PATCH 083/203] explosions --- code/__DEFINES/combat.dm | 1 + .../effects/effect_system/effects_other.dm | 13 +---- code/game/objects/items/devices/doorCharge.dm | 6 +-- code/game/objects/items/grenades/plastic.dm | 2 +- .../devil/true_devil/_true_devil.dm | 6 +-- .../mob/living/carbon/alien/alien_defense.dm | 6 +-- .../mob/living/carbon/human/human_defense.dm | 51 +++++++++++-------- .../living/carbon/monkey/monkey_defense.dm | 6 +-- .../living/simple_animal/animal_defense.dm | 6 +-- .../hostile/megafauna/megafauna.dm | 6 +-- 10 files changed, 52 insertions(+), 51 deletions(-) diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 2d40d91023..7b8c5ff6ae 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -159,6 +159,7 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( #define EXPLODE_DEVASTATE 1 #define EXPLODE_HEAVY 2 #define EXPLODE_LIGHT 3 +#define EXPLODE_GIB_THRESHOLD 50 #define EMP_HEAVY 1 #define EMP_LIGHT 2 diff --git a/code/game/objects/effects/effect_system/effects_other.dm b/code/game/objects/effects/effect_system/effects_other.dm index 18c1ff5890..dbc9b35275 100644 --- a/code/game/objects/effects/effect_system/effects_other.dm +++ b/code/game/objects/effects/effect_system/effects_other.dm @@ -104,15 +104,4 @@ if(explosion_message) location.visible_message("The solution violently explodes!", \ "You hear an explosion!") - if (amount < 1) - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(2, 1, location) - s.start() - - for(var/mob/living/L in viewers(1, location)) - if(prob(50 * amount)) - to_chat(L, "The explosion knocks you down.") - L.Knockdown(rand(20,100)) - return - else - dyn_explosion(location, amount, flashing_factor) \ No newline at end of file + dyn_explosion(location, amount, flashing_factor) \ No newline at end of file diff --git a/code/game/objects/items/devices/doorCharge.dm b/code/game/objects/items/devices/doorCharge.dm index 8def1d5ca3..e9ba9ea4a4 100644 --- a/code/game/objects/items/devices/doorCharge.dm +++ b/code/game/objects/items/devices/doorCharge.dm @@ -16,14 +16,14 @@ /obj/item/doorCharge/ex_act(severity, target) switch(severity) - if(1) + if(EXPLODE_DEVASTATE) visible_message("[src] detonates!") explosion(src.loc,0,2,1,flame_range = 4) qdel(src) - if(2) + if(EXPLODE_HEAVY) if(prob(50)) ex_act(EXPLODE_DEVASTATE) - if(3) + if(EXPLODE_LIGHT) if(prob(25)) ex_act(EXPLODE_DEVASTATE) diff --git a/code/game/objects/items/grenades/plastic.dm b/code/game/objects/items/grenades/plastic.dm index 1956a1f317..75e4e0b477 100644 --- a/code/game/objects/items/grenades/plastic.dm +++ b/code/game/objects/items/grenades/plastic.dm @@ -62,7 +62,7 @@ location = get_turf(target) target.cut_overlay(plastic_overlay, TRUE) if(!ismob(target) || full_damage_on_mobs) - target.ex_act(2, target) + target.ex_act(EXPLODE_HEAVY, target) else location = get_turf(src) if(location) diff --git a/code/modules/antagonists/devil/true_devil/_true_devil.dm b/code/modules/antagonists/devil/true_devil/_true_devil.dm index fc50a0ecf5..5725ac137b 100644 --- a/code/modules/antagonists/devil/true_devil/_true_devil.dm +++ b/code/modules/antagonists/devil/true_devil/_true_devil.dm @@ -197,11 +197,11 @@ if(!ascended) var/b_loss switch (severity) - if (1) + if (EXPLODE_DEVASTATE) b_loss = 500 - if (2) + if (EXPLODE_HEAVY) b_loss = 150 - if(3) + if(EXPLODE_LIGHT) b_loss = 30 if(has_bane(BANE_LIGHT)) b_loss *=2 diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm index b9e27c0637..837e629ee5 100644 --- a/code/modules/mob/living/carbon/alien/alien_defense.dm +++ b/code/modules/mob/living/carbon/alien/alien_defense.dm @@ -106,15 +106,15 @@ In all, this is a lot like the monkey code. /N return ..() switch (severity) - if (1) + if (EXPLODE_DEVASTATE) gib() return - if (2) + if (EXPLODE_HEAVY) take_overall_damage(60, 60) adjustEarDamage(30,120) - if(3) + if(EXPLODE_LIGHT) take_overall_damage(30,0) if(prob(50)) Unconscious(20) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 93f33c3a3d..4565725544 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -398,38 +398,49 @@ ..() if (!severity) return - var/b_loss = 0 - var/f_loss = 0 - var/bomb_armor = max(0,(100-getarmor(null, "bomb"))/100) + var/brute_loss = 0 + var/burn_loss = 0 + var/bomb_armor = getarmor(null, "bomb") + + //200 max knockdown for EXPLODE_HEAVY + //160 max knockdown for EXPLODE_LIGHT switch (severity) - if (1) - if(bomb_armor) - b_loss = 500*bomb_armor - var/atom/throw_target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src))) - throw_at(throw_target, 200, 4) - damage_clothes(400*bomb_armor, BRUTE, "bomb") - else - damage_clothes(400,BRUTE,"bomb") + if (EXPLODE_DEVASTATE) + if(bomb_armor < EXPLODE_GIB_THRESHOLD) //gibs the mob if their bomb armor is lower than EXPLODE_GIB_THRESHOLD + for(var/I in contents) + var/atom/A = I + A.ex_act(severity) gib() return + else + brute_loss = 500 + var/atom/throw_target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src))) + throw_at(throw_target, 200, 4) + damage_clothes(400 - bomb_armor, BRUTE, "bomb") - if (2) - b_loss = 60*bomb_armor - f_loss = 60*bomb_armor - damage_clothes(200*bomb_armor, BRUTE, "bomb") + if (EXPLODE_HEAVY) + brute_loss = 60 + burn_loss = 60 + if(bomb_armor) + brute_loss = 30*(2 - round(bomb_armor*0.01, 0.05)) + burn_loss = brute_loss //damage gets reduced from 120 to up to 60 combined brute+burn + damage_clothes(200 - bomb_armor, BRUTE, "bomb") if (!istype(ears, /obj/item/clothing/ears/earmuffs)) adjustEarDamage(30, 120) - Unconscious(200*bomb_armor) + Unconscious(20) //short amount of time for follow up attacks against elusive enemies like wizards + Knockdown(200 - (bomb_armor * 1.6)) //between ~4 and ~20 seconds of knockdown depending on bomb armor - if(3) - b_loss = 30*bomb_armor + if(EXPLODE_LIGHT) + brute_loss = 30 + if(bomb_armor) + brute_loss = 15*(2 - round(bomb_armor*0.01, 0.05)) damage_clothes(max(50 - bomb_armor, 0), BRUTE, "bomb") if (!istype(ears, /obj/item/clothing/ears/earmuffs)) adjustEarDamage(15,60) - Unconscious(100*bomb_armor) + Knockdown(160 - (bomb_armor * 1.6)) //100 bomb armor will prevent knockdown altogether - take_overall_damage(b_loss,f_loss) + take_overall_damage(brute_loss,burn_loss) //attempt to dismember bodyparts if(severity <= 2 || !bomb_armor) diff --git a/code/modules/mob/living/carbon/monkey/monkey_defense.dm b/code/modules/mob/living/carbon/monkey/monkey_defense.dm index df90dd56fd..cbd0c4c251 100644 --- a/code/modules/mob/living/carbon/monkey/monkey_defense.dm +++ b/code/modules/mob/living/carbon/monkey/monkey_defense.dm @@ -168,18 +168,18 @@ ..() switch (severity) - if (1) + if (EXPLODE_DEVASTATE) gib() return - if (2) + if (EXPLODE_HEAVY) take_overall_damage(60, 60) damage_clothes(200, BRUTE, "bomb") adjustEarDamage(30, 120) if(prob(70)) Unconscious(200) - if(3) + if(EXPLODE_LIGHT) take_overall_damage(30, 0) damage_clothes(50, BRUTE, "bomb") adjustEarDamage(15,60) diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index 793df63c87..5b95c670d9 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -120,19 +120,19 @@ ..() var/bomb_armor = getarmor(null, "bomb") switch (severity) - if (1) + if (EXPLODE_DEVASTATE) if(prob(bomb_armor)) adjustBruteLoss(500) else gib() return - if (2) + if (EXPLODE_HEAVY) var/bloss = 60 if(prob(bomb_armor)) bloss = bloss / 1.5 adjustBruteLoss(bloss) - if(3) + if(EXPLODE_LIGHT) var/bloss = 30 if(prob(bomb_armor)) bloss = bloss / 1.5 diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm index 8c2fbef15e..8475858cc9 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm @@ -103,13 +103,13 @@ /mob/living/simple_animal/hostile/megafauna/ex_act(severity, target) switch (severity) - if (1) + if (EXPLODE_DEVASTATE) adjustBruteLoss(250) - if (2) + if (EXPLODE_HEAVY) adjustBruteLoss(100) - if(3) + if(EXPLODE_LIGHT) adjustBruteLoss(50) /mob/living/simple_animal/hostile/megafauna/proc/SetRecoveryTime(buffer_time) From ab8e82d3df48832b7402afb88b9d4c704db05c5b Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:23:25 -0500 Subject: [PATCH 084/203] boombox --- tgstation.dme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tgstation.dme b/tgstation.dme index ea637139ec..0505947573 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -840,6 +840,7 @@ #include "code\game\objects\items\blueprints.dm" #include "code\game\objects\items\body_egg.dm" #include "code\game\objects\items\bodybag.dm" +#include "code\game\objects\items\boombox.dm" #include "code\game\objects\items\candle.dm" #include "code\game\objects\items\cardboard_cutouts.dm" #include "code\game\objects\items\cards_ids.dm" @@ -3079,7 +3080,6 @@ #include "modular_citadel\code\game\objects\cit_screenshake.dm" #include "modular_citadel\code\game\objects\items.dm" #include "modular_citadel\code\game\objects\effects\temporary_visuals\souldeath.dm" -#include "modular_citadel\code\game\objects\items\boombox.dm" #include "modular_citadel\code\game\objects\items\stunsword.dm" #include "modular_citadel\code\game\objects\items\devices\radio\encryptionkey.dm" #include "modular_citadel\code\game\objects\items\devices\radio\headset.dm" From 0f7b3f4ee89e8504c46e22bc1d53b59d3ab32050 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:23:32 -0500 Subject: [PATCH 085/203] death --- .../code/game/objects/items/boombox.dm | 61 ------------------- 1 file changed, 61 deletions(-) delete mode 100644 modular_citadel/code/game/objects/items/boombox.dm diff --git a/modular_citadel/code/game/objects/items/boombox.dm b/modular_citadel/code/game/objects/items/boombox.dm deleted file mode 100644 index 10d12f1973..0000000000 --- a/modular_citadel/code/game/objects/items/boombox.dm +++ /dev/null @@ -1,61 +0,0 @@ -/obj/item/boombox - name = "boombox" - desc = "A dusty, gray, bulky, battery-powered, auto-looping stereo cassette player. An ancient relic from prehistoric times on that one planet with humans and stuff. Yeah, that one." - icon = 'modular_citadel/icons/obj/boombox.dmi' - icon_state = "raiqbawks_off"//PLACEHOLDER UNTIL SOMEONE SPRITES PLAIN NON-FANCY BOOMBOXES - w_class = WEIGHT_CLASS_NORMAL - force = 3 - var/baseiconstate = "raiqbawks" - var/boomingandboxing = FALSE - var/list/availabletrackids - -/obj/item/boombox/attack_self(mob/user) - . = ..() - if(boomingandboxing) - SSjukeboxes.removejukebox(SSjukeboxes.findjukeboxindex(src)) - boomingandboxing = FALSE - to_chat(user, "You flip a switch on [src], and the music immediately stops.") - update_icon() - return - if(!availabletrackids || !availabletrackids.len) - to_chat(user, "[src] flashes as you prod it senselessly. It doesn't have any songs stored on it.") - return - if(!boomingandboxing) - var/list/tracklist = list() - for(var/datum/track/S in SSjukeboxes.songs) - if(istype(S) && S.song_associated_id in availabletrackids) - tracklist[S.song_name] = S - var/selected = input(user, "Play song", "Track:") as null|anything in tracklist - if(QDELETED(src) || !selected || !istype(tracklist[selected], /datum/track)) - return - var/jukeboxslottotake = SSjukeboxes.addjukebox(src, tracklist[selected]) - if(jukeboxslottotake) - boomingandboxing = TRUE - update_icon() - -/obj/item/boombox/Destroy(mob/user) - SSjukeboxes.removejukebox(SSjukeboxes.findjukeboxindex(src)) - . = ..() - -/obj/item/boombox/update_icon() - icon_state = "[baseiconstate]_[boomingandboxing ? "on" : "off"]" - return - -/obj/item/boombox/raiq - name = "Miami Boomer" - desc = "A shiny, fashionable boombox filled to the brim with neon lights, synthesizers, gang violence, and broken R keys. A worn-out sticker on the back states \"Includes three kickin' beats!\"" - icon_state = "raiqbawks_off" - baseiconstate = "raiqbawks" - availabletrackids = list("hotline.ogg","chiptune.ogg","genesis.ogg") - -/obj/item/boombox/raiq/update_icon() - . = ..() - if(boomingandboxing) - START_PROCESSING(SSobj, src) - else - STOP_PROCESSING(SSobj, src) - set_light(0) - -/obj/item/boombox/raiq/process() - set_light(5,0.95,pick("#d87aff","#7a7aff","#89ecff","#b88eff","#ff59ad")) - return From 62ebc2d2263cc310b2f0a38376cdca3050365619 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:25:07 -0500 Subject: [PATCH 086/203] zoom --- code/game/objects/items/devices/radio/encryptionkey.dm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm index cc009b5fc2..e26b9dd845 100644 --- a/code/game/objects/items/devices/radio/encryptionkey.dm +++ b/code/game/objects/items/devices/radio/encryptionkey.dm @@ -92,7 +92,13 @@ /obj/item/encryptionkey/heads/hop name = "\proper the head of personnel's encryption key" icon_state = "hop_cypherkey" - channels = list(RADIO_CHANNEL_SUPPLY = 1, RADIO_CHANNEL_SERVICE = 1, RADIO_CHANNEL_COMMAND = 1) + channels = list(RADIO_CHANNEL_SERVICE = 1, RADIO_CHANNEL_COMMAND = 1) + +/obj/item/encryptionkey/heads/qm + name = "\proper the quartermaster's encryption key" + desc = "An encryption key for a radio headset. Channels are as follows: :u - supply, :c - command." + icon_state = "hop_cypherkey" + channels = list(RADIO_CHANNEL_SUPPLY = 1, RADIO_CHANNEL_COMMAND = 1) /obj/item/encryptionkey/headset_cargo name = "supply radio encryption key" From 861a3c7a1154e84b108af6af56a2c706e38921f4 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:25:16 -0500 Subject: [PATCH 087/203] zee --- .../game/objects/items/devices/radio/encryptionkey.dm | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 modular_citadel/code/game/objects/items/devices/radio/encryptionkey.dm diff --git a/modular_citadel/code/game/objects/items/devices/radio/encryptionkey.dm b/modular_citadel/code/game/objects/items/devices/radio/encryptionkey.dm deleted file mode 100644 index 5e3d7318cf..0000000000 --- a/modular_citadel/code/game/objects/items/devices/radio/encryptionkey.dm +++ /dev/null @@ -1,10 +0,0 @@ -/obj/item/encryptionkey/heads/qm - name = "\proper the quartermaster's encryption key" - desc = "An encryption key for a radio headset. Channels are as follows: :u - supply, :c - command." - icon_state = "hop_cypherkey" - channels = list("Supply" = 1, "Command" = 1) - -/obj/item/encryptionkey/heads/hop - desc = "An encryption key for a radio headset. Channels are as follows: :v - service, :c - command." - channels = list("Service" = 1, "Command" = 1) - From 96a2ee3c3fbaced10c1d8d2373f45d925dac28bd Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:25:35 -0500 Subject: [PATCH 088/203] Update tgstation.dme --- tgstation.dme | 1 - 1 file changed, 1 deletion(-) diff --git a/tgstation.dme b/tgstation.dme index 0505947573..3459c8a5bb 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -3081,7 +3081,6 @@ #include "modular_citadel\code\game\objects\items.dm" #include "modular_citadel\code\game\objects\effects\temporary_visuals\souldeath.dm" #include "modular_citadel\code\game\objects\items\stunsword.dm" -#include "modular_citadel\code\game\objects\items\devices\radio\encryptionkey.dm" #include "modular_citadel\code\game\objects\items\devices\radio\headset.dm" #include "modular_citadel\code\game\objects\items\devices\radio\shockcollar.dm" #include "modular_citadel\code\modules\admin\admin.dm" From aacf4bec8bf3219a3cad48aedab7beb1ef616d55 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:26:48 -0500 Subject: [PATCH 089/203] qm set --- code/game/objects/items/devices/radio/headset.dm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 42d9ec0269..94ec3dc541 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -206,6 +206,12 @@ GLOBAL_LIST_INIT(channel_tokens, list( icon_state = "com_headset" keyslot = new /obj/item/encryptionkey/heads/hop +/obj/item/radio/headset/heads/qm + name = "\proper the quartermaster's headset" + desc = "The headset of the king (or queen) of paperwork." + icon_state = "com_headset" + keyslot = new /obj/item/encryptionkey/heads/qm + /obj/item/radio/headset/headset_cargo name = "supply radio headset" desc = "A headset used by the QM and his slaves." From 6abb7449c32ee9edc46830c909cd9601e033cfce Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:27:01 -0500 Subject: [PATCH 090/203] bye --- .../code/game/objects/items/devices/radio/headset.dm | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 modular_citadel/code/game/objects/items/devices/radio/headset.dm diff --git a/modular_citadel/code/game/objects/items/devices/radio/headset.dm b/modular_citadel/code/game/objects/items/devices/radio/headset.dm deleted file mode 100644 index 3d1b36f645..0000000000 --- a/modular_citadel/code/game/objects/items/devices/radio/headset.dm +++ /dev/null @@ -1,10 +0,0 @@ -/obj/item/radio/headset/heads/qm - name = "\proper the quartermaster's headset" - desc = "The headset of the king (or queen) of paperwork.\nChannels are as follows: :u - supply, :c - command." - icon_state = "com_headset" - keyslot = new /obj/item/encryptionkey/heads/qm - -/obj/item/radio/headset/heads/hop - desc = "The headset of the guy who will one day be captain.\nChannels are as follows: :v - service, :c - command." - keyslot = new /obj/item/encryptionkey/heads/hop - From 17a169b90c1f525db4074db767a838d4710a8006 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:27:14 -0500 Subject: [PATCH 091/203] headset --- tgstation.dme | 1 - 1 file changed, 1 deletion(-) diff --git a/tgstation.dme b/tgstation.dme index 3459c8a5bb..3bf5b6a848 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -3081,7 +3081,6 @@ #include "modular_citadel\code\game\objects\items.dm" #include "modular_citadel\code\game\objects\effects\temporary_visuals\souldeath.dm" #include "modular_citadel\code\game\objects\items\stunsword.dm" -#include "modular_citadel\code\game\objects\items\devices\radio\headset.dm" #include "modular_citadel\code\game\objects\items\devices\radio\shockcollar.dm" #include "modular_citadel\code\modules\admin\admin.dm" #include "modular_citadel\code\modules\admin\chat_commands.dm" From e21cb4e67b501f5214dca986e5b58ec4e790e418 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:28:55 -0500 Subject: [PATCH 092/203] shocking --- .../items/devices/radio/electropack.dm | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index b74b0fa3d4..231818be77 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -142,3 +142,87 @@ Code: user << browse(dat, "window=radio") onclose(user, "radio") return + +/obj/item/electropack/shockcollar + name = "shock collar" + desc = "A reinforced metal collar. It seems to have some form of wiring near the front. Strange.." + icon = 'modular_citadel/icons/obj/clothing/cit_neck.dmi' + alternate_worn_icon = 'modular_citadel/icons/mob/citadel/neck.dmi' + icon_state = "shockcollar" + item_state = "shockcollar" + body_parts_covered = NECK + slot_flags = ITEM_SLOT_NECK | ITEM_SLOT_DENYPOCKET //no more pocket shockers + w_class = WEIGHT_CLASS_SMALL + strip_delay = 60 + equip_delay_other = 60 + materials = list(MAT_METAL=5000, MAT_GLASS=2000) + var/tagname = null + +/datum/design/electropack/shockcollar + name = "Shockcollar" + id = "shockcollar" + build_type = AUTOLATHE + build_path = /obj/item/electropack/shockcollar + materials = list(MAT_METAL=5000, MAT_GLASS=2000) + category = list("hacked", "Misc") + +/obj/item/electropack/shockcollar/attack_hand(mob/user) + if(loc == user && user.get_item_by_slot(SLOT_NECK)) + to_chat(user, "The collar is fastened tight! You'll need help taking this off!") + return + ..() + +/obj/item/electropack/shockcollar/receive_signal(datum/signal/signal) + if(!signal || signal.data["code"] != code) + return + + if(isliving(loc) && on) + if(shock_cooldown != 0) + return + shock_cooldown = 1 + spawn(100) + shock_cooldown = 0 + var/mob/living/L = loc + step(L, pick(GLOB.cardinals)) + + to_chat(L, "You feel a sharp shock from the collar!") + var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread + s.set_up(3, 1, L) + s.start() + + L.Knockdown(100) + + if(master) + master.receive_signal() + return + +/obj/item/electropack/shockcollar/attack_self(mob/user) //Turns out can't fully source this from the parent item, spritepath gets confused if power toggled. Will come back to this when I know how to code better and readd powertoggle.. + var/option = "Change Name" + option = input(user, "What do you want to do?", "[src]", option) as null|anything in list("Change Name", "Change Frequency") + switch(option) + if("Change Name") + var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text + if(t) + tagname = copytext(sanitize(t), 1, MAX_NAME_LEN) + name = "[initial(name)] - [tagname]" + if("Change Frequency") + if(!ishuman(user)) + return + user.set_machine(src) + var/dat = {"
    + Frequency/Code for shock collar:
    + Frequency: +
    - + - [format_frequency(frequency)] + + + +
    + Code: + - + - [code] + + + +
    + "} + + user << browse(dat, "window=radio") + onclose(user, "radio") + return From 9f95fb5d9b5477cc6a80a34320717e81f4a36138 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:29:02 -0500 Subject: [PATCH 093/203] cya --- .../items/devices/radio/shockcollar.dm | 83 ------------------- 1 file changed, 83 deletions(-) delete mode 100644 modular_citadel/code/game/objects/items/devices/radio/shockcollar.dm diff --git a/modular_citadel/code/game/objects/items/devices/radio/shockcollar.dm b/modular_citadel/code/game/objects/items/devices/radio/shockcollar.dm deleted file mode 100644 index 9d0757e26e..0000000000 --- a/modular_citadel/code/game/objects/items/devices/radio/shockcollar.dm +++ /dev/null @@ -1,83 +0,0 @@ -/obj/item/electropack/shockcollar - name = "shock collar" - desc = "A reinforced metal collar. It seems to have some form of wiring near the front. Strange.." - icon = 'modular_citadel/icons/obj/clothing/cit_neck.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/neck.dmi' - icon_state = "shockcollar" - item_state = "shockcollar" - body_parts_covered = NECK - slot_flags = ITEM_SLOT_NECK | ITEM_SLOT_DENYPOCKET //no more pocket shockers - w_class = WEIGHT_CLASS_SMALL - strip_delay = 60 - equip_delay_other = 60 - materials = list(MAT_METAL=5000, MAT_GLASS=2000) - var/tagname = null - -/datum/design/electropack/shockcollar - name = "Shockcollar" - id = "shockcollar" - build_type = AUTOLATHE - build_path = /obj/item/electropack/shockcollar - materials = list(MAT_METAL=5000, MAT_GLASS=2000) - category = list("hacked", "Misc") - -/obj/item/electropack/shockcollar/attack_hand(mob/user) - if(loc == user && user.get_item_by_slot(SLOT_NECK)) - to_chat(user, "The collar is fastened tight! You'll need help taking this off!") - return - ..() - -/obj/item/electropack/shockcollar/receive_signal(datum/signal/signal) - if(!signal || signal.data["code"] != code) - return - - if(isliving(loc) && on) - if(shock_cooldown != 0) - return - shock_cooldown = 1 - spawn(100) - shock_cooldown = 0 - var/mob/living/L = loc - step(L, pick(GLOB.cardinals)) - - to_chat(L, "You feel a sharp shock from the collar!") - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(3, 1, L) - s.start() - - L.Knockdown(100) - - if(master) - master.receive_signal() - return - -/obj/item/electropack/shockcollar/attack_self(mob/user) //Turns out can't fully source this from the parent item, spritepath gets confused if power toggled. Will come back to this when I know how to code better and readd powertoggle.. - var/option = "Change Name" - option = input(user, "What do you want to do?", "[src]", option) as null|anything in list("Change Name", "Change Frequency") - switch(option) - if("Change Name") - var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text - if(t) - tagname = copytext(sanitize(t), 1, MAX_NAME_LEN) - name = "[initial(name)] - [tagname]" - if("Change Frequency") - if(!ishuman(user)) - return - user.set_machine(src) - var/dat = {"
    - Frequency/Code for shock collar:
    - Frequency: - - - - [format_frequency(frequency)] - + - +
    - Code: - - - - [code] - + - +
    -
    "} - - user << browse(dat, "window=radio") - onclose(user, "radio") - return From b66d773755b8febc1eb8ebffb3767f452e136cc6 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:29:16 -0500 Subject: [PATCH 094/203] bye --- tgstation.dme | 1 - 1 file changed, 1 deletion(-) diff --git a/tgstation.dme b/tgstation.dme index 3bf5b6a848..9430c579da 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -3081,7 +3081,6 @@ #include "modular_citadel\code\game\objects\items.dm" #include "modular_citadel\code\game\objects\effects\temporary_visuals\souldeath.dm" #include "modular_citadel\code\game\objects\items\stunsword.dm" -#include "modular_citadel\code\game\objects\items\devices\radio\shockcollar.dm" #include "modular_citadel\code\modules\admin\admin.dm" #include "modular_citadel\code\modules\admin\chat_commands.dm" #include "modular_citadel\code\modules\admin\holder2.dm" From f88eefa8a989b29b54ded8b240179dd3733255df Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:30:28 -0500 Subject: [PATCH 095/203] stunsword --- code/game/objects/items/stunbaton.dm | 81 ++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index 6972587263..fd35fa2509 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -223,6 +223,86 @@ if(!iscyborg(loc)) deductcharge(1000 / severity, TRUE, FALSE) +/obj/item/melee/baton/stunsword + name = "stunsword" + desc = "not actually sharp, this sword is functionally identical to a stunbaton" + icon = 'modular_citadel/icons/obj/stunsword.dmi' + icon_state = "stunsword" + item_state = "sword" + lefthand_file = 'modular_citadel/icons/mob/inhands/stunsword_left.dmi' + righthand_file = 'modular_citadel/icons/mob/inhands/stunsword_right.dmi' + +/obj/item/melee/baton/stunsword/get_belt_overlay() + if(istype(loc, /obj/item/storage/belt/sabre)) + return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "stunsword") + return ..() + +/obj/item/melee/baton/stunsword/get_worn_belt_overlay(icon_file) + return mutable_appearance(icon_file, "-stunsword") + +/obj/item/ssword_kit + name = "stunsword kit" + desc = "a modkit for making a stunbaton into a stunsword" + icon = 'icons/obj/vending_restock.dmi' + icon_state = "refill_donksoft" + var/product = /obj/item/melee/baton/stunsword //what it makes + var/list/fromitem = list(/obj/item/melee/baton, /obj/item/melee/baton/loaded) //what it needs + afterattack(obj/O, mob/user as mob) + if(istype(O, product)) + to_chat(user,"[O] is already modified!") + else if(O.type in fromitem) //makes sure O is the right thing + var/obj/item/melee/baton/B = O + if(!B.cell) //checks for a powercell in the baton. If there isn't one, continue. If there is, warn the user to take it out + new product(usr.loc) //spawns the product + user.visible_message("[user] modifies [O]!","You modify the [O]!") + qdel(O) //Gets rid of the baton + qdel(src) //gets rid of the kit + + else + to_chat(user,"Remove the powercell first!") //We make this check because the stunsword starts without a battery. + else + to_chat(user, " You can't modify [O] with this kit!") + +/obj/item/melee/baton/stunsword + name = "stunsword" + desc = "not actually sharp, this sword is functionally identical to a stunbaton" + icon = 'modular_citadel/icons/obj/stunsword.dmi' + icon_state = "stunsword" + item_state = "sword" + lefthand_file = 'modular_citadel/icons/mob/inhands/stunsword_left.dmi' + righthand_file = 'modular_citadel/icons/mob/inhands/stunsword_right.dmi' + +/obj/item/melee/baton/stunsword/get_belt_overlay() + if(istype(loc, /obj/item/storage/belt/sabre)) + return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "stunsword") + return ..() + +/obj/item/melee/baton/stunsword/get_worn_belt_overlay(icon_file) + return mutable_appearance(icon_file, "-stunsword") + +/obj/item/ssword_kit + name = "stunsword kit" + desc = "a modkit for making a stunbaton into a stunsword" + icon = 'icons/obj/vending_restock.dmi' + icon_state = "refill_donksoft" + var/product = /obj/item/melee/baton/stunsword //what it makes + var/list/fromitem = list(/obj/item/melee/baton, /obj/item/melee/baton/loaded) //what it needs + afterattack(obj/O, mob/user as mob) + if(istype(O, product)) + to_chat(user,"[O] is already modified!") + else if(O.type in fromitem) //makes sure O is the right thing + var/obj/item/melee/baton/B = O + if(!B.cell) //checks for a powercell in the baton. If there isn't one, continue. If there is, warn the user to take it out + new product(usr.loc) //spawns the product + user.visible_message("[user] modifies [O]!","You modify the [O]!") + qdel(O) //Gets rid of the baton + qdel(src) //gets rid of the kit + + else + to_chat(user,"Remove the powercell first!") //We make this check because the stunsword starts without a battery. + else + to_chat(user, " You can't modify [O] with this kit!") + //Makeshift stun baton. Replacement for stun gloves. /obj/item/melee/baton/cattleprod name = "stunprod" @@ -249,5 +329,6 @@ sparkler?.activate() . = ..() + #undef STUNBATON_CHARGE_LENIENCY #undef STUNBATON_DEPLETION_RATE From 0dbcf2085b4cf16a94f75b0b21821fe397f7de76 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:30:45 -0500 Subject: [PATCH 096/203] bye --- .../code/game/objects/items/stunsword.dm | 41 ------------------- 1 file changed, 41 deletions(-) delete mode 100644 modular_citadel/code/game/objects/items/stunsword.dm diff --git a/modular_citadel/code/game/objects/items/stunsword.dm b/modular_citadel/code/game/objects/items/stunsword.dm deleted file mode 100644 index 7a5398f7d2..0000000000 --- a/modular_citadel/code/game/objects/items/stunsword.dm +++ /dev/null @@ -1,41 +0,0 @@ -/obj/item/melee/baton/stunsword - name = "stunsword" - desc = "not actually sharp, this sword is functionally identical to a stunbaton" - icon = 'modular_citadel/icons/obj/stunsword.dmi' - icon_state = "stunsword" - item_state = "sword" - lefthand_file = 'modular_citadel/icons/mob/inhands/stunsword_left.dmi' - righthand_file = 'modular_citadel/icons/mob/inhands/stunsword_right.dmi' - -/obj/item/melee/baton/stunsword/get_belt_overlay() - if(istype(loc, /obj/item/storage/belt/sabre)) - return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "stunsword") - return ..() - -/obj/item/melee/baton/stunsword/get_worn_belt_overlay(icon_file) - return mutable_appearance(icon_file, "-stunsword") - -/obj/item/ssword_kit - name = "stunsword kit" - desc = "a modkit for making a stunbaton into a stunsword" - icon = 'icons/obj/vending_restock.dmi' - icon_state = "refill_donksoft" - var/product = /obj/item/melee/baton/stunsword //what it makes - var/list/fromitem = list(/obj/item/melee/baton, /obj/item/melee/baton/loaded) //what it needs - afterattack(obj/O, mob/user as mob) - if(istype(O, product)) - to_chat(user,"[O] is already modified!") - else if(O.type in fromitem) //makes sure O is the right thing - var/obj/item/melee/baton/B = O - if(!B.cell) //checks for a powercell in the baton. If there isn't one, continue. If there is, warn the user to take it out - new product(usr.loc) //spawns the product - user.visible_message("[user] modifies [O]!","You modify the [O]!") - qdel(O) //Gets rid of the baton - qdel(src) //gets rid of the kit - - else - to_chat(user,"Remove the powercell first!") //We make this check because the stunsword starts without a battery. - else - to_chat(user, " You can't modify [O] with this kit!") - - From a03f5b4b268e0316459efcd86324eaba029c10d2 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:30:53 -0500 Subject: [PATCH 097/203] bye --- tgstation.dme | 1 - 1 file changed, 1 deletion(-) diff --git a/tgstation.dme b/tgstation.dme index 9430c579da..cae142f3ee 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -3080,7 +3080,6 @@ #include "modular_citadel\code\game\objects\cit_screenshake.dm" #include "modular_citadel\code\game\objects\items.dm" #include "modular_citadel\code\game\objects\effects\temporary_visuals\souldeath.dm" -#include "modular_citadel\code\game\objects\items\stunsword.dm" #include "modular_citadel\code\modules\admin\admin.dm" #include "modular_citadel\code\modules\admin\chat_commands.dm" #include "modular_citadel\code\modules\admin\holder2.dm" From 799059071f912ff8b419acda89ea1e80b428a96c Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:32:47 -0500 Subject: [PATCH 098/203] this --- code/game/objects/items.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index b50acb33af..813733d6d7 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -10,6 +10,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/item_state = null var/lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' var/righthand_file = 'icons/mob/inhands/items_righthand.dmi' + var/list/alternate_screams = list() //REEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE //Dimensions of the icon file used when this item is worn, eg: hats.dmi //eg: 32x32 sprite, 64x64 sprite, etc. From 93fc0b3716e9624ef1cb9339157b14a430e5f141 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:34:26 -0500 Subject: [PATCH 099/203] xenos helmet --- code/modules/clothing/head/misc.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index 4c6a0fa3b6..ba43e0b9d5 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -178,6 +178,7 @@ icon_state = "xenos" item_state = "xenos_helm" desc = "A helmet made out of chitinous alien hide." + alternate_screams = list('sound/voice/hiss6.ogg') flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT /obj/item/clothing/head/fedora @@ -421,4 +422,4 @@ name = "security cowboy hat" desc = "A security cowboy hat, perfect for any true lawman" icon_state = "cowboyhat_sec" - item_state= "cowboyhat_sec" \ No newline at end of file + item_state= "cowboyhat_sec" From 5857da02a534c3cf38352029fa23b900cbb08e1f Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:35:30 -0500 Subject: [PATCH 100/203] cheeki breeki --- code/modules/clothing/head/misc_special.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index a18d68cc72..466af10dbd 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -86,6 +86,7 @@ desc = "Perfect for winter in Siberia, da?" icon_state = "ushankadown" item_state = "ushankadown" + alternate_screams = list('sound/voice/human/cyka1.ogg', 'sound/voice/human/cheekibreeki.ogg') flags_inv = HIDEEARS|HIDEHAIR var/earflaps = 1 cold_protection = HEAD From 3281db6000d8146c3fbd0469b4ed3f36c22d7611 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:39:13 -0500 Subject: [PATCH 101/203] scream --- code/modules/clothing/head/misc_special.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index 466af10dbd..24a5c5351d 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -165,6 +165,7 @@ icon_state = "cardborg_h" item_state = "cardborg_h" flags_cover = HEADCOVERSEYES + alternate_screams = list('modular_citadel/sound/voice/scream_silicon.ogg') flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT dog_fashion = /datum/dog_fashion/head/cardborg From bfedc80c6498c4f60df57c77cdac471f8f2a1fe2 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:39:45 -0500 Subject: [PATCH 102/203] idk what this even is lmao --- code/game/objects/items/grenades/grenade.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/game/objects/items/grenades/grenade.dm b/code/game/objects/items/grenades/grenade.dm index 98a1aed4c1..80096827e2 100644 --- a/code/game/objects/items/grenades/grenade.dm +++ b/code/game/objects/items/grenades/grenade.dm @@ -122,3 +122,6 @@ owner.visible_message("[attack_text] hits [owner]'s [src], setting it off! What a shot!") prime() return TRUE //It hit the grenade, not them + +/obj/item/proc/grenade_prime_react(obj/item/grenade/nade) + return From ab5223cb20847928f06e722017f9d22bae77061e Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:40:10 -0500 Subject: [PATCH 103/203] this took longer than all the other items combined --- modular_citadel/code/game/objects/items.dm | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 modular_citadel/code/game/objects/items.dm diff --git a/modular_citadel/code/game/objects/items.dm b/modular_citadel/code/game/objects/items.dm deleted file mode 100644 index dba460414e..0000000000 --- a/modular_citadel/code/game/objects/items.dm +++ /dev/null @@ -1,15 +0,0 @@ -/obj/item - var/list/alternate_screams = list() //REEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE - -// lazy for screaming. -/obj/item/clothing/head/xenos - alternate_screams = list('sound/voice/hiss6.ogg') - -/obj/item/clothing/head/cardborg - alternate_screams = list('modular_citadel/sound/voice/scream_silicon.ogg') - -/obj/item/clothing/head/ushanka - alternate_screams = list('sound/voice/human/cyka1.ogg', 'sound/voice/human/cheekibreeki.ogg') - -/obj/item/proc/grenade_prime_react(obj/item/grenade/nade) - return \ No newline at end of file From 0a3daa211cd8bcae5dbeff52309581d226906beb Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:40:25 -0500 Subject: [PATCH 104/203] items begone --- tgstation.dme | 1 - 1 file changed, 1 deletion(-) diff --git a/tgstation.dme b/tgstation.dme index cae142f3ee..65f613fe0e 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -3078,7 +3078,6 @@ #include "modular_citadel\code\datums\status_effects\debuffs.dm" #include "modular_citadel\code\game\machinery\wishgranter.dm" #include "modular_citadel\code\game\objects\cit_screenshake.dm" -#include "modular_citadel\code\game\objects\items.dm" #include "modular_citadel\code\game\objects\effects\temporary_visuals\souldeath.dm" #include "modular_citadel\code\modules\admin\admin.dm" #include "modular_citadel\code\modules\admin\chat_commands.dm" From b6a187dc6d68e96baf95e8e85d811670ac477e6d Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Fri, 10 Jan 2020 22:48:33 -0500 Subject: [PATCH 105/203] OOPS --- code/game/objects/items/stunbaton.dm | 40 ---------------------------- 1 file changed, 40 deletions(-) diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index fd35fa2509..b1133cb03d 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -263,46 +263,6 @@ else to_chat(user, " You can't modify [O] with this kit!") -/obj/item/melee/baton/stunsword - name = "stunsword" - desc = "not actually sharp, this sword is functionally identical to a stunbaton" - icon = 'modular_citadel/icons/obj/stunsword.dmi' - icon_state = "stunsword" - item_state = "sword" - lefthand_file = 'modular_citadel/icons/mob/inhands/stunsword_left.dmi' - righthand_file = 'modular_citadel/icons/mob/inhands/stunsword_right.dmi' - -/obj/item/melee/baton/stunsword/get_belt_overlay() - if(istype(loc, /obj/item/storage/belt/sabre)) - return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "stunsword") - return ..() - -/obj/item/melee/baton/stunsword/get_worn_belt_overlay(icon_file) - return mutable_appearance(icon_file, "-stunsword") - -/obj/item/ssword_kit - name = "stunsword kit" - desc = "a modkit for making a stunbaton into a stunsword" - icon = 'icons/obj/vending_restock.dmi' - icon_state = "refill_donksoft" - var/product = /obj/item/melee/baton/stunsword //what it makes - var/list/fromitem = list(/obj/item/melee/baton, /obj/item/melee/baton/loaded) //what it needs - afterattack(obj/O, mob/user as mob) - if(istype(O, product)) - to_chat(user,"[O] is already modified!") - else if(O.type in fromitem) //makes sure O is the right thing - var/obj/item/melee/baton/B = O - if(!B.cell) //checks for a powercell in the baton. If there isn't one, continue. If there is, warn the user to take it out - new product(usr.loc) //spawns the product - user.visible_message("[user] modifies [O]!","You modify the [O]!") - qdel(O) //Gets rid of the baton - qdel(src) //gets rid of the kit - - else - to_chat(user,"Remove the powercell first!") //We make this check because the stunsword starts without a battery. - else - to_chat(user, " You can't modify [O] with this kit!") - //Makeshift stun baton. Replacement for stun gloves. /obj/item/melee/baton/cattleprod name = "stunprod" From c6507d47e2c797578a98d6fab1dd2fcdc037afba Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 10 Jan 2020 20:06:35 -0800 Subject: [PATCH 106/203] bad patches, ugh --- code/controllers/subsystem/vote.dm | 38 ++++++++++++++++++------------ 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 9603edacef..e0ec031183 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -102,17 +102,18 @@ SUBSYSTEM_DEF(vote) var/list/d[][] = new/list(choices.len,choices.len) // the basic vote matrix, how many times a beats b for(var/ckey in voted) var/list/this_vote = voted[ckey] - for(var/a in 1 to choices.len) - for(var/b in a+1 to choices.len) - var/a_rank = this_vote.Find(a) - var/b_rank = this_vote.Find(b) - a_rank = a_rank ? a_rank : choices.len+1 - b_rank = b_rank ? b_rank : choices.len+1 - if(a_rank Date: Sat, 11 Jan 2020 17:57:18 +1300 Subject: [PATCH 107/203] Couple of lingering fixes --- _maps/map_files/BoxStation/BoxStation.dmm | 11 +- .../map_files/Deltastation/DeltaStation2.dmm | 1691 ++++------- _maps/map_files/MetaStation/MetaStation.dmm | 2641 ++++------------- _maps/map_files/PubbyStation/PubbyStation.dmm | 674 ++--- code/game/objects/items/robot/robot_items.dm | 8 +- .../mob/living/silicon/robot/robot_modules.dm | 7 +- modular_citadel/icons/mob/widerobot.dmi | Bin 664161 -> 695890 bytes 7 files changed, 1346 insertions(+), 3686 deletions(-) diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index b6463f7147..cfe7dd4335 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -49296,6 +49296,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/grimy, /area/ai_monitored/turret_protected/aisat_interior) "ctv" = ( @@ -49321,6 +49322,7 @@ /area/ai_monitored/turret_protected/aisat_interior) "ctx" = ( /obj/machinery/atmospherics/pipe/manifold4w/scrubbers, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/grimy, /area/ai_monitored/turret_protected/aisat_interior) "cty" = ( @@ -49328,6 +49330,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/grimy, /area/ai_monitored/turret_protected/aisat_interior) "ctz" = ( @@ -49381,6 +49384,7 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/grimy, /area/ai_monitored/turret_protected/aisat_interior) "ctH" = ( @@ -49405,6 +49409,7 @@ /area/ai_monitored/turret_protected/aisat_interior) "ctI" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/grimy, /area/ai_monitored/turret_protected/aisat_interior) "ctJ" = ( @@ -49448,6 +49453,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/grimy, /area/ai_monitored/turret_protected/aisat_interior) "ctQ" = ( @@ -49483,6 +49489,7 @@ /obj/structure/cable{ icon_state = "4-8" }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/grimy, /area/ai_monitored/turret_protected/aisat_interior) "ctT" = ( @@ -49493,6 +49500,7 @@ /obj/structure/cable{ icon_state = "1-2" }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/grimy, /area/ai_monitored/turret_protected/aisat_interior) "ctU" = ( @@ -57196,8 +57204,7 @@ dir = 5 }, /obj/machinery/camera{ - c_tag = "Bar Backroom"; - dir = 2 + c_tag = "Bar Backroom" }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index c59e0698f9..eb3140f281 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -197,7 +197,6 @@ /area/hallway/secondary/entry) "abs" = ( /obj/docking_port/stationary{ - dir = 1; dwidth = 1; height = 4; name = "escape pod loader"; @@ -256,9 +255,7 @@ name = "External Airlock"; req_access_txt = "13" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -269,9 +266,7 @@ /obj/machinery/door/airlock/external{ name = "Escape Pod 1" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -282,9 +277,7 @@ /obj/machinery/door/airlock/external{ name = "Escape Pod 2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -314,9 +307,7 @@ /area/construction/mining/aux_base) "abZ" = ( /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -360,9 +351,7 @@ name = "WARNING: EXTERNAL AIRLOCK"; pixel_x = 32 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -469,8 +458,8 @@ height = 17; id = "arrivals_stationary"; name = "delta arrivals"; - width = 9; - roundstart_template = /datum/map_template/shuttle/arrival/delta + roundstart_template = /datum/map_template/shuttle/arrival/delta; + width = 9 }, /turf/open/space/basic, /area/space) @@ -777,9 +766,8 @@ "adh" = ( /obj/structure/cable/white, /obj/machinery/power/apc/highcap/ten_k{ - dir = 2; - name = "Starboard Bow Solar APC"; areastring = "/area/maintenance/solars/starboard/fore"; + name = "Starboard Bow Solar APC"; pixel_y = -26 }, /obj/effect/turf_decal/stripes/line{ @@ -802,8 +790,7 @@ /obj/machinery/power/solar_control{ dir = 8; id = "forestarboard"; - name = "Starboard Bow Solar Control"; - track = 0 + name = "Starboard Bow Solar Control" }, /obj/structure/cable, /obj/effect/turf_decal/stripes/line{ @@ -977,9 +964,7 @@ name = "Auxiliary Construction Storage"; req_one_access_txt = "10;32;47;48" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -1394,9 +1379,9 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ + areastring = "/area/construction/mining/aux_base"; dir = 8; name = "Auxiliary Construction APC"; - areastring = "/area/construction/mining/aux_base"; pixel_x = -26; pixel_y = 3 }, @@ -1837,9 +1822,7 @@ name = "Maintenance Hatch"; req_one_access_txt = "32;47;48" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -1847,7 +1830,6 @@ /area/maintenance/starboard/fore) "aid" = ( /obj/docking_port/stationary{ - dir = 1; dwidth = 2; height = 13; id = "ferry_home"; @@ -2263,9 +2245,7 @@ "ajd" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -2274,9 +2254,7 @@ "aje" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -2301,9 +2279,7 @@ /obj/machinery/door/firedoor, /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -2317,9 +2293,7 @@ /obj/machinery/door/firedoor, /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -2547,9 +2521,9 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ + areastring = "/area/hallway/secondary/entry"; dir = 1; name = "Arrivals Hallway APC"; - areastring = "/area/hallway/secondary/entry"; pixel_y = 24 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -2557,7 +2531,6 @@ }, /obj/machinery/camera{ c_tag = "Arrivals - Center Port"; - dir = 2; name = "arrivals camera" }, /obj/effect/turf_decal/tile/blue{ @@ -3049,9 +3022,7 @@ /obj/machinery/door/airlock{ name = "Auxiliary Storage Closet" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -3074,9 +3045,7 @@ req_access_txt = "32" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -3097,9 +3066,7 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -3840,9 +3807,9 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ + areastring = "/area/security/checkpoint/customs"; dir = 8; name = "Customs Desk APC"; - areastring = "/area/security/checkpoint/customs"; pixel_x = -26 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ @@ -3916,7 +3883,6 @@ /obj/item/flashlight/lamp, /obj/machinery/camera{ c_tag = "Arrivals - Center"; - dir = 2; name = "arrivals camera" }, /turf/open/floor/plasteel/grimy, @@ -4532,7 +4498,6 @@ "anz" = ( /obj/effect/decal/cleanable/cobweb, /obj/machinery/computer/arcade{ - icon_state = "arcade"; dir = 4 }, /turf/open/floor/plating, @@ -4542,9 +4507,9 @@ icon_state = "0-2" }, /obj/machinery/power/apc{ + areastring = "/area/maintenance/starboard/fore"; dir = 1; name = "Starboard Bow Maintenance APC"; - areastring = "/area/maintenance/starboard/fore"; pixel_y = 24 }, /obj/effect/decal/cleanable/dirt, @@ -5731,9 +5696,7 @@ /obj/structure/sign/warning/vacuum{ pixel_y = 32 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -5747,9 +5710,7 @@ /obj/structure/disposalpipe/segment{ dir = 10 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -5763,9 +5724,7 @@ /obj/machinery/light/small{ dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -6026,9 +5985,8 @@ /area/security/vacantoffice) "aqg" = ( /obj/machinery/power/apc{ - dir = 2; - name = "Auxiliary Office APC"; areastring = "/area/security/vacantoffice"; + name = "Auxiliary Office APC"; pixel_y = -26 }, /obj/effect/decal/cleanable/dirt, @@ -6515,9 +6473,8 @@ /obj/item/twohanded/required/kirbyplants/random, /obj/structure/cable/white, /obj/machinery/power/apc{ - dir = 2; - name = "Electronics Marketing APC"; areastring = "/area/crew_quarters/electronic_marketing_den"; + name = "Electronics Marketing APC"; pixel_y = -26 }, /turf/open/floor/wood, @@ -6545,9 +6502,7 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -6575,9 +6530,7 @@ req_access_txt = "19" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -6593,9 +6546,7 @@ req_access_txt = "63" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -6691,7 +6642,6 @@ /area/maintenance/disposal) "ari" = ( /obj/machinery/mineral/stacking_unit_console{ - dir = 2; machinedir = 8; pixel_x = 32 }, @@ -6732,9 +6682,7 @@ req_one_access_txt = "24;10" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -6756,9 +6704,7 @@ name = "Reflector Access"; req_one_access_txt = "24;10" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -6821,9 +6767,7 @@ icon_state = "1-2" }, /obj/structure/barricade/wooden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -6837,9 +6781,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/barricade/wooden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -7010,7 +6952,6 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/camera{ c_tag = "Arrivals - Aft"; - dir = 2; name = "arrivals camera" }, /obj/effect/turf_decal/bot, @@ -7093,7 +7034,6 @@ /area/maintenance/starboard/fore) "arX" = ( /obj/machinery/computer/arcade{ - icon_state = "arcade"; dir = 1 }, /turf/open/floor/plating, @@ -7131,7 +7071,6 @@ "asa" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/computer/arcade{ - icon_state = "arcade"; dir = 1 }, /turf/open/floor/plating, @@ -7209,7 +7148,6 @@ "ash" = ( /obj/machinery/door/window/eastright{ base_state = "left"; - dir = 4; icon_state = "left"; name = "Danger: Conveyor Access"; req_access_txt = "12" @@ -8017,9 +7955,7 @@ req_access_txt = "12" }, /obj/structure/barricade/wooden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -8127,7 +8063,6 @@ /area/maintenance/disposal) "atF" = ( /obj/machinery/door/window/eastright{ - dir = 4; name = "Danger: Conveyor Access"; req_access_txt = "12" }, @@ -8466,9 +8401,7 @@ }, /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -8484,9 +8417,7 @@ req_access_txt = "12" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -8916,9 +8847,8 @@ /area/maintenance/disposal) "auO" = ( /obj/machinery/power/apc{ - dir = 2; - name = "Disposal APC"; areastring = "/area/maintenance/disposal"; + name = "Disposal APC"; pixel_y = -24 }, /obj/structure/disposalpipe/segment{ @@ -9308,9 +9238,9 @@ /area/janitor) "avB" = ( /obj/machinery/power/apc{ + areastring = "/area/janitor"; dir = 1; name = "Custodial Closet APC"; - areastring = "/area/janitor"; pixel_y = 24 }, /obj/structure/cable/white{ @@ -9341,7 +9271,6 @@ }, /obj/machinery/camera{ c_tag = "Custodial Closet"; - dir = 2; name = "service camera" }, /obj/effect/turf_decal/bot, @@ -9447,9 +9376,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -9459,11 +9386,8 @@ /obj/structure/sign/directions/evac{ pixel_y = -8 }, -/obj/structure/sign/directions/science{ - dir = 2 - }, +/obj/structure/sign/directions/science, /obj/structure/sign/directions/engineering{ - dir = 2; pixel_y = 8 }, /turf/closed/wall, @@ -9475,9 +9399,7 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -9488,9 +9410,7 @@ /obj/machinery/door/airlock/public/glass{ name = "Fore Primary Hallway" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -9502,9 +9422,7 @@ /obj/machinery/door/airlock/public/glass{ name = "Fore Primary Hallway" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -9514,11 +9432,8 @@ /obj/structure/sign/directions/evac{ pixel_y = -8 }, -/obj/structure/sign/directions/medical{ - dir = 2 - }, +/obj/structure/sign/directions/medical, /obj/structure/sign/directions/security{ - dir = 2; pixel_y = 8 }, /turf/closed/wall, @@ -9536,9 +9451,7 @@ req_access_txt = "31" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -9579,9 +9492,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -9982,7 +9893,6 @@ /obj/item/twohanded/required/kirbyplants/random, /obj/machinery/camera{ c_tag = "Auxiliary Restroom"; - dir = 2; name = "restroom camera" }, /obj/effect/turf_decal/tile/neutral{ @@ -10112,7 +10022,6 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/camera{ c_tag = "Cargo - Warehouse"; - dir = 2; name = "cargo camera" }, /turf/open/floor/plating, @@ -10388,7 +10297,6 @@ }, /obj/machinery/camera{ c_tag = "Supermatter Chamber"; - dir = 2; network = list("engine") }, /turf/open/floor/engine, @@ -10712,9 +10620,8 @@ }, /obj/effect/decal/cleanable/dirt, /obj/machinery/power/apc{ - dir = 2; - name = "Auxiliary Restrooms APC"; areastring = "/area/crew_quarters/toilet/auxiliary"; + name = "Auxiliary Restrooms APC"; pixel_y = -26 }, /turf/open/floor/plating, @@ -11164,9 +11071,8 @@ "ayU" = ( /obj/machinery/light/small, /obj/machinery/power/apc{ - dir = 2; - name = "Port Bow Maintenance APC"; areastring = "/area/maintenance/port/fore"; + name = "Port Bow Maintenance APC"; pixel_y = -26 }, /obj/structure/cable/white, @@ -11359,9 +11265,7 @@ /obj/machinery/door/airlock{ name = "Toilet Unit" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -11850,9 +11754,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -11863,9 +11765,7 @@ id = "custodialshutters"; name = "Custodial Closet Shutters" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -11883,9 +11783,7 @@ req_access_txt = "26" }, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -13419,9 +13317,9 @@ icon_state = "0-8" }, /obj/machinery/power/apc{ + areastring = "/area/quartermaster/warehouse"; dir = 4; name = "Cargo Warehouse APC"; - areastring = "/area/quartermaster/warehouse"; pixel_x = 26 }, /obj/effect/turf_decal/tile/brown, @@ -13551,9 +13449,7 @@ /turf/open/floor/plasteel, /area/quartermaster/storage) "aDg" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -13795,9 +13691,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -13986,7 +13880,6 @@ /area/quartermaster/storage) "aEg" = ( /obj/machinery/button/door{ - dir = 2; id = "cargounload"; layer = 4; name = "Loading Doors"; @@ -14219,9 +14112,9 @@ /area/engine/atmospherics_engine) "aEz" = ( /obj/machinery/power/apc{ + areastring = "/area/engine/atmospherics_engine"; dir = 4; name = "Atmospherics Engine APC"; - areastring = "/area/engine/atmospherics_engine"; pixel_x = 26 }, /obj/structure/cable/white{ @@ -14365,9 +14258,9 @@ "aEP" = ( /obj/structure/closet/secure_closet/bar, /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/bar"; dir = 1; name = "Bar APC"; - areastring = "/area/crew_quarters/bar"; pixel_y = 24 }, /obj/machinery/light/small{ @@ -14397,7 +14290,6 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on, /obj/machinery/camera{ c_tag = "Bar Backroom"; - dir = 2; name = "service camera" }, /turf/open/floor/plasteel/dark, @@ -14549,9 +14441,9 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ + areastring = "/area/hallway/primary/fore"; dir = 8; name = "Port Primary Hallway APC"; - areastring = "/area/hallway/primary/fore"; pixel_x = -26; pixel_y = 3 }, @@ -14609,9 +14501,7 @@ req_access_txt = "31" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -14929,7 +14819,6 @@ /obj/structure/cable/white, /obj/machinery/power/apc{ areastring = "/area/hydroponics/garden/abandoned"; - dir = 2; name = "Maintenance Garden APC"; pixel_y = -26 }, @@ -15585,7 +15474,6 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/camera{ c_tag = "Prison - Garden"; - dir = 2; name = "prison camera"; network = list("ss13","prison") }, @@ -16000,9 +15888,7 @@ req_access_txt = "12" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -16018,9 +15904,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -16259,7 +16143,6 @@ "aHK" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/conveyor{ - dir = 2; id = "cargodisposals" }, /turf/open/floor/plating, @@ -16719,9 +16602,9 @@ dir = 1 }, /obj/machinery/power/apc{ + areastring = "/area/maintenance/disposal/incinerator"; dir = 1; name = "Turbine Generator APC"; - areastring = "/area/maintenance/disposal/incinerator"; pixel_y = 24 }, /obj/structure/cable/white{ @@ -16754,9 +16637,7 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/door/airlock/atmos{ name = "Atmospherics Access"; req_one_access_txt = "24;10" @@ -16778,9 +16659,7 @@ icon_state = "1-2" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/door/airlock/atmos{ name = "Atmospherics Engine Access"; req_one_access_txt = "24;10" @@ -16823,9 +16702,7 @@ req_one_access_txt = "24;10" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -17179,7 +17056,6 @@ "aJk" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/conveyor{ - dir = 2; id = "cargodisposals" }, /obj/effect/spawner/lootdrop/maintenance, @@ -17361,8 +17237,7 @@ /obj/machinery/power/solar_control{ dir = 4; id = "foreport"; - name = "Port Bow Solar Control"; - track = 0 + name = "Port Bow Solar Control" }, /obj/structure/cable, /obj/effect/turf_decal/stripes/line{ @@ -17384,9 +17259,8 @@ "aJG" = ( /obj/structure/cable/white, /obj/machinery/power/apc/highcap/ten_k{ - dir = 2; - name = "Port Bow Solar APC"; areastring = "/area/maintenance/solars/port/fore"; + name = "Port Bow Solar APC"; pixel_y = -26 }, /obj/effect/turf_decal/stripes/line{ @@ -18262,9 +18136,7 @@ id = "justiceblast"; name = "Justice Blast door" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -18765,9 +18637,9 @@ pixel_y = -32 }, /obj/machinery/power/apc{ + areastring = "/area/security/checkpoint/supply"; dir = 8; name = "Security Post - Cargo APC"; - areastring = "/area/security/checkpoint/supply"; pixel_x = -26 }, /obj/effect/turf_decal/tile/red{ @@ -19139,9 +19011,7 @@ name = "Turbine Generator Access"; req_access_txt = "24" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -19162,9 +19032,7 @@ "aMH" = ( /obj/machinery/door/firedoor, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/door/airlock/atmos{ name = "Atmospherics Access"; req_one_access_txt = "24;10" @@ -19187,9 +19055,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/door/airlock/atmos{ name = "Atmospherics Engine Access"; req_one_access_txt = "24;10" @@ -19357,14 +19223,13 @@ dir = 1 }, /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/bar/atrium"; dir = 1; name = "Atrium APC"; - areastring = "/area/crew_quarters/bar/atrium"; pixel_y = 24 }, /obj/machinery/camera{ c_tag = "Theatre Stage"; - dir = 2; name = "service camera" }, /turf/open/floor/plasteel/grimy, @@ -19495,7 +19360,6 @@ "aNp" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/conveyor{ - dir = 2; id = "cargodisposals" }, /obj/structure/plasticflaps, @@ -19823,10 +19687,9 @@ /area/maintenance/disposal/incinerator) "aNQ" = ( /obj/machinery/power/compressor{ - icon_state = "compressor"; + comp_id = "incineratorturbine"; dir = 4; - luminosity = 2; - comp_id = "incineratorturbine" + luminosity = 2 }, /obj/structure/cable{ icon_state = "0-4" @@ -19865,9 +19728,7 @@ icon_state = "4-8" }, /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_atmos{ - dir = 2 - }, +/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_atmos, /turf/open/floor/engine, /area/maintenance/disposal/incinerator) "aNU" = ( @@ -20262,9 +20123,9 @@ dir = 1 }, /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/theatre"; dir = 1; name = "Theatre Backstage APC"; - areastring = "/area/crew_quarters/theatre"; pixel_y = 24 }, /obj/effect/turf_decal/tile/red{ @@ -20469,9 +20330,9 @@ /obj/item/stack/packageWrap, /obj/item/hand_labeler, /obj/machinery/power/apc{ + areastring = "/area/quartermaster/sorting"; dir = 8; name = "Delivery Office APC"; - areastring = "/area/quartermaster/sorting"; pixel_x = -26; pixel_y = 3 }, @@ -21928,7 +21789,6 @@ /obj/machinery/holopad, /obj/item/radio/intercom{ desc = "Talk through this. It looks like it has been modified to not broadcast."; - dir = 2; name = "Prison Intercom"; pixel_y = -28; prison_radio = 1 @@ -21951,7 +21811,6 @@ /area/security/prison) "aRi" = ( /obj/machinery/computer/arcade{ - icon_state = "arcade"; dir = 1 }, /turf/open/floor/plating, @@ -22531,9 +22390,7 @@ req_one_access_txt = "48;50" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -22585,9 +22442,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -22608,9 +22463,9 @@ icon_state = "0-2" }, /obj/machinery/power/apc{ + areastring = "/area/quartermaster/storage"; dir = 8; name = "Cargo Bay APC"; - areastring = "/area/quartermaster/storage"; pixel_x = -26; pixel_y = 3 }, @@ -22760,9 +22615,9 @@ icon_state = "0-2" }, /obj/machinery/power/apc{ + areastring = "/area/quartermaster/qm"; dir = 1; name = "Quartermaster's Office APC"; - areastring = "/area/quartermaster/qm"; pixel_y = 28 }, /obj/machinery/atmospherics/components/unary/vent_pump/on, @@ -22887,9 +22742,7 @@ name = "Cell 3" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -22908,9 +22761,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -22927,9 +22778,7 @@ name = "Cell 1" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -23809,7 +23658,6 @@ }, /obj/machinery/camera{ c_tag = "Cargo - Office"; - dir = 2; name = "cargo camera" }, /obj/effect/turf_decal/tile/brown{ @@ -23824,9 +23672,9 @@ /obj/structure/table, /obj/item/paper_bin, /obj/machinery/power/apc{ + areastring = "/area/quartermaster/office"; dir = 1; name = "Cargo Office APC"; - areastring = "/area/quartermaster/office"; pixel_y = 28 }, /obj/structure/cable/white{ @@ -24263,7 +24111,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on, /obj/machinery/camera{ c_tag = "Prison - Cell 3"; - dir = 2; name = "prison camera"; network = list("ss13","prison") }, @@ -24310,7 +24157,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on, /obj/machinery/camera{ c_tag = "Prison - Cell 2"; - dir = 2; name = "prison camera"; network = list("ss13","prison") }, @@ -24343,7 +24189,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on, /obj/machinery/camera{ c_tag = "Prison - Cell 1"; - dir = 2; name = "prison camera"; network = list("ss13","prison") }, @@ -24491,9 +24336,7 @@ name = "Security External Airlock"; req_access_txt = "63" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -25704,9 +25547,8 @@ "aWp" = ( /obj/structure/cable/white, /obj/machinery/power/apc{ - dir = 2; - name = "Education Chamber APC"; areastring = "/area/security/execution/education"; + name = "Education Chamber APC"; pixel_y = -26 }, /obj/machinery/atmospherics/pipe/simple/general/hidden{ @@ -25929,9 +25771,7 @@ }, /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -26045,9 +25885,9 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ + areastring = "/area/hallway/secondary/service"; dir = 8; name = "Service Hall APC"; - areastring = "/area/hallway/secondary/service"; pixel_x = -26; pixel_y = 3 }, @@ -26764,9 +26604,7 @@ name = "WARNING: EXTERNAL AIRLOCK"; pixel_x = 32 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -27678,8 +27516,7 @@ /area/security/prison) "aZm" = ( /obj/machinery/camera{ - c_tag = "Security - Prison Port"; - dir = 2 + c_tag = "Security - Prison Port" }, /obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, @@ -27756,9 +27593,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aZt" = ( @@ -27785,8 +27620,7 @@ }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/machinery/camera{ - c_tag = "Security - Prison"; - dir = 2 + c_tag = "Security - Prison" }, /obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, @@ -27827,9 +27661,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aZx" = ( @@ -27888,9 +27720,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aZB" = ( @@ -28027,8 +27857,7 @@ "aZK" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/camera{ - c_tag = "Security - Escape Pod"; - dir = 2 + c_tag = "Security - Escape Pod" }, /obj/effect/turf_decal/tile/red{ dir = 1 @@ -28049,8 +27878,8 @@ dir = 4 }, /turf/open/floor/plating{ - luminosity = 2; initial_gas_mix = "o2=0.01;n2=0.01"; + luminosity = 2; temperature = 2.7 }, /area/security/prison) @@ -28372,9 +28201,7 @@ req_access_txt = "35" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -28401,9 +28228,7 @@ dir = 4 }, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/hallway/secondary/service) "bax" = ( @@ -28412,9 +28237,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/hallway/secondary/service) "bay" = ( @@ -28445,7 +28268,6 @@ }, /obj/machinery/camera{ c_tag = "Kitchen Cold Room"; - dir = 2; name = "service camera" }, /obj/effect/turf_decal/stripes/line{ @@ -28650,9 +28472,7 @@ req_access_txt = "48" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -28680,9 +28500,7 @@ req_access_txt = "48" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -28827,9 +28645,8 @@ "bbk" = ( /obj/structure/cable/white, /obj/machinery/power/apc/highcap/five_k{ - dir = 2; - name = "Prison Wing APC"; areastring = "/area/security/prison"; + name = "Prison Wing APC"; pixel_x = 1; pixel_y = -24 }, @@ -29380,9 +29197,7 @@ "bcm" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -29394,9 +29209,7 @@ }, /obj/structure/disposalpipe/segment, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -29405,9 +29218,7 @@ "bco" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -29426,9 +29237,7 @@ req_one_access_txt = "48;50" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -29631,9 +29440,7 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -29652,9 +29459,7 @@ req_access_txt = "1" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -29819,8 +29624,8 @@ dir = 4 }, /turf/open/floor/plating{ - luminosity = 2; initial_gas_mix = "o2=0.01;n2=0.01"; + luminosity = 2; temperature = 2.7 }, /area/security/prison) @@ -30400,7 +30205,6 @@ "bdS" = ( /obj/machinery/camera{ c_tag = "Cargo - Waiting Room"; - dir = 2; name = "cargo camera" }, /obj/effect/turf_decal/loading_area{ @@ -31002,9 +30806,8 @@ "bfb" = ( /obj/structure/cable/white, /obj/machinery/power/apc{ - dir = 2; - name = "Kitchen APC"; areastring = "/area/crew_quarters/kitchen"; + name = "Kitchen APC"; pixel_y = -26 }, /obj/effect/turf_decal/bot, @@ -31597,9 +31400,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -31717,9 +31518,7 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -31734,9 +31533,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -31757,9 +31554,7 @@ req_access_txt = "28" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -32059,18 +31854,14 @@ /area/quartermaster/miningoffice) "bgR" = ( /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, /turf/open/floor/plasteel, /area/quartermaster/miningoffice) "bgS" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -32103,8 +31894,8 @@ height = 5; id = "mining_home"; name = "mining shuttle bay"; - width = 7; - roundstart_template = /datum/map_template/shuttle/mining/delta + roundstart_template = /datum/map_template/shuttle/mining/delta; + width = 7 }, /turf/open/space/basic, /area/space) @@ -32121,9 +31912,7 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -32151,9 +31940,7 @@ req_access_txt = "1" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -32237,9 +32024,9 @@ /area/engine/atmos) "bhj" = ( /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/engine/atmos"; dir = 1; name = "Atmospherics APC"; - areastring = "/area/engine/atmos"; pixel_y = 24 }, /obj/structure/cable/white{ @@ -33065,8 +32852,7 @@ dir = 4 }, /obj/machinery/camera{ - c_tag = "Security - Medbay"; - dir = 2 + c_tag = "Security - Medbay" }, /obj/effect/turf_decal/tile/red{ dir = 1 @@ -33188,8 +32974,7 @@ pixel_y = 32 }, /obj/machinery/camera{ - c_tag = "Security - Office Fore"; - dir = 2 + c_tag = "Security - Office Fore" }, /obj/effect/turf_decal/tile/red{ dir = 1 @@ -34413,8 +34198,7 @@ pixel_y = 32 }, /obj/machinery/camera{ - c_tag = "Security - Head of Security's Office"; - dir = 2 + c_tag = "Security - Head of Security's Office" }, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -34866,7 +34650,6 @@ dir = 4 }, /obj/machinery/door/window/eastleft{ - dir = 4; name = "Kitchen Desk"; req_access_txt = "28" }, @@ -35187,9 +34970,9 @@ /obj/item/storage/firstaid/regular, /obj/machinery/light, /obj/machinery/power/apc{ + areastring = "/area/quartermaster/miningoffice"; dir = 4; name = "Mining Dock APC"; - areastring = "/area/quartermaster/miningoffice"; pixel_x = 26 }, /obj/machinery/camera{ @@ -35582,8 +35365,7 @@ pixel_y = 32 }, /obj/machinery/camera{ - c_tag = "Security - Head of Security's Quarters"; - dir = 2 + c_tag = "Security - Head of Security's Quarters" }, /turf/open/floor/plasteel/grimy, /area/crew_quarters/heads/hos) @@ -36013,9 +35795,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -36054,9 +35834,7 @@ /obj/machinery/door/airlock/public/glass{ name = "Fore Primary Hallway" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -36071,9 +35849,7 @@ icon_state = "1-2" }, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -36094,9 +35870,7 @@ /area/hallway/primary/fore) "bnv" = ( /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -36105,9 +35879,7 @@ "bnw" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -36120,9 +35892,7 @@ "bny" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -36160,9 +35930,7 @@ name = "Mining Dock"; req_access_txt = "48" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -36265,9 +36033,9 @@ /area/security/main) "bnL" = ( /obj/machinery/power/apc{ + areastring = "/area/security/main"; dir = 8; name = "Security Office APC"; - areastring = "/area/security/main"; pixel_x = -26 }, /obj/structure/cable/white{ @@ -36623,9 +36391,7 @@ name = "Distribution Loop"; req_access_txt = "24" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -36664,9 +36430,7 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bor" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -36684,16 +36448,12 @@ /obj/item/clipboard, /obj/effect/decal/cleanable/dirt, /obj/item/toy/figure/atmos, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/engine/atmos) "bot" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/turf_decal/stripes/line{ dir = 8 }, @@ -36832,7 +36592,6 @@ }, /obj/machinery/camera{ c_tag = "Central Hallway - Fore Port"; - dir = 2; name = "hallway camera" }, /obj/effect/turf_decal/tile/neutral{ @@ -36929,7 +36688,6 @@ }, /obj/machinery/camera{ c_tag = "Central Hallway - Fore Starboard"; - dir = 2; name = "hallway camera" }, /obj/effect/turf_decal/tile/neutral{ @@ -36977,9 +36735,9 @@ dir = 4 }, /obj/machinery/power/apc{ + areastring = "/area/hallway/primary/central"; dir = 1; name = "Central Primary Hallway APC"; - areastring = "/area/hallway/primary/central"; pixel_y = 24 }, /obj/structure/cable/white{ @@ -37132,8 +36890,7 @@ pixel_y = 32 }, /obj/machinery/camera{ - c_tag = "Security - Transfer Centre"; - dir = 2 + c_tag = "Security - Transfer Centre" }, /obj/effect/turf_decal/tile/red{ dir = 1 @@ -37647,7 +37404,6 @@ /area/engine/atmos) "bpT" = ( /obj/machinery/atmospherics/components/binary/pump{ - dir = 2; name = "Pure to Mix" }, /obj/effect/decal/cleanable/dirt, @@ -37726,9 +37482,7 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bqa" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/landmark/start/atmospheric_technician, /obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 4 @@ -37750,9 +37504,7 @@ /obj/item/clothing/head/welding, /obj/structure/table/reinforced, /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/turf_decal/bot, /obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 4 @@ -37760,9 +37512,7 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bqc" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/turf_decal/stripes/line{ dir = 8 }, @@ -39063,9 +38813,7 @@ /obj/structure/table/reinforced, /obj/item/storage/belt/utility, /obj/item/t_scanner, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/engine/atmos) @@ -40253,9 +40001,7 @@ /area/engine/atmos) "btU" = ( /obj/effect/decal/cleanable/dirt, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -40269,9 +40015,7 @@ /turf/open/floor/plasteel, /area/engine/atmos) "btV" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/engine/atmos) @@ -40428,9 +40172,9 @@ /area/hallway/primary/port) "bui" = ( /obj/machinery/power/apc{ + areastring = "/area/hallway/primary/port"; dir = 4; name = "Port Primary Hallway APC"; - areastring = "/area/hallway/primary/port"; pixel_x = 26 }, /obj/structure/cable/white{ @@ -40475,9 +40219,7 @@ "bun" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -40489,9 +40231,7 @@ icon_state = "1-2" }, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -40501,9 +40241,7 @@ /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -40522,9 +40260,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -40550,9 +40286,7 @@ /turf/open/floor/plasteel, /area/security/execution/transfer) "buA" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -40782,9 +40516,8 @@ "buT" = ( /obj/item/twohanded/required/kirbyplants/random, /obj/machinery/power/apc{ - dir = 2; - name = "Head of Security's Office APC"; areastring = "/area/crew_quarters/heads/hos"; + name = "Head of Security's Office APC"; pixel_y = -26 }, /obj/structure/cable/white, @@ -40905,7 +40638,6 @@ /area/engine/atmos) "bva" = ( /obj/machinery/atmospherics/components/binary/pump{ - dir = 2; name = "Mix to Distro" }, /obj/effect/turf_decal/tile/neutral{ @@ -41450,9 +41182,8 @@ "bwa" = ( /obj/structure/cable/white, /obj/machinery/power/apc{ - dir = 2; - name = "Security Transferring APC"; areastring = "/area/security/execution/transfer"; + name = "Security Transferring APC"; pixel_y = -26 }, /obj/effect/turf_decal/tile/red, @@ -41743,9 +41474,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/door/airlock/atmos{ name = "Atmospherics Access"; req_one_access_txt = "24;10" @@ -42459,9 +42188,7 @@ name = "External Airlock"; req_access_txt = "13" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -43040,9 +42767,9 @@ icon_state = "0-8" }, /obj/machinery/power/apc{ + areastring = "/area/security/nuke_storage"; dir = 4; name = "Vault APC"; - areastring = "/area/security/nuke_storage"; pixel_x = 26 }, /obj/effect/turf_decal/tile/neutral{ @@ -43561,9 +43288,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/door/airlock/atmos{ name = "Atmospherics Access"; req_one_access_txt = "24;10" @@ -43740,9 +43465,7 @@ req_access_txt = "19;23" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -44055,8 +43778,8 @@ height = 5; id = "laborcamp_home"; name = "fore bay 1"; - width = 9; - roundstart_template = /datum/map_template/shuttle/labour/delta + roundstart_template = /datum/map_template/shuttle/labour/delta; + width = 9 }, /turf/open/space/basic, /area/space) @@ -44310,11 +44033,8 @@ icon_state = "1-8" }, /obj/item/radio/intercom{ - anyai = 1; - broadcasting = 0; freerange = 1; frequency = 1424; - listening = 1; name = "Interrogation Intercom"; pixel_y = -58 }, @@ -44575,9 +44295,9 @@ /area/engine/gravity_generator) "bAL" = ( /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/engine/gravity_generator"; dir = 1; name = "Gravity Generator APC"; - areastring = "/area/engine/gravity_generator"; pixel_y = 24 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -44641,9 +44361,7 @@ req_access_txt = "13" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -44715,9 +44433,7 @@ name = "Atmospherics Lockdown Blast door" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -44731,9 +44447,7 @@ id = "atmoslock"; name = "Atmospherics Lockdown Blast door" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -44751,9 +44465,7 @@ req_access_txt = "24" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -45003,9 +44715,7 @@ name = "Maintenance Hatch"; req_access_txt = "12" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -45023,7 +44733,6 @@ /obj/structure/disposalpipe/segment, /obj/machinery/navbeacon{ codes_txt = "delivery;dir=2"; - dir = 2; freq = 1400; location = "Tool Storage" }, @@ -45556,7 +45265,6 @@ /obj/structure/table/reinforced, /obj/item/flashlight/lamp, /obj/item/radio/intercom{ - anyai = 1; broadcasting = 1; freerange = 1; frequency = 1424; @@ -45892,9 +45600,7 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -45929,9 +45635,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -46014,9 +45718,9 @@ dir = 1 }, /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/engine/break_room"; dir = 1; name = "Engineering Foyer APC"; - areastring = "/area/engine/break_room"; pixel_y = 24 }, /obj/structure/cable/white{ @@ -47111,7 +46815,6 @@ /area/security/brig) "bEf" = ( /obj/item/radio/intercom{ - anyai = 1; freerange = 1; listening = 0; name = "Custom Channel"; @@ -47119,15 +46822,11 @@ pixel_y = 22 }, /obj/item/radio/intercom{ - broadcasting = 0; freerange = 1; - listening = 1; name = "Common Channel"; pixel_x = -27 }, /obj/item/radio/intercom{ - anyai = 1; - broadcasting = 0; freerange = 1; frequency = 1447; name = "Private Channel"; @@ -47259,7 +46958,6 @@ /area/ai_monitored/turret_protected/ai) "bEm" = ( /obj/item/radio/intercom{ - anyai = 1; freerange = 1; listening = 0; name = "Custom Channel"; @@ -47267,15 +46965,11 @@ pixel_y = 22 }, /obj/item/radio/intercom{ - broadcasting = 0; freerange = 1; - listening = 1; name = "Common Channel"; pixel_x = 27 }, /obj/item/radio/intercom{ - anyai = 1; - broadcasting = 0; freerange = 1; frequency = 1447; name = "Private Channel"; @@ -47469,9 +47163,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -47484,9 +47176,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -47502,9 +47192,7 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -47787,9 +47475,9 @@ }, /obj/item/stack/cable_coil/white, /obj/machinery/power/apc{ + areastring = "/area/storage/primary"; dir = 8; name = "Primary Tool Storage APC"; - areastring = "/area/storage/primary"; pixel_x = -26; pixel_y = 3 }, @@ -48478,23 +48166,18 @@ /area/ai_monitored/turret_protected/ai) "bFT" = ( /obj/item/radio/intercom{ - broadcasting = 0; freerange = 1; - listening = 1; name = "Common Channel"; pixel_x = -27; pixel_y = -7 }, /obj/item/radio/intercom{ - anyai = 1; freerange = 1; listening = 0; name = "Custom Channel"; pixel_y = -27 }, /obj/item/radio/intercom{ - anyai = 1; - broadcasting = 0; freerange = 1; frequency = 1447; name = "Private Channel"; @@ -49218,9 +48901,8 @@ "bGY" = ( /obj/structure/cable/white, /obj/machinery/power/apc{ - dir = 2; - name = "Bridge APC"; areastring = "/area/bridge"; + name = "Bridge APC"; pixel_y = -26 }, /obj/effect/turf_decal/tile/blue, @@ -49829,9 +49511,7 @@ name = "Transit Tube Lockdown Door" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -49844,9 +49524,7 @@ name = "Transit Tube Lockdown Door" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -50100,9 +49778,9 @@ /obj/item/folder/yellow, /obj/item/electronics/airlock, /obj/machinery/power/apc{ + areastring = "/area/storage/tech"; dir = 8; name = "Technology Storage APC"; - areastring = "/area/storage/tech"; pixel_x = -26; pixel_y = 3 }, @@ -50665,9 +50343,9 @@ icon_state = "0-2" }, /obj/machinery/power/apc{ + areastring = "/area/security/detectives_office"; dir = 1; name = "Detective's Office APC"; - areastring = "/area/security/detectives_office"; pixel_y = 24 }, /obj/item/taperecorder, @@ -51056,9 +50734,9 @@ dir = 6 }, /obj/machinery/power/apc{ + areastring = "/area/ai_monitored/turret_protected/ai"; dir = 1; name = "AI Chamber APC"; - areastring = "/area/ai_monitored/turret_protected/ai"; pixel_y = 24 }, /obj/effect/turf_decal/tile/neutral{ @@ -51640,9 +51318,9 @@ icon_state = "0-2" }, /obj/machinery/power/apc/highcap/ten_k{ + areastring = "/area/bridge/meeting_room/council"; dir = 1; name = "Council Chambers APC"; - areastring = "/area/bridge/meeting_room/council"; pixel_y = 26 }, /turf/open/floor/wood, @@ -51827,9 +51505,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -52325,9 +52001,9 @@ /area/engine/transit_tube) "bLI" = ( /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/engine/transit_tube"; dir = 1; name = "Transit Tube Access APC"; - areastring = "/area/engine/transit_tube"; pixel_y = 24 }, /obj/machinery/atmospherics/components/unary/vent_pump/on, @@ -52932,9 +52608,9 @@ /area/tcommsat/computer) "bMz" = ( /obj/machinery/power/apc/highcap/ten_k{ + areastring = "/area/tcommsat/computer"; dir = 1; name = "Telecomms Monitoring APC"; - areastring = "/area/tcommsat/computer"; pixel_y = 28 }, /obj/item/twohanded/required/kirbyplants/random, @@ -52952,7 +52628,6 @@ }, /obj/machinery/camera{ c_tag = "Telecomms - Monitoring"; - dir = 2; name = "telecomms camera"; network = list("ss13","tcomms") }, @@ -53126,9 +52801,9 @@ /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk, /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/storage/tools"; dir = 1; name = "Auxiliary Tool Storage APC"; - areastring = "/area/storage/tools"; pixel_y = 24 }, /obj/effect/turf_decal/tile/yellow{ @@ -55229,9 +54904,7 @@ req_access_txt = "10" }, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -55669,9 +55342,8 @@ /area/crew_quarters/heads/captain) "bQV" = ( /obj/machinery/power/apc/highcap/ten_k{ - dir = 2; - name = "Captain's Office APC"; areastring = "/area/crew_quarters/heads/captain"; + name = "Captain's Office APC"; pixel_y = -24 }, /obj/structure/cable/white, @@ -56176,7 +55848,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/camera{ c_tag = "AI Satellite - Antechamber"; - dir = 2; name = "ai camera"; network = list("minisat"); start_active = 1 @@ -56463,7 +56134,6 @@ }, /obj/machinery/camera{ c_tag = "Engineering - Chief Engineer's Quarters"; - dir = 2; name = "engineering camera" }, /obj/effect/turf_decal/stripes/line{ @@ -56577,9 +56247,7 @@ req_access_txt = "23" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -56591,9 +56259,7 @@ name = "Primary Tool Storage" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -56604,18 +56270,14 @@ /obj/machinery/door/airlock/engineering/glass{ name = "Primary Tool Storage" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, /turf/open/floor/plasteel, /area/storage/primary) "bSv" = ( -/obj/structure/sign/directions/science{ - dir = 2 - }, +/obj/structure/sign/directions/science, /obj/structure/sign/directions/engineering{ dir = 8; pixel_y = 8 @@ -56629,9 +56291,7 @@ "bSw" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -56844,7 +56504,6 @@ /area/crew_quarters/heads/captain) "bSS" = ( /obj/structure/sign/directions/science{ - dir = 2; pixel_y = -8 }, /obj/structure/sign/directions/command{ @@ -57037,9 +56696,9 @@ icon_state = "0-8" }, /obj/machinery/power/apc{ + areastring = "/area/security/warden"; dir = 4; name = "Warden's Office APC"; - areastring = "/area/security/warden"; pixel_x = 26 }, /obj/machinery/camera{ @@ -57327,8 +56986,6 @@ /obj/item/twohanded/required/kirbyplants/random, /obj/machinery/turretid{ control_area = "/area/ai_monitored/turret_protected/aisat_interior"; - enabled = 1; - icon_state = "control_standby"; name = "Antechamber Turret Control"; pixel_x = -32; req_access = null; @@ -57370,6 +57027,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "bTD" = ( @@ -57386,6 +57044,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "bTF" = ( @@ -57501,7 +57160,6 @@ }, /obj/machinery/camera{ c_tag = "AI Satellite - Transit Tube"; - dir = 2; name = "ai camera"; network = list("minisat"); start_active = 1 @@ -57838,9 +57496,9 @@ /area/security/checkpoint/engineering) "bUf" = ( /obj/machinery/power/apc{ + areastring = "/area/security/checkpoint/engineering"; dir = 1; name = "Security Post - Engineering APC"; - areastring = "/area/security/checkpoint/engineering"; pixel_y = 24 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -58073,7 +57731,6 @@ }, /obj/machinery/camera{ c_tag = "Engineering Hallway - Starboard"; - dir = 2; name = "hallway camera" }, /obj/effect/turf_decal/tile/neutral{ @@ -58404,7 +58061,6 @@ }, /obj/machinery/camera{ c_tag = "Security Hallway - Port"; - dir = 2; name = "hallway camera" }, /obj/effect/turf_decal/tile/neutral{ @@ -59010,6 +58666,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "bVL" = ( @@ -59029,6 +58686,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "bVM" = ( @@ -60885,9 +60543,8 @@ /obj/structure/window/reinforced, /obj/structure/cable/white, /obj/machinery/power/apc{ - dir = 2; - name = "AI Satellite Exterior APC"; areastring = "/area/aisat"; + name = "AI Satellite Exterior APC"; pixel_y = -26 }, /obj/effect/turf_decal/tile/neutral{ @@ -61059,9 +60716,8 @@ "bYu" = ( /obj/structure/cable/white, /obj/machinery/power/apc{ - dir = 2; - name = "Chief Engineer's APC"; areastring = "/area/crew_quarters/heads/chief"; + name = "Chief Engineer's APC"; pixel_y = -26 }, /obj/effect/turf_decal/tile/neutral{ @@ -61725,9 +61381,8 @@ dir = 4 }, /obj/machinery/power/apc{ - dir = 2; - name = "Starboard Primary Hallway APC"; areastring = "/area/hallway/primary/starboard"; + name = "Starboard Primary Hallway APC"; pixel_y = -26 }, /obj/structure/cable/white{ @@ -62056,9 +61711,8 @@ pixel_x = -26 }, /obj/machinery/power/apc{ - dir = 2; - name = "MiniSat APC"; areastring = "/area/ai_monitored/turret_protected/aisat_interior"; + name = "MiniSat APC"; pixel_y = -27 }, /obj/structure/cable/white, @@ -62377,9 +62031,7 @@ req_access_txt = "10" }, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -62403,9 +62055,7 @@ req_access_txt = "63" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -62455,9 +62105,7 @@ req_access_txt = "12" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -62508,11 +62156,8 @@ /obj/structure/sign/directions/evac{ pixel_y = -8 }, -/obj/structure/sign/directions/medical{ - dir = 2 - }, +/obj/structure/sign/directions/medical, /obj/structure/sign/directions/security{ - dir = 2; pixel_y = 8 }, /turf/closed/wall, @@ -62736,9 +62381,7 @@ /obj/structure/sign/directions/evac{ pixel_y = -8 }, -/obj/structure/sign/directions/medical{ - dir = 2 - }, +/obj/structure/sign/directions/medical, /obj/structure/sign/directions/security{ dir = 4; pixel_y = 8 @@ -63042,9 +62685,8 @@ "cbK" = ( /obj/structure/cable/white, /obj/machinery/power/apc{ - dir = 2; - name = "Armoury APC"; areastring = "/area/ai_monitored/security/armory"; + name = "Armoury APC"; pixel_y = -26 }, /obj/machinery/camera{ @@ -63236,7 +62878,6 @@ }, /obj/machinery/camera{ c_tag = "Engineering - Fore"; - dir = 2; name = "engineering camera" }, /obj/effect/turf_decal/stripes/line{ @@ -63359,9 +63000,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -63601,7 +63240,6 @@ icon_state = "4-8" }, /obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 2; external_pressure_bound = 140; name = "server vent"; pressure_checks = 0 @@ -63651,7 +63289,6 @@ icon_state = "4-8" }, /obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ - dir = 2; external_pressure_bound = 120; name = "server vent" }, @@ -63818,8 +63455,7 @@ dir = 4 }, /obj/machinery/camera{ - c_tag = "Courtroom - Fore"; - dir = 2 + c_tag = "Courtroom - Fore" }, /obj/structure/sign/poster/official/report_crimes{ pixel_y = 32 @@ -63978,7 +63614,6 @@ /obj/item/folder/red, /obj/item/pen, /obj/machinery/door/window/brigdoor/southright{ - dir = 2; name = "Security Desk"; req_access_txt = "63" }, @@ -64080,9 +63715,7 @@ id = "armouryaccess"; name = "Armoury Access" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -64762,9 +64395,9 @@ /area/crew_quarters/heads/hop) "cer" = ( /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/heads/hop"; dir = 4; name = "HoP Office APC"; - areastring = "/area/crew_quarters/heads/hop"; pixel_x = 26 }, /obj/structure/cable/white{ @@ -64784,9 +64417,9 @@ /area/crew_quarters/heads/hop) "cet" = ( /obj/machinery/power/apc{ + areastring = "/area/tcommsat/server"; dir = 8; name = "Telecomms Server Room APC"; - areastring = "/area/tcommsat/server"; pixel_x = -26 }, /obj/structure/cable/white, @@ -65073,7 +64706,6 @@ /area/security/courtroom) "ceP" = ( /obj/structure/chair{ - dir = 2; name = "Prosecution" }, /obj/effect/turf_decal/tile/red{ @@ -65089,7 +64721,6 @@ /area/security/courtroom) "ceQ" = ( /obj/structure/chair{ - dir = 2; name = "Prosecution" }, /obj/effect/turf_decal/tile/red{ @@ -65438,17 +65069,16 @@ icon_state = "0-8" }, /obj/machinery/power/apc/highcap/ten_k{ + areastring = "/area/security/brig"; dir = 1; name = "Brig APC"; - areastring = "/area/security/brig"; pixel_y = 28 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/machinery/camera{ - c_tag = "Security - Gear Room"; - dir = 2 + c_tag = "Security - Gear Room" }, /obj/effect/turf_decal/tile/red{ dir = 1 @@ -65534,8 +65164,8 @@ }, /obj/effect/spawner/lootdrop/aimodule_harmless{ fan_out_items = 1; - lootdoubles = 0; - lootcount = 3 + lootcount = 3; + lootdoubles = 0 }, /obj/structure/sign/nanotrasen{ pixel_x = -32 @@ -65614,8 +65244,8 @@ }, /obj/effect/spawner/lootdrop/aimodule_harmful{ fan_out_items = 1; - lootdoubles = 0; - lootcount = 2 + lootcount = 2; + lootdoubles = 0 }, /obj/item/aiModule/supplied/oxygen{ pixel_x = -3; @@ -66102,9 +65732,8 @@ dir = 8 }, /obj/machinery/power/apc/highcap/ten_k{ - dir = 2; - name = "Captain's Quarters APC"; areastring = "/area/crew_quarters/heads/captain/private"; + name = "Captain's Quarters APC"; pixel_y = -24 }, /obj/structure/cable/white, @@ -67114,7 +66743,6 @@ /obj/structure/bookcase/manuals/research_and_development, /obj/machinery/camera{ c_tag = "Library"; - dir = 2; name = "library camera" }, /turf/open/floor/wood, @@ -67272,9 +66900,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -67411,9 +67037,9 @@ }, /obj/structure/cable/white, /obj/machinery/power/apc{ + areastring = "/area/lawoffice"; dir = 8; name = "Law Office APC"; - areastring = "/area/lawoffice"; pixel_x = -26; pixel_y = 3 }, @@ -68496,9 +68122,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -68788,9 +68412,9 @@ icon_state = "0-8" }, /obj/machinery/power/apc{ + areastring = "/area/engine/engineering"; dir = 4; name = "Engine Room APC"; - areastring = "/area/engine/engineering"; pixel_x = 26 }, /obj/effect/turf_decal/bot, @@ -68953,9 +68577,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -69181,9 +68803,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -69417,8 +69037,8 @@ /obj/structure/table/reinforced, /obj/effect/spawner/lootdrop/aimodule_neutral{ fan_out_items = 1; - lootdoubles = 0; - lootcount = 3 + lootcount = 3; + lootdoubles = 0 }, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -69815,9 +69435,9 @@ /obj/structure/table, /obj/item/hand_tele, /obj/machinery/power/apc/highcap/ten_k{ + areastring = "/area/teleporter"; dir = 1; name = "Teleporter APC"; - areastring = "/area/teleporter"; pixel_y = 28 }, /obj/structure/cable/white{ @@ -70353,9 +69973,8 @@ /obj/machinery/light, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/power/apc{ - dir = 2; - name = "AI Upload Access APC"; areastring = "/area/ai_monitored/turret_protected/ai_upload"; + name = "AI Upload Access APC"; pixel_y = -27 }, /obj/effect/turf_decal/tile/neutral{ @@ -70505,9 +70124,7 @@ /obj/structure/cable{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -71157,9 +70774,9 @@ "coN" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/power/apc{ + areastring = "/area/security/range"; dir = 8; name = "Shooting Range APC"; - areastring = "/area/security/range"; pixel_x = -26 }, /obj/structure/cable/white{ @@ -71375,9 +70992,7 @@ /obj/item/stack/sheet/mineral/plasma{ amount = 20 }, -/obj/item/gps/engineering{ - gpstag = "ENG0" - }, +/obj/item/gps/engineering, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/engine/engineering) @@ -71444,9 +71059,9 @@ /area/maintenance/port) "cpr" = ( /obj/machinery/power/apc{ + areastring = "/area/library"; dir = 8; name = "Library APC"; - areastring = "/area/library"; pixel_x = -26; pixel_y = 3 }, @@ -71780,9 +71395,9 @@ /area/security/courtroom) "cqb" = ( /obj/machinery/power/apc{ + areastring = "/area/security/courtroom"; dir = 4; name = "Courtroom APC"; - areastring = "/area/security/courtroom"; pixel_x = 26 }, /obj/structure/cable/white{ @@ -71803,9 +71418,7 @@ icon_state = "1-2" }, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -71829,9 +71442,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -71859,9 +71470,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -72214,9 +71823,7 @@ req_access_txt = "61" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -72228,9 +71835,7 @@ name = "Teleport Access"; req_access_txt = "17" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -72248,9 +71853,7 @@ id = "teleportershutters"; name = "Teleporter Shutters" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -72262,9 +71865,7 @@ name = "Teleporter Shutters" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -72792,9 +72393,7 @@ /turf/open/floor/plasteel, /area/engine/engineering) "crX" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -72802,9 +72401,7 @@ /area/engine/engineering) "crY" = ( /obj/effect/decal/cleanable/oil, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -73055,9 +72652,9 @@ dir = 4 }, /obj/machinery/power/apc{ + areastring = "/area/hallway/secondary/command"; dir = 1; name = "Command Hall APC"; - areastring = "/area/hallway/secondary/command"; pixel_y = 24 }, /obj/structure/cable/white{ @@ -73099,7 +72696,6 @@ }, /obj/machinery/camera{ c_tag = "Central Hallway - Center"; - dir = 2; name = "hallway camera" }, /obj/effect/turf_decal/tile/neutral{ @@ -73396,7 +72992,6 @@ }, /obj/machinery/camera{ c_tag = "Locker Room - Fore"; - dir = 2; name = "dormitories camera" }, /obj/effect/turf_decal/tile/neutral{ @@ -74443,9 +74038,8 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small, /obj/machinery/power/apc{ - dir = 2; - name = "Starboard Maintenance APC"; areastring = "/area/maintenance/starboard"; + name = "Starboard Maintenance APC"; pixel_y = -26 }, /obj/structure/cable/white, @@ -74777,9 +74371,7 @@ req_access_txt = "18" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -74792,9 +74384,7 @@ req_access_txt = "18" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -74907,9 +74497,7 @@ }, /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -75040,7 +74628,6 @@ }, /obj/machinery/camera{ c_tag = "Dormitory Hallway"; - dir = 2; name = "hallway camera" }, /obj/effect/turf_decal/tile/neutral{ @@ -75304,7 +74891,6 @@ /obj/item/pen, /obj/machinery/camera{ c_tag = "Recreation - Fore"; - dir = 2; name = "recreation camera" }, /obj/effect/turf_decal/tile/neutral{ @@ -75564,9 +75150,9 @@ /area/ai_monitored/storage/eva) "cwF" = ( /obj/machinery/power/apc{ + areastring = "/area/ai_monitored/storage/eva"; dir = 1; name = "E.V.A. Storage APC"; - areastring = "/area/ai_monitored/storage/eva"; pixel_y = 26 }, /obj/structure/cable/white{ @@ -75603,7 +75189,6 @@ /obj/structure/table/reinforced, /obj/machinery/camera{ c_tag = "Bridge - E.V.A. Fore"; - dir = 2; name = "command camera" }, /obj/effect/turf_decal/tile/neutral{ @@ -75721,9 +75306,9 @@ icon_state = "0-2" }, /obj/machinery/power/apc/highcap/ten_k{ + areastring = "/area/gateway"; dir = 1; name = "Gateway APC"; - areastring = "/area/gateway"; pixel_y = 28 }, /obj/effect/decal/cleanable/dirt, @@ -77798,9 +77383,7 @@ /obj/machinery/door/airlock{ name = "Primary Restroom" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -77929,9 +77512,9 @@ icon_state = "0-8" }, /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/locker"; dir = 4; name = "Lockerroom APC"; - areastring = "/area/crew_quarters/locker"; pixel_x = 26 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -77949,9 +77532,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -78458,7 +78039,6 @@ }, /obj/machinery/camera{ c_tag = "Bridge - Corporate Lounge"; - dir = 2; name = "command camera" }, /obj/effect/turf_decal/tile/neutral{ @@ -78697,8 +78277,7 @@ /area/crew_quarters/toilet/restrooms) "cBJ" = ( /obj/machinery/shower{ - dir = 8; - icon_state = "shower" + dir = 8 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -78748,9 +78327,9 @@ icon_state = "0-2" }, /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/toilet/restrooms"; dir = 1; name = "Primary Restroom APC"; - areastring = "/area/crew_quarters/toilet/restrooms"; pixel_y = 24 }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -78758,7 +78337,6 @@ }, /obj/machinery/camera{ c_tag = "Primary Restroom"; - dir = 2; name = "restroom camera" }, /obj/effect/turf_decal/tile/neutral{ @@ -79522,9 +79100,9 @@ icon_state = "2-4" }, /obj/machinery/power/apc{ + areastring = "/area/bridge/showroom/corporate"; dir = 8; name = "Corporate Lounge APC"; - areastring = "/area/bridge/showroom/corporate"; pixel_x = -26 }, /obj/structure/cable/white{ @@ -80294,9 +79872,9 @@ }, /obj/item/tank/jetpack/carbondioxide/eva, /obj/machinery/power/apc{ + areastring = "/area/engine/storage"; dir = 4; name = "Engineering Storage APC"; - areastring = "/area/engine/storage"; pixel_x = 26 }, /obj/structure/cable/white{ @@ -80858,8 +80436,7 @@ /area/crew_quarters/toilet/restrooms) "cFd" = ( /obj/machinery/shower{ - dir = 8; - icon_state = "shower" + dir = 8 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -81158,7 +80735,6 @@ "cFG" = ( /obj/machinery/camera{ c_tag = "Holodeck - Fore"; - dir = 2; name = "holodeck camera" }, /turf/open/floor/engine{ @@ -81898,7 +81474,6 @@ }, /obj/item/reagent_containers/food/drinks/beer{ desc = "Whatever it is, it reeks of foul, putrid froth."; - icon_state = "beer"; list_reagents = list("bacchus_blessing" = 15); name = "Delta-Down"; pixel_x = 5; @@ -82300,9 +81875,7 @@ name = "E.V.A. Storage Shutters" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -82313,9 +81886,7 @@ id = "evashutters"; name = "E.V.A. Storage Shutters" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -82333,9 +81904,7 @@ name = "E.V.A. Storage Shutters" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -82375,9 +81944,7 @@ name = "Gateway Atrium"; req_access_txt = "62" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -82396,9 +81963,7 @@ req_access_txt = "19" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -82410,9 +81975,7 @@ name = "Gateway Chamber Shutters" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -82423,9 +81986,7 @@ id = "gatewayshutters"; name = "Gateway Chamber Shutters" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -82522,9 +82083,7 @@ name = "Lockerroom" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -82537,9 +82096,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -82664,9 +82221,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -82735,7 +82290,6 @@ }, /obj/machinery/camera{ c_tag = "Central Hallway - Science Aft"; - dir = 2; name = "hallway camera" }, /obj/effect/turf_decal/stripes/corner{ @@ -82890,7 +82444,6 @@ }, /obj/machinery/camera{ c_tag = "Central Hallway - Medbay Aft"; - dir = 2; name = "hallway camera" }, /obj/effect/turf_decal/tile/neutral{ @@ -82965,9 +82518,7 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -83169,7 +82720,6 @@ }, /obj/machinery/camera{ c_tag = "Dormitories - Starboard"; - dir = 2; name = "dormitories camera" }, /obj/effect/turf_decal/tile/neutral{ @@ -83399,7 +82949,6 @@ }, /obj/machinery/camera{ c_tag = "Holodeck Control"; - dir = 2; name = "holodeck camera" }, /obj/effect/turf_decal/tile/neutral{ @@ -85264,9 +84813,8 @@ "cMy" = ( /obj/structure/cable/white, /obj/machinery/power/apc{ - dir = 2; - name = "Dormitories APC"; areastring = "/area/crew_quarters/dorms"; + name = "Dormitories APC"; pixel_y = -26 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -85487,9 +85035,7 @@ req_access_txt = "24" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -85512,9 +85058,7 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -85675,7 +85219,6 @@ }, /obj/machinery/camera{ c_tag = "Xenobiology - Killroom Chamber"; - dir = 2; name = "xenobiology camera"; network = list("ss13","xeno","rd") }, @@ -85748,9 +85291,7 @@ "cNr" = ( /obj/machinery/door/firedoor, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -85762,9 +85303,7 @@ /area/science/research) "cNt" = ( /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -85790,9 +85329,7 @@ name = "Aft Primary Hallway" }, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -85803,9 +85340,7 @@ /obj/machinery/door/airlock/public/glass{ name = "Aft Primary Hallway" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -85818,9 +85353,7 @@ name = "Aft Primary Hallway" }, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -85845,9 +85378,7 @@ /area/medical/medbay/central) "cNA" = ( /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -85860,9 +85391,7 @@ "cNC" = ( /obj/machinery/door/firedoor, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -86474,7 +86003,6 @@ /area/science/xenobiology) "cOO" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 2; external_pressure_bound = 140; name = "killroom vent"; pressure_checks = 0 @@ -86486,7 +86014,6 @@ /area/science/xenobiology) "cOQ" = ( /obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ - dir = 2; external_pressure_bound = 120; name = "server vent" }, @@ -86508,9 +86035,7 @@ req_access_txt = "47" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -86811,16 +86336,16 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ + areastring = "/area/medical/storage"; dir = 8; name = "Medbay Storage APC"; - areastring = "/area/medical/storage"; pixel_x = -26 }, /obj/machinery/camera{ c_tag = "Medbay - Storage"; - network = list("ss13","medbay"); dir = 4; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/item/twohanded/required/kirbyplants/random, /obj/effect/turf_decal/tile/neutral, @@ -87282,9 +86807,9 @@ icon_state = "0-8" }, /obj/machinery/power/apc{ + areastring = "/area/maintenance/department/electrical"; dir = 4; name = "Auxiliary Power APC"; - areastring = "/area/maintenance/department/electrical"; pixel_x = 26 }, /turf/open/floor/plating, @@ -87313,9 +86838,7 @@ req_access_txt = "47" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -88182,7 +87705,6 @@ }, /obj/machinery/camera{ c_tag = "Xenobiology - Port"; - dir = 2; name = "xenobiology camera"; network = list("ss13","xeno","rd") }, @@ -88387,9 +87909,7 @@ name = "Xenobiology Kill Room"; req_access_txt = "47" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -88957,9 +88477,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -89310,7 +88828,6 @@ icon_state = "1-2" }, /obj/machinery/door/window/brigdoor{ - dir = 2; name = "Creature Pen"; req_access_txt = "47" }, @@ -91128,9 +90645,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -91162,9 +90677,9 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/fitness/recreation"; dir = 8; name = "Recreation Area APC"; - areastring = "/area/crew_quarters/fitness/recreation"; pixel_x = -26 }, /obj/effect/turf_decal/tile/neutral{ @@ -91466,9 +90981,7 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -91484,9 +90997,7 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -91496,9 +91007,7 @@ /obj/structure/cable/white{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -91617,9 +91126,9 @@ pixel_y = -32 }, /obj/machinery/power/apc{ + areastring = "/area/security/checkpoint/science/research"; dir = 8; name = "Security Post - Science APC"; - areastring = "/area/security/checkpoint/science/research"; pixel_x = -26; pixel_y = 3 }, @@ -91865,9 +91374,9 @@ /obj/machinery/light, /obj/machinery/camera{ c_tag = "Medbay - Waiting Room"; - network = list("ss13","medbay"); dir = 1; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/blue, /turf/open/floor/plasteel/white, @@ -91991,9 +91500,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/structure/sign/poster/official/cleanliness{ pixel_x = -32 }, @@ -92008,9 +91515,7 @@ name = "Medbay Storage"; req_access_txt = "5" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -92040,9 +91545,8 @@ "cYc" = ( /obj/machinery/camera{ c_tag = "Medbay - Break Room"; - network = list("ss13","medbay"); - dir = 2; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/machinery/airalarm{ pixel_y = 23 @@ -92693,9 +92197,7 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -92714,9 +92216,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -92871,9 +92371,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/camera{ c_tag = "Medbay - Fore Port"; - network = list("ss13","medbay"); dir = 8; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/blue{ dir = 4 @@ -92891,9 +92391,9 @@ pixel_y = -32 }, /obj/machinery/power/apc{ + areastring = "/area/security/checkpoint/medical"; dir = 8; name = "Security Post - Medical APC"; - areastring = "/area/security/checkpoint/medical"; pixel_x = -26 }, /obj/machinery/atmospherics/components/unary/vent_pump/on{ @@ -92979,9 +92479,8 @@ /obj/item/stack/medical/ointment, /obj/machinery/camera{ c_tag = "Medbay - Sleepers"; - network = list("ss13","medbay"); - dir = 2; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/blue{ dir = 1 @@ -93430,9 +92929,7 @@ name = "Engineering Auxiliary Power"; req_access_txt = "10" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -93596,7 +93093,6 @@ /area/science/xenobiology) "daE" = ( /obj/structure/chair/office/light{ - icon_state = "officechair_white"; dir = 4 }, /obj/effect/turf_decal/stripes/line{ @@ -93891,9 +93387,9 @@ icon_state = "0-2" }, /obj/machinery/power/apc{ + areastring = "/area/medical/chemistry"; dir = 1; name = "Chemistry Lab APC"; - areastring = "/area/medical/chemistry"; pixel_y = 24 }, /obj/effect/turf_decal/tile/yellow{ @@ -94376,9 +93872,9 @@ dir = 4 }, /obj/machinery/power/apc{ + areastring = "/area/maintenance/port"; dir = 1; name = "Port Maintenance APC"; - areastring = "/area/maintenance/port"; pixel_y = 28 }, /obj/structure/cable/white{ @@ -94533,7 +94029,6 @@ icon_state = "1-4" }, /obj/machinery/door/window/brigdoor{ - dir = 2; name = "Creature Pen"; req_access_txt = "47" }, @@ -94584,7 +94079,6 @@ icon_state = "1-4" }, /obj/machinery/door/window/brigdoor{ - dir = 2; name = "Creature Pen"; req_access_txt = "47" }, @@ -94639,7 +94133,6 @@ name = "Creature Cell #3" }, /obj/machinery/door/window/brigdoor{ - dir = 2; name = "Creature Pen"; req_access_txt = "47" }, @@ -94733,9 +94226,9 @@ dir = 4 }, /obj/machinery/power/apc{ + areastring = "/area/science/xenobiology"; dir = 4; name = "Xenobiology Lab APC"; - areastring = "/area/science/xenobiology"; pixel_x = 26 }, /obj/effect/turf_decal/stripes/line, @@ -96244,9 +95737,7 @@ name = "Xenobiology Lab"; req_access_txt = "47" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -96272,9 +95763,7 @@ "dfg" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -96283,9 +95772,7 @@ "dfh" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -96336,9 +95823,7 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -96355,9 +95840,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -96378,9 +95861,9 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ + areastring = "/area/science/lab"; dir = 8; name = "Research and Development Lab APC"; - areastring = "/area/science/lab"; pixel_x = -26; pixel_y = 3 }, @@ -96515,9 +95998,9 @@ }, /obj/machinery/camera{ c_tag = "Medbay - Chemistry"; - network = list("ss13","medbay"); dir = 8; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/yellow, /turf/open/floor/plasteel/white, @@ -96572,9 +96055,7 @@ name = "Medical Cell"; req_access_txt = "63" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -96583,9 +96064,7 @@ "dfF" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -96594,9 +96073,7 @@ "dfG" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -96611,9 +96088,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -96631,9 +96106,7 @@ req_access_txt = "5" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -96819,9 +96292,9 @@ /obj/item/clothing/gloves/color/fyellow, /obj/item/storage/toolbox/electrical, /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/abandoned_gambling_den"; dir = 1; name = "Abandoned Gambling Den APC"; - areastring = "/area/crew_quarters/abandoned_gambling_den"; pixel_y = 24 }, /turf/open/floor/plating, @@ -97061,7 +96534,6 @@ }, /obj/machinery/camera{ c_tag = "Science - Port"; - dir = 2; name = "science camera"; network = list("ss13","rd") }, @@ -97146,7 +96618,6 @@ }, /obj/machinery/camera{ c_tag = "Science - Center"; - dir = 2; name = "science camera"; network = list("ss13","rd") }, @@ -97557,9 +97028,8 @@ }, /obj/machinery/camera{ c_tag = "Medbay - Center"; - network = list("ss13","medbay"); - dir = 2; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/blue{ dir = 1 @@ -98174,7 +97644,6 @@ /area/science/lab) "dil" = ( /obj/structure/chair/office/light{ - icon_state = "officechair_white"; dir = 4 }, /obj/effect/turf_decal/tile/purple, @@ -99007,14 +98476,13 @@ icon_state = "0-2" }, /obj/machinery/power/apc{ + areastring = "/area/science/explab"; dir = 1; name = "Experimentation Lab APC"; - areastring = "/area/science/explab"; pixel_y = 24 }, /obj/machinery/camera{ c_tag = "Science - Experimentation Lab"; - dir = 2; name = "science camera"; network = list("ss13","rd") }, @@ -99453,9 +98921,9 @@ /obj/machinery/light, /obj/machinery/camera{ c_tag = "Medbay - Port"; - network = list("ss13","medbay"); dir = 1; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -99583,9 +99051,9 @@ /obj/machinery/light, /obj/machinery/camera{ c_tag = "Medbay - Starboard"; - network = list("ss13","medbay"); dir = 1; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/structure/sign/poster/official/work_for_a_future{ pixel_y = -32 @@ -99649,9 +99117,8 @@ /obj/effect/decal/cleanable/dirt, /obj/structure/cable/white, /obj/machinery/power/apc{ - dir = 2; - name = "Abandoned Medical Lab APC"; areastring = "/area/medical/abandoned"; + name = "Abandoned Medical Lab APC"; pixel_x = 1; pixel_y = -24 }, @@ -100063,9 +99530,7 @@ name = "Research Division Access"; req_access_txt = "47" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -100178,9 +99643,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -100190,9 +99653,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/disposalpipe/segment, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -100200,9 +99661,7 @@ /area/hallway/primary/aft) "dlR" = ( /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -100216,9 +99675,7 @@ pixel_x = 24 }, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -100234,9 +99691,7 @@ req_access_txt = "5; 33" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -100259,9 +99714,7 @@ }, /obj/structure/disposalpipe/segment, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -100272,9 +99725,7 @@ icon_state = "1-2" }, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -100293,9 +99744,7 @@ name = "Surgery Observation" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -100310,9 +99759,7 @@ /obj/machinery/door/airlock/medical{ name = "Surgery Observation" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -100760,9 +100207,9 @@ icon_state = "0-8" }, /obj/machinery/power/apc/highcap/ten_k{ + areastring = "/area/science/robotics/mechbay"; dir = 1; name = "Mech Bay APC"; - areastring = "/area/science/robotics/mechbay"; pixel_y = 28 }, /obj/effect/turf_decal/stripes/line{ @@ -100803,9 +100250,9 @@ "dni" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/power/apc{ + areastring = "/area/maintenance/department/medical"; dir = 1; name = "Medical Maintenance APC"; - areastring = "/area/maintenance/department/medical"; pixel_y = 24 }, /obj/structure/cable/white{ @@ -100907,9 +100354,9 @@ icon_state = "0-2" }, /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/medical/genetics/cloning"; dir = 1; name = "Cloning Lab APC"; - areastring = "/area/medical/genetics/cloning"; pixel_y = 24 }, /obj/item/folder/white, @@ -101177,9 +100624,7 @@ "dnP" = ( /obj/machinery/pipedispenser, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -101187,9 +100632,7 @@ /area/hallway/secondary/construction) "dnQ" = ( /obj/machinery/pipedispenser/disposal, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -101197,9 +100640,7 @@ /area/hallway/secondary/construction) "dnR" = ( /obj/machinery/pipedispenser/disposal/transit_tube, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -103056,9 +102497,7 @@ /obj/machinery/door/airlock/medical{ name = "Surgery Observation" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -103201,7 +102640,6 @@ /obj/structure/cable/white, /obj/machinery/power/apc{ areastring = "/area/science/circuit"; - dir = 2; name = "Circuitry Lab APC"; pixel_x = 1; pixel_y = -24 @@ -103335,9 +102773,7 @@ id = "rdtoxins"; name = "Toxins Lab Shutters" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -103352,9 +102788,9 @@ /area/science/mixing) "drX" = ( /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/heads/hor"; dir = 8; name = "Research Director's Office APC"; - areastring = "/area/crew_quarters/heads/hor"; pixel_x = -26 }, /obj/structure/cable/white, @@ -103640,9 +103076,9 @@ }, /obj/machinery/camera{ c_tag = "Medbay - Cloning Lab"; - network = list("ss13","medbay"); dir = 1; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel/white, @@ -103720,9 +103156,9 @@ /obj/structure/table/glass, /obj/machinery/camera{ c_tag = "Medbay - Cryogenics"; - network = list("ss13","medbay"); dir = 1; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/item/book/manual/wiki/medicine, /obj/item/clothing/neck/stethoscope, @@ -104175,9 +103611,7 @@ name = "Genetics Desk Maintenance"; req_access_txt = "9" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -104213,9 +103647,7 @@ icon_state = "2-4" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -104234,9 +103666,9 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ + areastring = "/area/medical/medbay/central"; dir = 8; name = "Medbay APC"; - areastring = "/area/medical/medbay/central"; pixel_x = -26 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -104328,9 +103760,9 @@ /obj/machinery/iv_drip, /obj/machinery/camera{ c_tag = "Medbay - Recovery Room"; - network = list("ss13","medbay"); dir = 8; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 @@ -105982,9 +105414,9 @@ /obj/item/clipboard, /obj/item/toy/figure/geneticist, /obj/machinery/power/apc{ + areastring = "/area/medical/genetics"; dir = 4; name = "Genetics Lab APC"; - areastring = "/area/medical/genetics"; pixel_x = 26 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -106011,9 +105443,9 @@ }, /obj/machinery/camera{ c_tag = "Medbay - Genetics Lab"; - network = list("ss13","medbay"); dir = 4; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/machinery/light_switch{ pixel_x = -26 @@ -106679,9 +106111,7 @@ req_access_txt = "30" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -106701,9 +106131,7 @@ icon_state = "1-2" }, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -106713,9 +106141,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/airalarm{ dir = 8; pixel_x = 24 @@ -106749,9 +106175,7 @@ name = "Robotics Lab"; req_access_txt = "29" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -106764,9 +106188,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -106785,9 +106207,9 @@ /obj/item/storage/box/disks, /obj/machinery/camera{ c_tag = "Medbay - Genetics Desk"; - network = list("ss13","medbay"); dir = 4; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/purple{ dir = 1 @@ -107218,16 +106640,15 @@ "dyI" = ( /obj/structure/cable/white, /obj/machinery/power/apc{ - dir = 2; - name = "Surgery APC"; areastring = "/area/medical/surgery"; + name = "Surgery APC"; pixel_y = -26 }, /obj/machinery/camera{ c_tag = "Medbay - Surgery"; - network = list("ss13","medbay"); dir = 1; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -107322,9 +106743,8 @@ /area/hallway/secondary/construction) "dyP" = ( /obj/machinery/power/apc{ - dir = 2; - name = "Auxiliary Construction Zone APC"; areastring = "/area/hallway/secondary/construction"; + name = "Auxiliary Construction Zone APC"; pixel_y = -26 }, /obj/structure/cable/white{ @@ -107969,9 +107389,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/camera{ c_tag = "Medbay - Aft Port"; - network = list("ss13","medbay"); dir = 8; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/item/clipboard, /obj/item/healthanalyzer, @@ -108042,16 +107462,16 @@ dir = 4 }, /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/heads/cmo"; dir = 4; name = "Chief Medical Officer's Office APC"; - areastring = "/area/crew_quarters/heads/cmo"; pixel_x = 26 }, /obj/machinery/camera{ c_tag = "Medbay - Chief Medical Officer's Office"; - network = list("ss13","medbay"); dir = 8; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -108084,9 +107504,7 @@ req_access_txt = "12" }, /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -108101,9 +107519,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -108221,9 +107637,9 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ + areastring = "/area/science/mixing"; dir = 8; name = "Toxins Lab APC"; - areastring = "/area/science/mixing"; pixel_x = -26; pixel_y = 3 }, @@ -108396,7 +107812,6 @@ /area/science/robotics/lab) "dAO" = ( /obj/structure/chair/office/light{ - icon_state = "officechair_white"; dir = 4 }, /obj/effect/landmark/start/roboticist, @@ -109414,9 +108829,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, /obj/machinery/power/apc{ + areastring = "/area/hallway/primary/aft"; dir = 4; name = "Aft Primary Hallway APC"; - areastring = "/area/hallway/primary/aft"; pixel_x = 26 }, /obj/structure/cable/white{ @@ -109438,9 +108853,7 @@ req_access_txt = "9" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -109470,9 +108883,7 @@ req_access_txt = "5" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -109559,9 +108970,9 @@ }, /obj/machinery/camera{ c_tag = "Medbay - Aft Starboard"; - network = list("ss13","medbay"); dir = 4; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/blue{ dir = 8 @@ -109764,9 +109175,8 @@ "dDc" = ( /obj/structure/cable/white, /obj/machinery/power/apc/highcap/ten_k{ - dir = 2; - name = "Starboard Quarter Solar APC"; areastring = "/area/maintenance/solars/starboard/aft"; + name = "Starboard Quarter Solar APC"; pixel_y = -26 }, /obj/effect/turf_decal/stripes/line{ @@ -109785,8 +109195,7 @@ /obj/machinery/power/solar_control{ dir = 8; id = "aftstarboard"; - name = "Starboard Quarter Solar Control"; - track = 0 + name = "Starboard Quarter Solar Control" }, /obj/structure/cable, /obj/machinery/airalarm{ @@ -109958,9 +109367,7 @@ id = "rdtoxins"; name = "Toxins Lab Shutters" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -110533,9 +109940,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/barricade/wooden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -111094,9 +110499,7 @@ /turf/open/floor/plating, /area/crew_quarters/theatre/abandoned) "dFl" = ( -/obj/machinery/vending/autodrobe{ - req_access_txt = "0" - }, +/obj/machinery/vending/autodrobe, /obj/machinery/light/small{ dir = 1 }, @@ -111107,9 +110510,9 @@ icon_state = "0-2" }, /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/theatre/abandoned"; dir = 1; name = "Abandoned Theatre APC"; - areastring = "/area/crew_quarters/theatre/abandoned"; pixel_y = 24 }, /turf/open/floor/plating, @@ -111277,7 +110680,6 @@ /obj/item/clothing/mask/gas, /obj/machinery/camera{ c_tag = "Science - Toxins Launch Site"; - dir = 2; name = "science camera"; network = list("ss13","rd") }, @@ -111327,9 +110729,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -111458,9 +110858,9 @@ dir = 4 }, /obj/machinery/power/apc{ + areastring = "/area/science/server"; dir = 8; name = "Research Division Server Room APC"; - areastring = "/area/science/server"; pixel_x = -26 }, /obj/machinery/light_switch{ @@ -111593,9 +110993,9 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ + areastring = "/area/science/robotics/lab"; dir = 8; name = "Robotics Lab APC"; - areastring = "/area/science/robotics/lab"; pixel_x = -26 }, /obj/structure/disposalpipe/trunk{ @@ -112905,9 +112305,9 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ + areastring = "/area/security/detectives_office/private_investigators_office"; dir = 8; name = "Private Investigator's Office APC"; - areastring = "/area/security/detectives_office/private_investigators_office"; pixel_x = -26; pixel_y = 3 }, @@ -112952,7 +112352,6 @@ /area/science/test_area) "dIj" = ( /obj/machinery/button/massdriver{ - dir = 2; id = "toxinsdriver"; pixel_x = -24 }, @@ -112975,9 +112374,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/mixing) "dIm" = ( @@ -112985,18 +112382,14 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/mixing) "dIn" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/mixing) "dIo" = ( @@ -113007,9 +112400,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/mixing) "dIp" = ( @@ -113250,7 +112641,6 @@ /area/science/storage) "dIF" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 2; external_pressure_bound = 140; name = "server vent"; pressure_checks = 0 @@ -113273,7 +112663,6 @@ /area/science/server) "dIH" = ( /obj/machinery/atmospherics/components/unary/vent_pump/siphon/on{ - dir = 2; external_pressure_bound = 120; name = "server vent" }, @@ -113329,9 +112718,9 @@ icon_state = "0-8" }, /obj/machinery/power/apc{ + areastring = "/area/science/research"; dir = 4; name = "Research Division APC"; - areastring = "/area/science/research"; pixel_x = 26 }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -113449,9 +112838,8 @@ "dIV" = ( /obj/structure/cable/white, /obj/machinery/power/apc{ - dir = 2; - name = "Morgue APC"; areastring = "/area/medical/morgue"; + name = "Morgue APC"; pixel_y = -26 }, /turf/open/floor/plating, @@ -113478,9 +112866,9 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/camera{ c_tag = "Medbay - Morgue"; - network = list("ss13","medbay"); dir = 1; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/structure/sign/poster/official/bless_this_spess{ pixel_y = -32 @@ -113569,9 +112957,8 @@ "dJg" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/power/apc{ - dir = 2; - name = "Morgue Maintenance APC"; areastring = "/area/maintenance/department/medical/morgue"; + name = "Morgue Maintenance APC"; pixel_y = -26 }, /obj/structure/cable/white{ @@ -113619,9 +113006,9 @@ }, /obj/machinery/camera{ c_tag = "Medbay - Chief Medical Officer's Quarters"; - network = list("ss13","medbay"); dir = 1; - name = "medbay camera" + name = "medbay camera"; + network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/blue{ dir = 4 @@ -114100,9 +113487,9 @@ /obj/machinery/portable_atmospherics/scrubber/huge, /obj/effect/decal/cleanable/dirt, /obj/machinery/power/apc{ + areastring = "/area/science/storage"; dir = 4; name = "Toxins Storage APC"; - areastring = "/area/science/storage"; pixel_x = 26 }, /obj/structure/cable/white, @@ -114172,9 +113559,7 @@ req_access_txt = "29" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -114216,9 +113601,7 @@ req_access_txt = "12" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -114237,9 +113620,7 @@ name = "Virology Access"; req_access_txt = "39" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -114390,9 +113771,7 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -114413,9 +113792,7 @@ }, /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -114447,9 +113824,7 @@ icon_state = "1-2" }, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -115024,9 +114399,7 @@ /area/science/test_area) "dLG" = ( /obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating/airless, /area/science/test_area) "dLH" = ( @@ -115064,9 +114437,7 @@ /turf/open/floor/plasteel, /area/science/mixing) "dLM" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -115529,9 +114900,8 @@ }, /obj/structure/cable/white, /obj/machinery/power/apc{ - dir = 2; - name = "Aft Maintenance APC"; areastring = "/area/maintenance/aft"; + name = "Aft Maintenance APC"; pixel_x = 1; pixel_y = -24 }, @@ -116223,9 +115593,7 @@ req_access_txt = "19" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -116245,9 +115613,7 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -116258,9 +115624,7 @@ /obj/machinery/door/airlock/public/glass{ name = "Departures Lounge" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -116273,9 +115637,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -116820,9 +116182,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /obj/structure/barricade/wooden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -116839,9 +116199,7 @@ icon_state = "1-2" }, /obj/structure/barricade/wooden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -116871,9 +116229,7 @@ /obj/machinery/door/airlock{ name = "Bathroom" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -117100,9 +116456,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/mapping_helpers/airlock/locked, /obj/machinery/door/airlock/virology{ autoclose = 0; @@ -117301,9 +116655,9 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /obj/machinery/power/apc{ + areastring = "/area/maintenance/port/aft"; dir = 1; name = "Port Quarter Maintenance APC"; - areastring = "/area/maintenance/port/aft"; pixel_y = 24 }, /obj/structure/cable/white{ @@ -117601,9 +116955,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/camera{ c_tag = "Virology - Containment Lock"; - network = list("ss13","medbay"); dir = 8; - name = "virology camera" + name = "virology camera"; + network = list("ss13","medbay") }, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, @@ -117865,9 +117219,7 @@ /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -118102,9 +117454,7 @@ /obj/machinery/light/small{ dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -118120,9 +117470,7 @@ /obj/structure/cable/white{ icon_state = "1-4" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -118259,9 +117607,9 @@ }, /obj/machinery/camera{ c_tag = "Virology - Break Room"; - network = list("ss13","medbay"); dir = 8; - name = "virology camera" + name = "virology camera"; + network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/green{ dir = 4 @@ -119047,9 +118395,7 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -119145,9 +118491,7 @@ name = "Maintenance Hatch"; req_access_txt = "12" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, @@ -119194,9 +118538,7 @@ name = "Departures Lounge" }, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -119207,9 +118549,7 @@ /obj/machinery/door/airlock/public/glass{ name = "Departures Lounge" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -119362,9 +118702,9 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ + areastring = "/area/library/abandoned"; dir = 8; name = "Abandoned Library APC"; - areastring = "/area/library/abandoned"; pixel_x = -26; pixel_y = 3 }, @@ -119531,14 +118871,13 @@ /area/hallway/secondary/exit/departure_lounge) "dTG" = ( /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/hallway/secondary/exit/departure_lounge"; dir = 1; name = "Departure Lounge APC"; - areastring = "/area/hallway/secondary/exit/departure_lounge"; pixel_y = 28 }, /obj/machinery/camera{ c_tag = "Departures - Fore"; - dir = 2; name = "departures camera" }, /obj/structure/cable/white{ @@ -120112,9 +119451,9 @@ dir = 4 }, /obj/machinery/power/apc{ + areastring = "/area/medical/virology"; dir = 4; name = "Virology Satellite APC"; - areastring = "/area/medical/virology"; pixel_x = 26 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -120383,8 +119722,8 @@ }, /obj/machinery/camera{ c_tag = "Virology - Lab"; - network = list("ss13","medbay"); - name = "virology camera" + name = "virology camera"; + network = list("ss13","medbay") }, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, @@ -120407,9 +119746,9 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/camera{ c_tag = "Virology - Hallway"; - network = list("ss13","medbay"); dir = 8; - name = "virology camera" + name = "virology camera"; + network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/green, /obj/effect/turf_decal/tile/green{ @@ -121357,9 +120696,7 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -122381,7 +121718,6 @@ /obj/effect/landmark/start/assistant, /obj/machinery/camera{ c_tag = "Departures - Center"; - dir = 2; name = "departures camera" }, /obj/effect/turf_decal/bot, @@ -122520,9 +121856,9 @@ }, /obj/machinery/camera{ c_tag = "Virology - Cells"; - network = list("ss13","medbay"); dir = 8; - name = "virology camera" + name = "virology camera"; + network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/green, /turf/open/floor/plasteel/white, @@ -122646,9 +121982,9 @@ /area/chapel/office) "dZQ" = ( /obj/machinery/power/apc{ + areastring = "/area/chapel/main"; dir = 8; name = "Chapel APC"; - areastring = "/area/chapel/main"; pixel_x = -26; pixel_y = 3 }, @@ -122779,7 +122115,6 @@ /area/hallway/secondary/exit/departure_lounge) "eab" = ( /obj/docking_port/stationary{ - dheight = 0; dir = 4; dwidth = 11; height = 18; @@ -122843,9 +122178,7 @@ req_access_txt = "39" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -123206,9 +122539,7 @@ }, /obj/effect/decal/cleanable/dirt, /obj/structure/barricade/wooden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -123226,9 +122557,7 @@ name = "E.V.A. Storage Shutters" }, /obj/structure/barricade/wooden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -123245,9 +122574,7 @@ icon_state = "1-2" }, /obj/structure/barricade/wooden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -123260,9 +122587,7 @@ req_access_txt = "18" }, /obj/structure/barricade/wooden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -123771,8 +123096,7 @@ /obj/machinery/power/solar_control{ dir = 4; id = "aftport"; - name = "Port Quarter Solar Control"; - track = 0 + name = "Port Quarter Solar Control" }, /obj/structure/cable, /obj/effect/turf_decal/stripes/line{ @@ -123794,9 +123118,8 @@ "ecm" = ( /obj/structure/cable/white, /obj/machinery/power/apc/highcap/ten_k{ - dir = 2; - name = "Port Quarter Solar APC"; areastring = "/area/maintenance/solars/port/aft"; + name = "Port Quarter Solar APC"; pixel_y = -26 }, /obj/effect/turf_decal/stripes/line{ @@ -124826,9 +124149,7 @@ name = "Maintenance Hatch"; req_access_txt = "12" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -124851,9 +124172,7 @@ req_access_txt = "63" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -124874,9 +124193,7 @@ /obj/structure/cable/white{ icon_state = "2-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -124917,9 +124234,7 @@ name = "Holding Area"; req_access_txt = "2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -125049,7 +124364,6 @@ pixel_x = -26 }, /obj/machinery/airalarm{ - dir = 2; pixel_y = 22 }, /obj/effect/turf_decal/tile/neutral{ @@ -125075,9 +124389,9 @@ dir = 1 }, /obj/machinery/power/apc{ + areastring = "/area/chapel/office"; dir = 1; name = "Chapel Quarters APC"; - areastring = "/area/chapel/office"; pixel_y = 24 }, /obj/structure/cable/white{ @@ -125095,7 +124409,6 @@ /obj/item/twohanded/required/kirbyplants/random, /obj/machinery/camera{ c_tag = "Chapel Quarters"; - dir = 2; name = "chapel camera" }, /turf/open/floor/plasteel/grimy, @@ -125212,8 +124525,7 @@ pixel_y = 26 }, /obj/machinery/camera{ - c_tag = "Security - Departures Port"; - dir = 2 + c_tag = "Security - Departures Port" }, /obj/effect/turf_decal/tile/red{ dir = 1 @@ -125376,9 +124688,7 @@ /turf/open/floor/plasteel, /area/security/checkpoint/escape) "eeT" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -125568,9 +124878,7 @@ name = "External Airlock"; req_access_txt = "13" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -126186,9 +125494,7 @@ name = "External Airlock"; req_access_txt = "13" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -126282,9 +125588,7 @@ /turf/open/floor/plasteel/dark/corner, /area/engine/engineering) "ehy" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -126353,9 +125657,7 @@ /turf/open/floor/plasteel/white, /area/medical/storage) "ehM" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -126771,9 +126073,7 @@ }, /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -126878,7 +126178,6 @@ dir = 8 }, /obj/machinery/computer/arcade{ - icon_state = "arcade"; dir = 1 }, /turf/open/floor/plasteel/dark, @@ -126969,7 +126268,6 @@ /obj/structure/table/reinforced, /obj/machinery/camera{ c_tag = "Science - Experimentation Lab"; - dir = 2; name = "science camera"; network = list("ss13","rd") }, @@ -127102,7 +126400,6 @@ dir = 8 }, /obj/machinery/computer/arcade{ - icon_state = "arcade"; dir = 4 }, /turf/open/floor/plasteel/dark, @@ -127359,6 +126656,23 @@ }, /turf/open/floor/plasteel, /area/maintenance/port/aft) +"mgh" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/landmark/start/cyborg, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat_interior) "mkm" = ( /obj/machinery/atmospherics/components/binary/valve, /obj/machinery/embedded_controller/radio/airlock_controller/incinerator_toxmix{ @@ -127419,9 +126733,7 @@ /turf/open/floor/plating, /area/crew_quarters/abandoned_gambling_den) "mPj" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/chapel/office) "mPH" = ( @@ -127498,7 +126810,6 @@ dir = 8 }, /obj/machinery/computer/arcade{ - icon_state = "arcade"; dir = 1 }, /turf/open/floor/plasteel/dark, @@ -127894,7 +127205,6 @@ dir = 4 }, /obj/machinery/airalarm{ - dir = 2; pixel_y = 22 }, /turf/open/floor/plasteel/dark, @@ -128243,6 +127553,21 @@ }, /turf/open/floor/plating, /area/science/research/abandoned) +"ylW" = ( +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/effect/turf_decal/tile/neutral{ + dir = 1 + }, +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 8 + }, +/obj/effect/landmark/start/cyborg, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat_interior) (1,1,1) = {" aaa @@ -138137,7 +137462,7 @@ bPC bRK bTC bVK -bXW +ylW cal bPC aaa @@ -138394,7 +137719,7 @@ bPC bRL bTC bVx -bXX +mgh cam bPC bRO @@ -138651,7 +137976,7 @@ bPC bRM bTD bVL -bXX +mgh can bPC bkE diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 3516d61080..d31dbe1405 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -334,7 +334,6 @@ /area/solar/port/fore) "abg" = ( /obj/machinery/door/poddoor{ - density = 1; id = "SecJusticeChamber"; name = "Justice Vent" }, @@ -448,7 +447,6 @@ /area/security/prison) "abu" = ( /obj/docking_port/stationary{ - dir = 1; dwidth = 1; height = 4; roundstart_template = /datum/map_template/shuttle/escape_pod/default; @@ -662,7 +660,6 @@ dir = 8 }, /obj/machinery/sparker{ - dir = 2; id = "executionburn"; pixel_x = -25 }, @@ -798,14 +795,11 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel/dark, /area/security/execution/education) "aco" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/on{ - dir = 2; name = "justice injector" }, /obj/effect/turf_decal/stripes/line{ @@ -952,7 +946,6 @@ /area/security/execution/education) "acC" = ( /obj/machinery/door/window/brigdoor{ - dir = 2; name = "Justice Chamber"; req_access_txt = "3" }, @@ -1025,7 +1018,6 @@ }, /obj/item/radio/intercom{ desc = "Talk through this. It looks like it has been modified to not broadcast."; - dir = 2; name = "Prison Intercom (General)"; pixel_y = -28; prison_radio = 1 @@ -1053,9 +1045,7 @@ /turf/open/floor/plasteel, /area/security/prison) "acK" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel, /area/security/prison) "acL" = ( @@ -1129,7 +1119,6 @@ }, /obj/machinery/camera{ c_tag = "Prison Sanitarium"; - dir = 2; network = list("ss13","prison") }, /obj/effect/turf_decal/tile/red{ @@ -1220,7 +1209,6 @@ req_access_txt = "1" }, /obj/machinery/button/door{ - dir = 2; id = "SecJusticeChamber"; layer = 4; name = "Justice Vent Control"; @@ -1291,9 +1279,9 @@ /area/security/execution/education) "acZ" = ( /obj/machinery/power/apc{ + areastring = "/area/security/execution/education"; dir = 1; name = "Prisoner Education Chamber APC"; - areastring = "/area/security/execution/education"; pixel_y = 24 }, /obj/structure/cable/yellow{ @@ -1582,8 +1570,6 @@ /area/space/nearstation) "adJ" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = -28 }, @@ -1630,9 +1616,7 @@ pixel_y = -25; specialfunctions = 4 }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ dir = 8 @@ -1793,9 +1777,7 @@ /turf/open/floor/plating, /area/crew_quarters/heads/hos) "aed" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/crew_quarters/fitness/recreation) "aee" = ( @@ -1829,9 +1811,7 @@ }, /obj/machinery/meter, /obj/machinery/door/window/westleft{ - base_state = "left"; dir = 1; - icon_state = "left"; name = "gas ports" }, /turf/open/floor/plasteel/dark, @@ -1933,9 +1913,7 @@ /area/ai_monitored/security/armory) "aer" = ( /obj/structure/rack, -/obj/item/gun/energy/ionrifle{ - pin = /obj/item/firing_pin - }, +/obj/item/gun/energy/ionrifle, /obj/machinery/light{ dir = 1 }, @@ -2143,9 +2121,7 @@ /obj/structure/cable/yellow{ icon_state = "1-4" }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aeL" = ( @@ -2160,9 +2136,7 @@ name = "WARNING: Do Not Enter When Red Light Shows"; pixel_y = 32 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aeM" = ( @@ -2173,9 +2147,7 @@ icon_state = "2-4" }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aeN" = ( @@ -2185,9 +2157,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aeO" = ( @@ -2209,9 +2179,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aeP" = ( @@ -2232,9 +2200,7 @@ c_tag = "Prison Hallway Port"; network = list("ss13","prison") }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aeQ" = ( @@ -2247,9 +2213,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aeR" = ( @@ -2260,9 +2224,7 @@ icon_state = "1-4" }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aeS" = ( @@ -2285,9 +2247,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aeT" = ( @@ -2303,9 +2263,7 @@ network = list("prison"); pixel_y = 30 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aeU" = ( @@ -2316,9 +2274,7 @@ /obj/machinery/light{ dir = 1 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aeV" = ( @@ -2328,9 +2284,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aeW" = ( @@ -2353,16 +2307,14 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aeX" = ( /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/security/prison"; dir = 1; name = "Prison Wing APC"; - areastring = "/area/security/prison"; pixel_x = 1; pixel_y = 24 }, @@ -2380,12 +2332,9 @@ }, /obj/machinery/camera{ c_tag = "Prison Hallway Starboard"; - dir = 2; network = list("ss13","prison") }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aeY" = ( @@ -2395,9 +2344,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "aeZ" = ( @@ -2410,9 +2357,7 @@ /obj/structure/sign/warning/pods{ pixel_y = 30 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "afa" = ( @@ -2427,9 +2372,7 @@ id = "insaneflash"; pixel_y = 26 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "afb" = ( @@ -2442,9 +2385,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/prison) "afc" = ( @@ -2489,8 +2430,7 @@ pixel_y = 28 }, /obj/machinery/camera{ - c_tag = "Head of Security's Office"; - dir = 2 + c_tag = "Head of Security's Office" }, /turf/open/floor/plasteel/dark, /area/crew_quarters/heads/hos) @@ -2525,8 +2465,6 @@ pixel_x = -22 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = -29; pixel_y = 23 @@ -2844,9 +2782,7 @@ /turf/open/floor/plasteel, /area/security/prison) "afK" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/tile/red{ dir = 1 }, @@ -2865,9 +2801,7 @@ /turf/open/floor/plasteel, /area/security/prison) "afM" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/machinery/firealarm{ dir = 1; pixel_y = -24 @@ -2895,8 +2829,6 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -30 }, @@ -2941,9 +2873,7 @@ /turf/open/floor/plasteel, /area/security/prison) "afT" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/machinery/light, /obj/effect/turf_decal/tile/red{ dir = 1 @@ -2990,8 +2920,6 @@ /area/ai_monitored/security/armory) "afZ" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 24 }, @@ -3038,7 +2966,6 @@ icon_state = "secbot1"; idcheck = 1; name = "Sergeant-at-Armsky"; - on = 1; weaponscheck = 1 }, /turf/open/floor/plasteel/dark, @@ -3250,8 +3177,7 @@ icon_state = "4-8" }, /obj/machinery/camera{ - c_tag = "Fitness Room - Fore"; - dir = 2 + c_tag = "Fitness Room - Fore" }, /obj/machinery/airalarm{ pixel_y = 24 @@ -3282,9 +3208,9 @@ dir = 1 }, /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/fitness/recreation"; dir = 1; name = "Recreation Area APC"; - areastring = "/area/crew_quarters/fitness/recreation"; pixel_y = 24 }, /obj/structure/cable/yellow{ @@ -3307,8 +3233,7 @@ "agB" = ( /obj/machinery/power/solar_control{ id = "foreport"; - name = "Port Bow Solar Control"; - track = 0 + name = "Port Bow Solar Control" }, /obj/structure/cable{ icon_state = "0-4" @@ -3647,15 +3572,15 @@ icon_gib = "guard_dead"; icon_living = "guard"; icon_state = "guard"; + maxHealth = 250; max_co2 = 5; max_tox = 2; - maxHealth = 250; melee_damage_lower = 15; melee_damage_upper = 20; min_oxy = 5; + movement_type = 1; name = "Sergeant Araneus"; real_name = "Sergeant Araneus"; - movement_type = 1; response_help = "pets"; turns_per_move = 10 }, @@ -3695,16 +3620,12 @@ /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "ahh" = ( -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "ahi" = ( /obj/structure/chair, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "ahj" = ( @@ -3776,8 +3697,6 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, @@ -3926,9 +3845,8 @@ /area/ai_monitored/security/armory) "ahF" = ( /obj/machinery/power/apc/highcap/five_k{ - dir = 2; - name = "Armory APC"; areastring = "/area/ai_monitored/security/armory"; + name = "Armory APC"; pixel_x = 1; pixel_y = -24 }, @@ -4160,9 +4078,7 @@ dir = 1 }, /obj/machinery/door/window/eastright{ - base_state = "right"; dir = 8; - icon_state = "right"; name = "Fitness Ring" }, /turf/open/floor/plasteel/dark, @@ -4293,9 +4209,9 @@ /area/maintenance/disposal) "ail" = ( /obj/machinery/power/apc{ + areastring = "/area/maintenance/solars/port/fore"; dir = 8; name = "Port Bow Solar APC"; - areastring = "/area/maintenance/solars/port/fore"; pixel_x = -25; pixel_y = 3 }, @@ -4314,9 +4230,7 @@ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/solars/port/fore) "ain" = ( @@ -4458,8 +4372,7 @@ }, /obj/effect/landmark/blobstart, /obj/machinery/camera{ - c_tag = "Evidence Storage"; - dir = 2 + c_tag = "Evidence Storage" }, /obj/item/storage/secure/safe{ name = "evidence safe"; @@ -4647,9 +4560,7 @@ desc = "Whoever wears this makes the rules."; name = "referee suit" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "aiS" = ( @@ -5329,18 +5240,14 @@ /obj/structure/disposalpipe/segment{ dir = 6 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/disposal) "aki" = ( /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/disposal) "akj" = ( @@ -5350,9 +5257,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/disposal) "akk" = ( @@ -5480,8 +5385,6 @@ "aku" = ( /obj/structure/table, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 26 }, @@ -5723,8 +5626,6 @@ dir = 1 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 26 }, @@ -6027,9 +5928,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "alm" = ( @@ -6067,8 +5966,6 @@ dir = 1 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -28 }, @@ -6192,7 +6089,6 @@ /area/maintenance/disposal) "alB" = ( /obj/machinery/mineral/stacking_unit_console{ - dir = 2; machinedir = 8; pixel_x = 32 }, @@ -6312,9 +6208,7 @@ /area/security/brig) "alP" = ( /obj/machinery/door/window/westleft{ - base_state = "left"; dir = 4; - icon_state = "left"; name = "Infirmary" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -6567,9 +6461,9 @@ icon_state = "1-4" }, /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/security/warden"; dir = 8; name = "Brig Control APC"; - areastring = "/area/security/warden"; pixel_x = -26 }, /obj/structure/cable/yellow, @@ -6757,9 +6651,9 @@ req_access_txt = "1" }, /obj/machinery/power/apc{ + areastring = "/area/security/range"; dir = 4; name = "Shooting Range APC"; - areastring = "/area/security/range"; pixel_x = 24 }, /obj/structure/cable/yellow{ @@ -6778,9 +6672,7 @@ /area/maintenance/fore) "amu" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/fore) "amw" = ( @@ -6824,9 +6716,7 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "amD" = ( @@ -6838,13 +6728,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/closed/wall, /area/crew_quarters/fitness/recreation) -"amF" = ( -/obj/machinery/door/airlock/maintenance{ - name = "maintenance access"; - req_access_txt = "12" - }, -/turf/open/floor/plating, -/area/maintenance/starboard/fore) "amG" = ( /obj/machinery/light/small{ dir = 8 @@ -6954,7 +6837,6 @@ "amQ" = ( /obj/machinery/door/window/eastright{ base_state = "left"; - dir = 4; icon_state = "left"; name = "Danger: Conveyor Access"; req_access_txt = "12" @@ -7304,9 +7186,9 @@ /area/security/main) "anC" = ( /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/security/main"; dir = 4; name = "Security Office APC"; - areastring = "/area/security/main"; pixel_x = 24 }, /obj/structure/cable/yellow, @@ -7475,7 +7357,6 @@ /area/maintenance/disposal) "anY" = ( /obj/machinery/door/window/eastright{ - dir = 4; name = "Danger: Conveyor Access"; req_access_txt = "12" }, @@ -7953,9 +7834,8 @@ /area/maintenance/fore) "aoO" = ( /obj/machinery/power/apc{ - dir = 2; - name = "Disposal APC"; areastring = "/area/maintenance/disposal"; + name = "Disposal APC"; pixel_y = -24 }, /obj/structure/cable/yellow, @@ -7977,9 +7857,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -8051,9 +7929,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 8 }, @@ -8077,27 +7953,21 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "aoZ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "apa" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "apb" = ( @@ -8206,8 +8076,7 @@ "apn" = ( /obj/machinery/power/solar_control{ id = "forestarboard"; - name = "Starboard Bow Solar Control"; - track = 0 + name = "Starboard Bow Solar Control" }, /obj/structure/cable{ icon_state = "0-4" @@ -8243,9 +8112,7 @@ freq = 1400; location = "Disposals" }, -/obj/structure/plasticflaps{ - opacity = 0 - }, +/obj/structure/plasticflaps, /obj/machinery/door/window/northright{ dir = 2; name = "delivery door"; @@ -8433,8 +8300,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Warden's Office"; - dir = 2 + c_tag = "Warden's Office" }, /obj/structure/rack, /obj/item/storage/toolbox/mechanical{ @@ -8639,9 +8505,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/fitness/recreation) "aqj" = ( @@ -8671,8 +8535,6 @@ "aqk" = ( /obj/machinery/vending/coffee, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -28 }, @@ -8763,9 +8625,9 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ + areastring = "/area/engine/gravity_generator"; dir = 8; name = "Gravity Generator APC"; - areastring = "/area/engine/gravity_generator"; pixel_x = -25; pixel_y = 1 }, @@ -8852,8 +8714,6 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, @@ -9041,7 +8901,6 @@ }, /obj/machinery/computer/security/telescreen{ desc = "Used for watching Prison Wing holding areas."; - dir = 2; name = "Prison Monitor"; network = list("prison"); pixel_x = -30 @@ -9224,9 +9083,7 @@ /obj/structure/chair{ dir = 1 }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/landmark/start/security_officer, /obj/effect/turf_decal/tile/red, /obj/effect/turf_decal/tile/red{ @@ -9414,9 +9271,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/engine/gravity_generator) "arQ" = ( @@ -9428,9 +9283,7 @@ dir = 9 }, /obj/machinery/holopad, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/engine/gravity_generator) "arR" = ( @@ -9438,9 +9291,7 @@ dir = 1 }, /obj/machinery/power/terminal, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/engine/gravity_generator) "arS" = ( @@ -9459,9 +9310,9 @@ /area/engine/gravity_generator) "arT" = ( /obj/machinery/power/apc{ + areastring = "/area/maintenance/solars/starboard/fore"; dir = 8; name = "Starboard Bow Solar APC"; - areastring = "/area/maintenance/solars/starboard/fore"; pixel_x = -25; pixel_y = 3 }, @@ -9480,9 +9331,7 @@ icon_state = "2-4" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/solars/starboard/fore) "arV" = ( @@ -9500,9 +9349,7 @@ /obj/structure/cable/yellow{ icon_state = "2-4" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/port/fore) "arX" = ( @@ -10054,11 +9901,8 @@ }, /obj/structure/table/wood, /obj/item/radio/intercom{ - anyai = 1; - broadcasting = 0; freerange = 1; frequency = 1424; - listening = 1; name = "Interrogation Intercom"; pixel_y = -31 }, @@ -10170,9 +10014,7 @@ /obj/machinery/light/small{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "ata" = ( @@ -10214,9 +10056,7 @@ /area/maintenance/starboard/fore) "ate" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/starboard/fore) "atf" = ( @@ -10248,9 +10088,7 @@ icon_state = "1-8" }, /obj/structure/table, -/obj/item/paper/guides/jobs/engi/gravity_gen{ - layer = 3 - }, +/obj/item/paper/guides/jobs/engi/gravity_gen, /obj/item/pen/blue, /obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, @@ -10308,9 +10146,7 @@ /obj/machinery/door/poddoor/shutters{ id = "supplybridge" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/port/fore) "atr" = ( @@ -10335,9 +10171,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plating, /area/maintenance/port/fore) "atu" = ( @@ -10692,9 +10526,7 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "auk" = ( @@ -10993,9 +10825,9 @@ "auX" = ( /obj/machinery/photocopier, /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/heads/hos"; dir = 4; name = "Head of Security's Office APC"; - areastring = "/area/crew_quarters/heads/hos"; pixel_x = 24 }, /obj/structure/cable/yellow{ @@ -11070,8 +10902,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Brig - Hallway - Entrance"; - dir = 2 + c_tag = "Brig - Hallway - Entrance" }, /obj/effect/turf_decal/tile/red{ dir = 4 @@ -11090,8 +10921,6 @@ /area/security/brig) "avd" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 26 }, @@ -11209,9 +11038,7 @@ /obj/structure/extinguisher_cabinet{ pixel_x = 27 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "avo" = ( @@ -11228,9 +11055,7 @@ /area/crew_quarters/dorms) "avq" = ( /obj/item/cigbutt, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/starboard/fore) "avr" = ( @@ -11324,18 +11149,14 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/engine/gravity_generator) "avy" = ( /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/stripes/line{ dir = 6 }, @@ -11895,9 +11716,7 @@ c_tag = "Dormitories - Fore"; dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "awG" = ( @@ -11983,9 +11802,7 @@ /obj/structure/cable/yellow{ icon_state = "2-4" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/port/fore) "awR" = ( @@ -12004,9 +11821,7 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/port/fore) "awU" = ( @@ -12055,9 +11870,7 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/brig) "axc" = ( @@ -12093,9 +11906,7 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plasteel, /area/security/brig) "axf" = ( @@ -12126,17 +11937,13 @@ /turf/open/floor/plasteel, /area/security/brig) "axh" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/machinery/door_timer{ id = "Cell 3"; name = "Cell 3"; pixel_y = -32 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/brig) "axi" = ( @@ -12186,9 +11993,8 @@ dir = 4 }, /obj/machinery/power/apc/highcap/ten_k{ - dir = 2; - name = "Brig APC"; areastring = "/area/security/brig"; + name = "Brig APC"; pixel_x = 1; pixel_y = -24 }, @@ -12235,18 +12041,12 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/brig) "axq" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/brig) "axr" = ( @@ -12259,9 +12059,7 @@ req_access_txt = "1" }, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/brig) "axs" = ( @@ -12277,9 +12075,7 @@ c_tag = "Brig - Hallway - Starboard"; dir = 1 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/brig) "axt" = ( @@ -12290,18 +12086,14 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/brig) "axu" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/security/brig) "axv" = ( @@ -12346,7 +12138,6 @@ /obj/item/folder/red, /obj/item/taperecorder, /obj/item/radio/intercom{ - anyai = 1; broadcasting = 1; freerange = 1; frequency = 1424; @@ -12487,9 +12278,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -12710,9 +12499,9 @@ /area/security/nuke_storage) "ayr" = ( /obj/machinery/power/apc{ + areastring = "/area/security/nuke_storage"; dir = 1; name = "Vault APC"; - areastring = "/area/security/nuke_storage"; pixel_y = 25 }, /obj/structure/cable/yellow{ @@ -12980,9 +12769,7 @@ /obj/machinery/light/small{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "ayQ" = ( @@ -13140,9 +12927,9 @@ /area/quartermaster/miningoffice) "azn" = ( /obj/machinery/power/apc{ + areastring = "/area/quartermaster/miningoffice"; dir = 1; name = "Mining APC"; - areastring = "/area/quartermaster/miningoffice"; pixel_y = 24 }, /obj/structure/cable/yellow{ @@ -13551,9 +13338,9 @@ icon_state = "0-2" }, /obj/machinery/power/apc{ + areastring = "/area/maintenance/fore"; dir = 1; name = "Fore Maintenance APC"; - areastring = "/area/maintenance/fore"; pixel_y = 24 }, /turf/open/floor/plating, @@ -13623,8 +13410,6 @@ dir = 1 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 28 }, @@ -13673,9 +13458,7 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aAi" = ( @@ -13778,14 +13561,11 @@ /area/engine/engineering) "aAr" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, /obj/machinery/camera{ - c_tag = "Engineering - Fore"; - dir = 2 + c_tag = "Engineering - Fore" }, /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -13841,9 +13621,7 @@ pixel_y = 30 }, /obj/effect/decal/cleanable/cobweb, -/turf/open/floor/plasteel/cult{ - dir = 2 - }, +/turf/open/floor/plasteel/cult, /area/library) "aAA" = ( /obj/docking_port/stationary{ @@ -13852,8 +13630,8 @@ height = 5; id = "mining_home"; name = "mining shuttle bay"; - width = 7; - roundstart_template = /datum/map_template/shuttle/mining/box + roundstart_template = /datum/map_template/shuttle/mining/box; + width = 7 }, /turf/open/space/basic, /area/space) @@ -14039,8 +13817,8 @@ height = 5; id = "laborcamp_home"; name = "fore bay 1"; - width = 9; - roundstart_template = /datum/map_template/shuttle/labour/box + roundstart_template = /datum/map_template/shuttle/labour/box; + width = 9 }, /turf/open/space/basic, /area/space) @@ -14244,9 +14022,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/fore) "aBs" = ( @@ -14315,9 +14091,9 @@ dir = 1 }, /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/dorms"; dir = 1; name = "Dormitories APC"; - areastring = "/area/crew_quarters/dorms"; pixel_y = 24 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -14355,9 +14131,7 @@ /obj/structure/sign/warning/pods{ pixel_x = 30 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aBC" = ( @@ -14409,8 +14183,7 @@ /area/engine/engineering) "aBG" = ( /obj/machinery/camera{ - c_tag = "Engineering - Storage"; - dir = 2 + c_tag = "Engineering - Storage" }, /obj/machinery/suit_storage_unit/engine, /obj/effect/turf_decal/bot{ @@ -14644,8 +14417,8 @@ "aCg" = ( /obj/machinery/camera/motion{ c_tag = "Vault"; - network = list("vault"); - dir = 1 + dir = 1; + network = list("vault") }, /obj/machinery/light, /obj/structure/cable/yellow{ @@ -14814,9 +14587,9 @@ dir = 8 }, /obj/machinery/power/apc{ + areastring = "/area/security/detectives_office"; dir = 8; name = "Detective APC"; - areastring = "/area/security/detectives_office"; pixel_x = -24 }, /obj/structure/cable/yellow{ @@ -14955,9 +14728,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aCJ" = ( @@ -15118,8 +14889,7 @@ }, /obj/machinery/computer/shuttle/mining{ dir = 4; - req_access = null; - req_one_access = null + req_access = null }, /obj/effect/turf_decal/tile/brown{ dir = 1 @@ -15274,8 +15044,7 @@ pixel_y = 32 }, /obj/machinery/camera{ - c_tag = "Fore Primary Hallway Cells"; - dir = 2 + c_tag = "Fore Primary Hallway Cells" }, /obj/effect/turf_decal/tile/red{ dir = 1 @@ -15396,8 +15165,6 @@ dir = 8 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29; pixel_y = -2 @@ -15435,8 +15202,6 @@ "aDL" = ( /obj/machinery/light/small, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -26 }, @@ -15534,9 +15299,7 @@ /obj/structure/cable/yellow{ icon_state = "2-8" }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/structure/urinal{ pixel_y = 29 }, @@ -15861,9 +15624,9 @@ /area/quartermaster/warehouse) "aEE" = ( /obj/machinery/power/apc{ + areastring = "/area/quartermaster/warehouse"; dir = 4; name = "Warehouse APC"; - areastring = "/area/quartermaster/warehouse"; pixel_x = 27 }, /obj/structure/cable/yellow{ @@ -16030,7 +15793,6 @@ /obj/structure/table/reinforced, /obj/machinery/door/window/westleft{ base_state = "right"; - dir = 8; icon_state = "right"; name = "Outer Window" }, @@ -16128,9 +15890,8 @@ "aFe" = ( /obj/machinery/light/small, /obj/machinery/power/apc{ - dir = 2; - name = "Restrooms APC"; areastring = "/area/crew_quarters/toilet/restrooms"; + name = "Restrooms APC"; pixel_y = -26 }, /obj/structure/cable/yellow{ @@ -16214,9 +15975,7 @@ dir = 8; pixel_x = 28 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aFp" = ( @@ -16242,18 +16001,14 @@ /turf/open/floor/plasteel, /area/engine/engineering) "aFr" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/engine/engineering) "aFs" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/engine/engineering) "aFt" = ( @@ -16302,9 +16057,7 @@ /turf/open/floor/plating, /area/engine/engineering) "aFv" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/stripes/line{ dir = 8 }, @@ -16381,9 +16134,7 @@ /obj/item/folder, /obj/item/folder, /obj/effect/decal/cleanable/cobweb/cobweb2, -/turf/open/floor/plasteel/cult{ - dir = 2 - }, +/turf/open/floor/plasteel/cult, /area/library) "aFF" = ( /obj/structure/table, @@ -16391,7 +16142,6 @@ /obj/item/pen, /obj/machinery/requests_console{ department = "Mining"; - departmentType = 0; pixel_y = -30 }, /obj/effect/turf_decal/tile/brown{ @@ -16698,9 +16448,8 @@ dir = 4 }, /obj/machinery/power/apc/highcap/five_k{ - dir = 2; - name = "Fore Primary Hallway APC"; areastring = "/area/hallway/primary/fore"; + name = "Fore Primary Hallway APC"; pixel_y = -27 }, /obj/structure/cable/yellow, @@ -16724,8 +16473,6 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -26 }, @@ -16769,34 +16516,24 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aGm" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aGn" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aGo" = ( /obj/item/beacon, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aGp" = ( @@ -16991,9 +16728,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aGJ" = ( @@ -17005,9 +16740,7 @@ dir = 1; pixel_y = -22 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aGK" = ( @@ -17015,18 +16748,12 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aGL" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aGM" = ( @@ -17326,9 +17053,7 @@ /turf/open/floor/plasteel, /area/construction/storage/wing) "aHp" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/tile/brown{ dir = 8 }, @@ -17418,9 +17143,7 @@ /area/hallway/primary/fore) "aHB" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aHC" = ( @@ -17517,9 +17240,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aHQ" = ( @@ -17716,8 +17437,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Cargo Bay - Fore"; - dir = 2 + c_tag = "Cargo Bay - Fore" }, /obj/structure/sign/map/right{ desc = "A framed picture of the station. Clockwise from security at the top (red), you see engineering (yellow), science (purple), escape (red and white), medbay (green), arrivals (blue and white), and finally cargo (brown)."; @@ -17733,9 +17453,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable/yellow{ icon_state = "1-4" }, @@ -17770,9 +17488,7 @@ /obj/structure/disposalpipe/segment{ dir = 6 }, -/obj/effect/turf_decal/stripes/corner{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/corner, /turf/open/floor/plasteel, /area/quartermaster/storage) "aIp" = ( @@ -17785,9 +17501,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/quartermaster/storage) "aIq" = ( @@ -17853,9 +17567,8 @@ dir = 4 }, /obj/machinery/power/apc{ - dir = 2; - name = "Storage Wing APC"; areastring = "/area/construction/storage/wing"; + name = "Storage Wing APC"; pixel_y = -27 }, /obj/structure/cable/yellow{ @@ -17897,12 +17610,8 @@ /obj/structure/cable/yellow{ icon_state = "1-8" }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -26 }, @@ -18063,9 +17772,7 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aIL" = ( @@ -18085,8 +17792,6 @@ /area/security/courtroom) "aIN" = ( /obj/item/radio/intercom{ - broadcasting = 0; - listening = 1; name = "Station Intercom (General)"; pixel_y = 20 }, @@ -18118,8 +17823,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Courtroom"; - dir = 2 + c_tag = "Courtroom" }, /obj/effect/turf_decal/tile/blue{ dir = 1 @@ -18200,9 +17904,9 @@ icon_state = "0-2" }, /obj/machinery/power/apc{ + areastring = "/area/lawoffice"; dir = 1; name = "Law Office APC"; - areastring = "/area/lawoffice"; pixel_y = 24 }, /obj/item/twohanded/required/kirbyplants{ @@ -18222,9 +17926,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/fore) "aJa" = ( @@ -18295,9 +17997,7 @@ /area/crew_quarters/dorms) "aJg" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/dorms) "aJh" = ( @@ -18326,8 +18026,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Engineering - Secure Storage"; - dir = 2 + c_tag = "Engineering - Secure Storage" }, /turf/open/floor/plating, /area/engine/engineering) @@ -18545,9 +18244,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aJW" = ( @@ -18911,7 +18608,6 @@ /area/engine/engineering) "aKN" = ( /obj/machinery/door/poddoor{ - density = 1; id = "QMLoaddoor2"; name = "Supply Dock Loading Door" }, @@ -19215,8 +18911,8 @@ dir = 8 }, /obj/machinery/flasher{ - pixel_y = 24; - id = "AI" + id = "AI"; + pixel_y = 24 }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai_upload) @@ -19399,8 +19095,6 @@ /obj/machinery/atmospherics/components/unary/portables_connector/visible, /obj/machinery/portable_atmospherics/scrubber, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 26 }, @@ -19414,8 +19108,7 @@ /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk, /obj/machinery/camera{ - c_tag = "Locker Room Starboard"; - dir = 2 + c_tag = "Locker Room Starboard" }, /obj/structure/sign/warning/pods{ pixel_y = 30 @@ -19498,8 +19191,7 @@ "aLX" = ( /obj/machinery/door/firedoor/border_only/closed{ dir = 8; - name = "Animal Pen A"; - opacity = 1 + name = "Animal Pen A" }, /turf/open/floor/grass, /area/hydroponics/garden) @@ -19736,8 +19428,8 @@ /obj/effect/spawner/lootdrop/aimodule_neutral, /obj/item/aiModule/core/full/custom, /obj/machinery/flasher{ - pixel_y = 24; - id = "AI" + id = "AI"; + pixel_y = 24 }, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai_upload) @@ -19747,16 +19439,14 @@ "aMI" = ( /obj/structure/table, /obj/machinery/door/window{ - base_state = "left"; dir = 8; - icon_state = "left"; name = "High-Risk Modules"; req_access_txt = "20" }, /obj/structure/window/reinforced, /obj/machinery/flasher{ - pixel_y = 24; - id = "AI" + id = "AI"; + pixel_y = 24 }, /obj/effect/spawner/lootdrop/aimodule_harmful, /obj/item/aiModule/supplied/oxygen, @@ -19768,8 +19458,6 @@ "aMJ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = -29 }, @@ -19943,9 +19631,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/locker) "aNa" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -20182,7 +19868,6 @@ pixel_y = -5 }, /obj/machinery/button/door{ - dir = 2; id = "QMLoaddoor2"; layer = 4; name = "Loading Doors"; @@ -20233,9 +19918,7 @@ dir = 4 }, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/corner{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/corner, /turf/open/floor/plasteel, /area/quartermaster/storage) "aNL" = ( @@ -20290,16 +19973,14 @@ /turf/open/floor/plasteel, /area/quartermaster/qm) "aNP" = ( -/obj/machinery/camera/autoname{ - dir = 2 - }, +/obj/machinery/camera/autoname, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 }, /obj/machinery/power/apc{ + areastring = "/area/quartermaster/qm"; dir = 1; name = "Quartermaster's Office APC"; - areastring = "/area/quartermaster/qm"; pixel_y = 30 }, /obj/structure/cable/yellow{ @@ -20442,9 +20123,7 @@ dir = 8 }, /obj/machinery/door/window/westleft{ - base_state = "left"; dir = 2; - icon_state = "left"; layer = 3.1; name = "Cyborg Upload Console Window"; req_access_txt = "16" @@ -20664,9 +20343,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aOC" = ( @@ -20706,9 +20383,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/locker) "aOF" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/structure/disposalpipe/segment{ dir = 4 }, @@ -20812,9 +20487,9 @@ /area/hydroponics/garden) "aON" = ( /obj/machinery/power/apc{ + areastring = "/area/hydroponics/garden"; dir = 4; name = "Garden APC"; - areastring = "/area/hydroponics/garden"; pixel_x = 27; pixel_y = 2 }, @@ -20837,9 +20512,9 @@ /area/hydroponics/garden) "aOO" = ( /obj/machinery/power/apc/highcap/ten_k{ + areastring = "/area/engine/engineering"; dir = 8; name = "Engine Room APC"; - areastring = "/area/engine/engineering"; pixel_x = -26 }, /obj/structure/cable/yellow{ @@ -20884,8 +20559,6 @@ dir = 1 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -21079,9 +20752,7 @@ /obj/item/stack/packageWrap, /obj/item/stack/packageWrap, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/brown{ - dir = 2 - }, +/obj/effect/turf_decal/tile/brown, /turf/open/floor/plasteel, /area/storage/primary) "aPp" = ( @@ -21108,7 +20779,6 @@ }, /obj/machinery/requests_console{ department = "Tool Storage"; - departmentType = 0; pixel_x = 30 }, /obj/machinery/light{ @@ -21200,9 +20870,7 @@ c_tag = "Fore Primary Hallway Aft"; dir = 8 }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aPB" = ( @@ -21306,9 +20974,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aPN" = ( @@ -21349,8 +21015,6 @@ /area/hydroponics/garden) "aPR" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, @@ -21424,8 +21088,7 @@ pixel_y = 32 }, /obj/machinery/camera{ - c_tag = "Engineering - Power Monitoring"; - dir = 2 + c_tag = "Engineering - Power Monitoring" }, /obj/machinery/modular_computer/console/preset/engineering, /obj/effect/turf_decal/tile/neutral{ @@ -21491,7 +21154,6 @@ /area/engine/engineering) "aQg" = ( /obj/machinery/door/poddoor{ - density = 1; id = "QMLoaddoor"; name = "Supply Dock Loading Door" }, @@ -21674,9 +21336,8 @@ /area/ai_monitored/turret_protected/ai_upload) "aQA" = ( /obj/machinery/power/apc/highcap/five_k{ - dir = 2; - name = "Upload APC"; areastring = "/area/ai_monitored/turret_protected/ai_upload"; + name = "Upload APC"; pixel_y = -24 }, /obj/structure/cable/yellow{ @@ -21826,8 +21487,7 @@ icon_state = "4-8" }, /obj/machinery/camera{ - c_tag = "Crew Quarters Entrance"; - dir = 2 + c_tag = "Crew Quarters Entrance" }, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -21887,9 +21547,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aQU" = ( @@ -21961,9 +21619,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aRb" = ( @@ -22025,8 +21681,7 @@ "aRg" = ( /obj/machinery/door/firedoor/border_only/closed{ dir = 8; - name = "Animal Pen B"; - opacity = 1 + name = "Animal Pen B" }, /turf/open/floor/grass, /area/hydroponics/garden) @@ -22271,8 +21926,6 @@ dir = 1 }, /obj/item/radio/intercom{ - broadcasting = 0; - listening = 1; name = "Station Intercom (General)"; pixel_y = -28 }, @@ -22390,8 +22043,7 @@ "aRX" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/grunge{ - name = "Courtroom"; - opacity = 1 + name = "Courtroom" }, /turf/open/floor/plasteel/dark, /area/security/courtroom) @@ -22460,9 +22112,7 @@ pixel_x = 4; pixel_y = -2 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aSj" = ( @@ -22553,9 +22203,7 @@ "aSq" = ( /obj/machinery/power/terminal, /obj/structure/cable, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/engine/engineering) "aSr" = ( @@ -22732,9 +22380,8 @@ icon_state = "0-8" }, /obj/machinery/power/apc{ - dir = 2; - name = "Auxillary Base Construction APC"; areastring = "/area/construction/mining/aux_base"; + name = "Auxillary Base Construction APC"; pixel_y = -24 }, /obj/effect/turf_decal/tile/yellow, @@ -22775,9 +22422,7 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/port) "aSP" = ( @@ -22992,8 +22637,6 @@ /area/security/courtroom) "aTm" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -26 }, @@ -23046,18 +22689,14 @@ codes_txt = "patrol;next_patrol=14.3-Lockers-Dorms"; location = "14.2-Central-CrewQuarters" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aTt" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aTu" = ( @@ -23075,16 +22714,13 @@ dir = 4 }, /obj/machinery/power/apc{ - dir = 2; - name = "Locker Room APC"; areastring = "/area/crew_quarters/locker"; + name = "Locker Room APC"; pixel_x = -1; pixel_y = -26 }, /obj/structure/cable/yellow, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aTw" = ( @@ -23092,8 +22728,6 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -26 }, @@ -23101,9 +22735,7 @@ c_tag = "Locker Room Port"; dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aTx" = ( @@ -23111,9 +22743,7 @@ dir = 4 }, /obj/machinery/light, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aTy" = ( @@ -23124,9 +22754,7 @@ dir = 1; pixel_y = -24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aTz" = ( @@ -23137,27 +22765,21 @@ /obj/machinery/newscaster{ pixel_y = -32 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aTA" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aTB" = ( /obj/structure/extinguisher_cabinet{ pixel_x = 27 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aTC" = ( @@ -23228,26 +22850,20 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/engine/engineering) "aTH" = ( /obj/structure/disposalpipe/segment{ dir = 9 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel, /area/engine/engineering) "aTI" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -23258,9 +22874,7 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 10 }, @@ -23316,7 +22930,6 @@ dir = 8 }, /obj/machinery/door/window{ - dir = 2; name = "MiniSat Walkway Access" }, /turf/open/floor/plasteel/dark, @@ -23398,7 +23011,6 @@ }, /obj/machinery/door/window{ base_state = "right"; - dir = 2; icon_state = "right"; name = "MiniSat Walkway Access" }, @@ -23489,9 +23101,9 @@ /area/security/checkpoint/supply) "aUk" = ( /obj/machinery/power/apc{ + areastring = "/area/security/checkpoint/supply"; dir = 1; name = "Security Post - Cargo Bay APC"; - areastring = "/area/security/checkpoint/supply"; pixel_x = 1; pixel_y = 24 }, @@ -23656,9 +23268,8 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ - dir = 2; - name = "AI Upload Access APC"; areastring = "/area/ai_monitored/turret_protected/ai_upload_foyer"; + name = "AI Upload Access APC"; pixel_y = -27 }, /obj/machinery/light/small{ @@ -23700,6 +23311,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/ai_upload_foyer) "aUA" = ( @@ -23736,7 +23348,6 @@ dir = 4 }, /obj/structure/sign/directions/command{ - dir = 2; pixel_y = -8 }, /turf/closed/wall/r_wall, @@ -23768,9 +23379,7 @@ /obj/machinery/door/airlock/public/glass{ name = "Fore Primary Hallway" }, -/obj/effect/turf_decal/tile/red{ - dir = 2 - }, +/obj/effect/turf_decal/tile/red, /turf/open/floor/plasteel, /area/hallway/primary/fore) "aUF" = ( @@ -23785,9 +23394,8 @@ /area/security/courtroom) "aUG" = ( /obj/machinery/power/apc{ - dir = 2; - name = "Courtroom APC"; areastring = "/area/security/courtroom"; + name = "Courtroom APC"; pixel_x = 1; pixel_y = -24 }, @@ -23852,9 +23460,7 @@ dir = 8; pixel_x = 24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/locker) "aUM" = ( @@ -23995,9 +23601,7 @@ "aUX" = ( /obj/structure/closet/secure_closet/personal, /obj/item/clothing/under/assistantformal, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/item/clothing/suit/hooded/wintercoat, /obj/item/clothing/shoes/winterboots, /obj/effect/turf_decal/tile/neutral{ @@ -24032,7 +23636,6 @@ /area/engine/engineering) "aVa" = ( /obj/machinery/requests_console{ - announcementConsole = 0; department = "Engineering"; departmentType = 4; name = "Engineering RC" @@ -24115,7 +23718,6 @@ /area/ai_monitored/turret_protected/ai) "aVn" = ( /obj/structure/showcase/cyborg/old{ - dir = 2; pixel_y = 20 }, /turf/open/floor/plasteel/dark, @@ -24123,11 +23725,9 @@ "aVp" = ( /obj/machinery/camera{ c_tag = "AI Chamber - Fore"; - dir = 2; network = list("aicore") }, /obj/structure/showcase/cyborg/old{ - dir = 2; pixel_y = 20 }, /obj/structure/cable{ @@ -24170,8 +23770,6 @@ /area/hallway/secondary/entry) "aVv" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -24191,8 +23789,7 @@ "aVx" = ( /obj/structure/chair, /obj/machinery/camera{ - c_tag = "Arrivals - Fore Arm - Far"; - dir = 2 + c_tag = "Arrivals - Fore Arm - Far" }, /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -24240,9 +23837,7 @@ /obj/machinery/light{ dir = 1 }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable/yellow{ icon_state = "4-8" }, @@ -24550,8 +24145,7 @@ /area/hallway/primary/central) "aWd" = ( /obj/machinery/camera{ - c_tag = "Central Primary Hallway - Fore"; - dir = 2 + c_tag = "Central Primary Hallway - Fore" }, /obj/effect/turf_decal/tile/red{ dir = 1 @@ -24623,8 +24217,6 @@ icon_state = "plant-16" }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -24644,8 +24236,7 @@ }, /obj/machinery/door/firedoor, /obj/machinery/door/airlock/grunge{ - name = "Courtroom"; - opacity = 1 + name = "Courtroom" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/dark, @@ -24961,9 +24552,7 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, -/obj/effect/turf_decal/stripes/corner{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/corner, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "aWZ" = ( @@ -25273,9 +24862,7 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -25330,8 +24917,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Central Primary Hallway - Fore - AI Upload"; - dir = 2 + c_tag = "Central Primary Hallway - Fore - AI Upload" }, /obj/structure/sign/warning/securearea{ desc = "A warning sign which reads 'HIGH-POWER TURRETS AHEAD'."; @@ -25349,8 +24935,6 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -25372,9 +24956,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "aXH" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/machinery/status_display/ai{ pixel_y = 32 }, @@ -25448,9 +25030,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "aXO" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/plaque{ icon_state = "L9" }, @@ -25499,9 +25079,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "aXU" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable/yellow{ icon_state = "1-2" }, @@ -25534,9 +25112,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "aXX" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 4 }, @@ -25694,8 +25270,6 @@ /obj/item/assembly/flash/handheld, /obj/item/assembly/flash/handheld, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 28 }, @@ -25709,8 +25283,6 @@ /area/storage/tech) "aYo" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = -29 }, @@ -25745,8 +25317,7 @@ pixel_y = 30 }, /obj/machinery/camera{ - c_tag = "Chief Engineer's Office"; - dir = 2 + c_tag = "Chief Engineer's Office" }, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -25763,9 +25334,9 @@ "aYr" = ( /obj/structure/disposalpipe/segment, /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/heads/chief"; dir = 4; name = "CE Office APC"; - areastring = "/area/crew_quarters/heads/chief"; pixel_x = 28 }, /obj/structure/cable/yellow, @@ -25803,8 +25374,6 @@ /area/engine/engineering) "aYt" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, @@ -25982,9 +25551,7 @@ /area/quartermaster/storage) "aYO" = ( /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/corner{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/corner, /turf/open/floor/plasteel, /area/quartermaster/storage) "aYP" = ( @@ -25992,17 +25559,13 @@ c_tag = "Cargo Bay - Aft"; dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/quartermaster/storage) "aYQ" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/quartermaster/storage) "aYR" = ( @@ -26276,9 +25839,9 @@ /area/storage/tech) "aZx" = ( /obj/machinery/power/apc{ + areastring = "/area/storage/tech"; dir = 8; name = "Tech Storage APC"; - areastring = "/area/storage/tech"; pixel_x = -27 }, /obj/structure/cable/yellow{ @@ -26398,9 +25961,7 @@ "aZD" = ( /obj/structure/table/reinforced, /obj/item/flashlight/lamp, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/crew_quarters/heads/chief) "aZE" = ( @@ -26560,7 +26121,6 @@ "aZQ" = ( /obj/effect/landmark/start/ai/secondary, /obj/item/radio/intercom{ - anyai = 1; freerange = 1; listening = 0; name = "Custom Channel"; @@ -26568,15 +26128,11 @@ pixel_y = 22 }, /obj/item/radio/intercom{ - broadcasting = 0; freerange = 1; - listening = 1; name = "Common Channel"; pixel_x = -27 }, /obj/item/radio/intercom{ - anyai = 1; - broadcasting = 0; freerange = 1; frequency = 1447; name = "Private Channel"; @@ -26586,10 +26142,10 @@ /obj/machinery/door/window{ base_state = "rightsecure"; dir = 4; - obj_integrity = 300; icon_state = "rightsecure"; layer = 4.1; name = "Secondary AI Core Access"; + obj_integrity = 300; pixel_x = 4; req_access_txt = "16" }, @@ -26642,14 +26198,13 @@ /obj/machinery/door/window{ base_state = "rightsecure"; dir = 4; - obj_integrity = 300; icon_state = "rightsecure"; name = "Primary AI Core Access"; + obj_integrity = 300; req_access_txt = "16" }, /obj/machinery/camera{ c_tag = "AI Chamber - Core"; - dir = 2; network = list("aicore") }, /obj/effect/turf_decal/tile/neutral{ @@ -26696,7 +26251,6 @@ "aZY" = ( /obj/effect/landmark/start/ai/secondary, /obj/item/radio/intercom{ - anyai = 1; freerange = 1; listening = 0; name = "Custom Channel"; @@ -26704,15 +26258,11 @@ pixel_y = 22 }, /obj/item/radio/intercom{ - broadcasting = 0; freerange = 1; - listening = 1; name = "Common Channel"; pixel_x = 27 }, /obj/item/radio/intercom{ - anyai = 1; - broadcasting = 0; freerange = 1; frequency = 1447; name = "Private Channel"; @@ -26722,19 +26272,17 @@ /obj/machinery/door/window{ base_state = "leftsecure"; dir = 8; - obj_integrity = 300; icon_state = "leftsecure"; layer = 4.1; name = "Tertiary AI Core Access"; + obj_integrity = 300; pixel_x = -3; req_access_txt = "16" }, /turf/open/floor/circuit/green, /area/ai_monitored/turret_protected/ai) "aZZ" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/hallway/secondary/entry) "baa" = ( @@ -26841,8 +26389,6 @@ /area/maintenance/port/fore) "bal" = ( /obj/item/radio/intercom{ - broadcasting = 0; - listening = 1; name = "Station Intercom (General)"; pixel_y = -28 }, @@ -26874,9 +26420,7 @@ pixel_x = -8; pixel_y = -2 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/quartermaster/storage) "bap" = ( @@ -26907,17 +26451,14 @@ pixel_x = 4; pixel_y = 3 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/quartermaster/storage) "baq" = ( /obj/structure/rack, /obj/machinery/power/apc{ - dir = 2; - name = "Cargo Bay APC"; areastring = "/area/quartermaster/storage"; + name = "Cargo Bay APC"; pixel_x = 1; pixel_y = -24 }, @@ -26928,15 +26469,11 @@ /obj/item/screwdriver{ pixel_y = 10 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/quartermaster/storage) "bar" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/vending/wardrobe/cargo_wardrobe, /turf/open/floor/plasteel, /area/quartermaster/storage) @@ -27038,7 +26575,6 @@ /area/hallway/primary/port) "baB" = ( /obj/machinery/firealarm{ - dir = 2; pixel_y = 24 }, /obj/effect/turf_decal/tile/brown{ @@ -27112,9 +26648,7 @@ /obj/structure/disposalpipe/segment{ dir = 6 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /obj/structure/sign/departments/custodian{ pixel_x = 32; pixel_y = -32 @@ -27128,25 +26662,18 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "baJ" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /mob/living/simple_animal/bot/cleanbot{ auto_patrol = 1; icon_state = "cleanbot1"; - mode = 0; name = "Mopficcer Sweepsky" }, /turf/open/floor/plasteel, @@ -27159,9 +26686,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "baL" = ( @@ -27175,9 +26700,7 @@ /obj/structure/extinguisher_cabinet{ pixel_y = -30 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "baM" = ( @@ -27191,21 +26714,15 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "baN" = ( /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "baO" = ( @@ -27219,9 +26736,7 @@ /obj/structure/disposalpipe/segment{ dir = 10 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "baP" = ( @@ -27229,30 +26744,20 @@ dir = 1; pixel_y = -24 }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "baQ" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "baR" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "baS" = ( @@ -27322,9 +26827,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "baY" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/structure/extinguisher_cabinet{ pixel_y = -30 }, @@ -27338,8 +26841,6 @@ dir = 1 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = -27; pixel_y = -29 @@ -27385,9 +26886,9 @@ /area/storage/tools) "bbd" = ( /obj/machinery/power/apc{ + areastring = "/area/storage/tools"; dir = 1; name = "Auxiliary Tool Storage APC"; - areastring = "/area/storage/tools"; pixel_y = 24 }, /obj/structure/cable/yellow{ @@ -27419,8 +26920,6 @@ "bbf" = ( /obj/structure/closet/toolcloset, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 28 }, @@ -27481,8 +26980,6 @@ dir = 8 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, @@ -27860,7 +27357,6 @@ /obj/structure/plasticflaps/opaque, /obj/machinery/conveyor{ backwards = 1; - dir = 2; forwards = 2; id = "packageSort2" }, @@ -27875,9 +27371,9 @@ /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/power/apc{ + areastring = "/area/quartermaster/office"; dir = 8; name = "Cargo Office APC"; - areastring = "/area/quartermaster/office"; pixel_x = -24 }, /obj/structure/cable/yellow{ @@ -27944,7 +27440,6 @@ /obj/structure/table/reinforced, /obj/machinery/door/firedoor, /obj/machinery/door/window/westleft{ - dir = 8; name = "Cargo Desk"; req_access_txt = "50" }, @@ -27991,8 +27486,6 @@ "bcb" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = -29 }, @@ -28007,9 +27500,7 @@ "bcc" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bcd" = ( @@ -28369,9 +27860,9 @@ /area/engine/engineering) "bcL" = ( /obj/machinery/power/apc{ + areastring = "/area/security/checkpoint/engineering"; dir = 8; name = "Engineering Security APC"; - areastring = "/area/security/checkpoint/engineering"; pixel_x = -24 }, /obj/structure/cable/yellow{ @@ -28478,9 +27969,9 @@ /area/security/checkpoint/customs) "bcY" = ( /obj/machinery/power/apc{ + areastring = "/area/security/checkpoint/customs"; dir = 1; name = "Customs APC"; - areastring = "/area/security/checkpoint/customs"; pixel_y = 24 }, /obj/structure/cable/yellow{ @@ -28499,7 +27990,6 @@ /area/security/checkpoint/customs) "bcZ" = ( /obj/item/radio/intercom{ - broadcasting = 0; name = "Station Intercom (General)"; pixel_y = 20 }, @@ -28523,8 +28013,7 @@ pixel_y = 30 }, /obj/machinery/camera{ - c_tag = "Customs Checkpoint"; - dir = 2 + c_tag = "Customs Checkpoint" }, /obj/effect/turf_decal/tile/red{ dir = 1 @@ -28622,9 +28111,7 @@ dir = 4; id = "packageSort2" }, -/obj/structure/plasticflaps{ - opacity = 0 - }, +/obj/structure/plasticflaps, /turf/open/floor/plating, /area/quartermaster/sorting) "bdk" = ( @@ -28776,9 +28263,7 @@ dir = 8; pixel_x = 24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bdA" = ( @@ -29079,8 +28564,6 @@ dir = 1 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -28 }, @@ -29171,9 +28654,7 @@ /turf/open/floor/plasteel/dark, /area/crew_quarters/heads/chief) "bek" = ( -/obj/structure/closet/secure_closet/engineering_chief{ - req_access_txt = "0" - }, +/obj/structure/closet/secure_closet/engineering_chief, /obj/structure/cable/yellow{ icon_state = "1-2" }, @@ -29323,9 +28804,9 @@ /area/ai_monitored/turret_protected/ai) "bew" = ( /obj/machinery/power/apc{ + areastring = "/area/ai_monitored/turret_protected/ai"; dir = 1; name = "AI Chamber APC"; - areastring = "/area/ai_monitored/turret_protected/ai"; pixel_y = 24 }, /obj/structure/cable{ @@ -29593,9 +29074,7 @@ /area/hallway/primary/central) "bfi" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bfj" = ( @@ -29845,7 +29324,6 @@ dir = 4 }, /obj/structure/sign/directions/command{ - dir = 2; pixel_y = -8 }, /turf/closed/wall/r_wall, @@ -30229,7 +29707,6 @@ /obj/item/paper, /obj/structure/table/reinforced, /obj/machinery/door/window/brigdoor{ - dir = 2; name = "Arrivals Security Checkpoint"; pixel_y = -8; req_access_txt = "1" @@ -30300,9 +29777,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/port/fore) "bgD" = ( @@ -30364,7 +29839,6 @@ /area/quartermaster/sorting) "bgK" = ( /obj/machinery/firealarm{ - dir = 2; pixel_y = 24 }, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ @@ -30409,9 +29883,7 @@ /turf/open/floor/plasteel, /area/quartermaster/sorting) "bgO" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable/yellow{ icon_state = "4-8" }, @@ -30546,9 +30018,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/port) "bgY" = ( -/obj/effect/turf_decal/tile/brown{ - dir = 2 - }, +/obj/effect/turf_decal/tile/brown, /turf/open/floor/plasteel, /area/hallway/primary/port) "bgZ" = ( @@ -30561,9 +30031,9 @@ /area/hallway/primary/port) "bha" = ( /obj/machinery/power/apc{ + areastring = "/area/janitor"; dir = 8; name = "Custodial Closet APC"; - areastring = "/area/janitor"; pixel_x = -24 }, /obj/structure/table, @@ -30615,9 +30085,9 @@ "bhf" = ( /obj/effect/landmark/blobstart, /obj/machinery/power/apc{ + areastring = "/area/maintenance/central"; dir = 4; name = "Central Maintenance APC"; - areastring = "/area/maintenance/central"; pixel_x = 26 }, /obj/structure/cable/yellow, @@ -30676,8 +30146,7 @@ pixel_y = 4 }, /obj/machinery/camera{ - c_tag = "Bridge - Central"; - dir = 2 + c_tag = "Bridge - Central" }, /obj/structure/table/glass, /obj/effect/turf_decal/tile/brown{ @@ -30906,9 +30375,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/starboard) "bhF" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/tile/yellow{ dir = 1 }, @@ -30941,8 +30408,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Starboard Primary Hallway - Tech Storage"; - dir = 2 + c_tag = "Starboard Primary Hallway - Tech Storage" }, /obj/effect/turf_decal/tile/yellow{ dir = 1 @@ -30950,9 +30416,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/starboard) "bhJ" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable/yellow{ icon_state = "1-2" }, @@ -31036,9 +30500,9 @@ dir = 4 }, /obj/machinery/power/apc{ + areastring = "/area/hallway/primary/starboard"; dir = 1; name = "Starboard Hallway APC"; - areastring = "/area/hallway/primary/starboard"; pixel_y = 26 }, /obj/structure/cable/yellow{ @@ -31174,8 +30638,6 @@ /area/engine/break_room) "bia" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -31979,9 +31441,7 @@ /obj/structure/disposalpipe/segment{ dir = 9 }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/structure/cable/yellow{ icon_state = "4-8" }, @@ -32129,8 +31589,6 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -32166,9 +31624,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/port) "bke" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/sign/map/left{ desc = "A framed picture of the station. Clockwise from security at the top (red), you see engineering (yellow), science (purple), escape (red and white), medbay (green), arrivals (blue and white), and finally cargo (brown)."; icon_state = "map-left-MS"; @@ -32249,8 +31705,6 @@ "bkk" = ( /obj/structure/filingcabinet/filingcabinet, /obj/item/radio/intercom{ - broadcasting = 0; - listening = 1; name = "Station Intercom (General)"; pixel_y = -28 }, @@ -32324,9 +31778,9 @@ }, /obj/item/hand_labeler, /obj/machinery/power/apc{ + areastring = "/area/quartermaster/sorting"; dir = 4; name = "Delivery Office APC"; - areastring = "/area/quartermaster/sorting"; pixel_x = 26 }, /obj/structure/cable/yellow{ @@ -32385,8 +31839,6 @@ pixel_x = 28 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -28 }, @@ -32430,9 +31882,7 @@ /obj/structure/cable/yellow{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/brown{ - dir = 2 - }, +/obj/effect/turf_decal/tile/brown, /turf/open/floor/plasteel, /area/hallway/primary/port) "bkv" = ( @@ -32472,8 +31922,6 @@ /obj/structure/table, /obj/item/toner, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 30 }, @@ -32497,9 +31945,7 @@ "bky" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bkz" = ( @@ -32589,9 +32035,7 @@ /obj/structure/cable/yellow{ icon_state = "2-4" }, -/obj/machinery/computer/security/mining{ - network = list("mine","auxbase") - }, +/obj/machinery/computer/security/mining, /obj/machinery/keycard_auth{ pixel_y = 24 }, @@ -32652,9 +32096,7 @@ /obj/structure/toilet{ pixel_y = 13 }, -/obj/machinery/light{ - dir = 2 - }, +/obj/machinery/light, /obj/effect/landmark/start/captain, /obj/machinery/light_switch{ pixel_y = -25 @@ -32720,9 +32162,7 @@ dir = 4 }, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/yellow{ - dir = 2 - }, +/obj/effect/turf_decal/tile/yellow, /turf/open/floor/plasteel, /area/hallway/primary/central) "bkT" = ( @@ -32760,9 +32200,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/starboard) "bkW" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, @@ -32815,9 +32253,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/starboard) "blb" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/machinery/firealarm{ dir = 1; pixel_y = -24 @@ -33068,7 +32504,6 @@ /area/ai_monitored/turret_protected/ai) "blF" = ( /obj/structure/showcase/cyborg/old{ - dir = 2; pixel_y = 20 }, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ @@ -33077,20 +32512,22 @@ /obj/effect/turf_decal/tile/blue{ dir = 1 }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "blG" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "blH" = ( /obj/structure/showcase/cyborg/old{ - dir = 2; pixel_y = 20 }, /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "blI" = ( @@ -33162,7 +32599,6 @@ pixel_y = 26 }, /obj/machinery/atmospherics/components/unary/portables_connector/visible{ - dir = 2; name = "Auxiliary MiniSat Distribution Port" }, /obj/machinery/portable_atmospherics/canister/air, @@ -33411,7 +32847,6 @@ dir = 4 }, /obj/structure/sign/directions/command{ - dir = 2; pixel_y = -8 }, /turf/closed/wall/r_wall, @@ -33425,9 +32860,7 @@ dir = 8; pixel_x = 24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bmo" = ( @@ -33573,7 +33006,6 @@ icon_state = "4-8" }, /obj/machinery/door/window/brigdoor{ - dir = 2; name = "Command Desk"; req_access_txt = "19" }, @@ -33673,9 +33105,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/yellow{ - dir = 2 - }, +/obj/effect/turf_decal/tile/yellow, /turf/open/floor/plasteel, /area/hallway/primary/central) "bmL" = ( @@ -33818,9 +33248,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel, /area/engine/break_room) "bnb" = ( @@ -34044,8 +33472,6 @@ "bny" = ( /obj/machinery/turretid{ control_area = "/area/ai_monitored/turret_protected/aisat_interior"; - enabled = 1; - icon_state = "control_standby"; name = "Antechamber Turret Control"; pixel_x = 30; req_access_txt = "65" @@ -34089,6 +33515,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 1 }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "bnC" = ( @@ -34107,13 +33534,14 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "bnE" = ( /obj/machinery/power/apc{ + areastring = "/area/ai_monitored/turret_protected/aisat_interior"; dir = 4; name = "MiniSat Antechamber APC"; - areastring = "/area/ai_monitored/turret_protected/aisat_interior"; pixel_x = 29 }, /obj/structure/cable/yellow{ @@ -34319,9 +33747,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/port) "bnY" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -34335,8 +33761,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Port Primary Hallway - Middle"; - dir = 2 + c_tag = "Port Primary Hallway - Middle" }, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -34355,9 +33780,9 @@ /area/hallway/primary/port) "bob" = ( /obj/machinery/power/apc{ + areastring = "/area/hallway/primary/port"; dir = 1; name = "Port Hallway APC"; - areastring = "/area/hallway/primary/port"; pixel_x = -1; pixel_y = 26 }, @@ -34387,8 +33812,6 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -34421,9 +33844,7 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/tile/brown{ dir = 4 }, @@ -34512,9 +33933,9 @@ /area/crew_quarters/heads/hop) "bop" = ( /obj/machinery/power/apc/highcap/ten_k{ + areastring = "/area/bridge"; dir = 8; name = "Bridge APC"; - areastring = "/area/bridge"; pixel_x = -27 }, /obj/structure/cable/yellow, @@ -34772,8 +34193,7 @@ /obj/item/stack/packageWrap, /obj/item/gun/ballistic/revolver/doublebarrel, /obj/machinery/camera{ - c_tag = "Bar - Backroom"; - dir = 2 + c_tag = "Bar - Backroom" }, /obj/structure/sink/kitchen{ pixel_y = 28 @@ -34788,9 +34208,6 @@ /area/crew_quarters/dorms) "boT" = ( /obj/machinery/door/window/southleft{ - base_state = "left"; - dir = 2; - icon_state = "left"; name = "Bar Delivery"; req_access_txt = "25" }, @@ -35372,9 +34789,9 @@ /area/hallway/secondary/entry) "bqd" = ( /obj/machinery/power/apc{ + areastring = "/area/hallway/secondary/entry"; dir = 4; name = "Arrivals APC"; - areastring = "/area/hallway/secondary/entry"; pixel_x = 24 }, /obj/structure/cable/yellow{ @@ -35467,9 +34884,9 @@ /obj/machinery/door/window{ base_state = "leftsecure"; dir = 8; - obj_integrity = 300; icon_state = "leftsecure"; name = "Primary AI Core Access"; + obj_integrity = 300; req_access_txt = "16" }, /obj/machinery/newscaster/security_unit{ @@ -35629,9 +35046,7 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bqB" = ( @@ -35649,7 +35064,6 @@ icon_state = "1-2" }, /obj/machinery/door/window{ - dir = 2; name = "HoP's Desk"; req_access_txt = "57" }, @@ -35667,8 +35081,6 @@ req_access_txt = "57" }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -35776,8 +35188,6 @@ /area/bridge) "bqP" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -29 }, @@ -35856,9 +35266,9 @@ /obj/structure/table/wood, /obj/item/book/manual/wiki/security_space_law, /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/heads/captain/private"; dir = 8; name = "Captain's Quarters APC"; - areastring = "/area/crew_quarters/heads/captain/private"; pixel_x = -24 }, /obj/structure/cable/yellow{ @@ -35937,9 +35347,9 @@ "brd" = ( /obj/structure/table, /obj/machinery/power/apc{ + areastring = "/area/storage/art"; dir = 8; name = "Art Storage APC"; - areastring = "/area/storage/art"; pixel_x = -25 }, /obj/structure/cable/yellow{ @@ -36003,8 +35413,6 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -30 }, @@ -36101,9 +35509,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plating, /area/maintenance/starboard) "brt" = ( @@ -36192,9 +35598,7 @@ /obj/structure/sign/warning/securearea{ pixel_x = 32 }, -/turf/open/floor/plasteel/dark/corner{ - dir = 2 - }, +/turf/open/floor/plasteel/dark/corner, /area/hallway/primary/starboard) "brA" = ( /obj/machinery/vending/coffee, @@ -36248,9 +35652,8 @@ dir = 4 }, /obj/machinery/power/apc{ - dir = 2; - name = "Engineering Foyer APC"; areastring = "/area/engine/break_room"; + name = "Engineering Foyer APC"; pixel_x = -1; pixel_y = -26 }, @@ -36392,9 +35795,8 @@ network = list("minisat") }, /obj/machinery/power/apc{ - dir = 2; - name = "MiniSat Exterior APC"; areastring = "/area/aisat"; + name = "MiniSat Exterior APC"; pixel_y = -24 }, /obj/structure/cable/yellow{ @@ -36418,7 +35820,6 @@ /area/aisat) "brS" = ( /obj/machinery/door/window{ - dir = 2; name = "MiniSat Walkway Access" }, /obj/machinery/atmospherics/pipe/manifold4w/supply/hidden, @@ -36477,9 +35878,7 @@ /obj/machinery/status_display/ai{ pixel_y = 32 }, -/obj/machinery/porta_turret/ai{ - dir = 2 - }, +/obj/machinery/porta_turret/ai, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, @@ -36507,9 +35906,8 @@ dir = 4 }, /obj/machinery/power/apc/highcap/five_k{ - dir = 2; - name = "MiniSat Foyer APC"; areastring = "/area/ai_monitored/turret_protected/aisat/foyer"; + name = "MiniSat Foyer APC"; pixel_y = -29 }, /obj/structure/cable/yellow, @@ -36572,9 +35970,7 @@ /obj/machinery/status_display{ pixel_y = 32 }, -/obj/machinery/porta_turret/ai{ - dir = 2 - }, +/obj/machinery/porta_turret/ai, /obj/machinery/computer/security/telescreen/minisat{ dir = 8; pixel_x = 28 @@ -36749,15 +36145,11 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/port) "bsw" = ( /obj/item/radio/intercom{ - broadcasting = 0; - listening = 1; name = "Station Intercom (General)"; pixel_y = -28 }, @@ -36789,9 +36181,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/port) "bsz" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 8 }, @@ -36881,9 +36271,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/port) "bsI" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/structure/extinguisher_cabinet{ pixel_y = -30 }, @@ -37383,8 +36771,6 @@ /area/engine/break_room) "btE" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -28 }, @@ -37426,9 +36812,9 @@ icon_state = "0-2" }, /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/heads/hop"; dir = 1; name = "Head of Personnel APC"; - areastring = "/area/crew_quarters/heads/hop"; pixel_y = 24 }, /turf/open/floor/carpet, @@ -37701,9 +37087,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bum" = ( @@ -38035,9 +37419,7 @@ /turf/open/floor/plating, /area/maintenance/starboard) "buZ" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, @@ -38089,23 +37471,18 @@ /area/maintenance/starboard) "bvf" = ( /obj/item/radio/intercom{ - broadcasting = 0; freerange = 1; - listening = 1; name = "Common Channel"; pixel_x = -27; pixel_y = -7 }, /obj/item/radio/intercom{ - anyai = 1; freerange = 1; listening = 0; name = "Custom Channel"; pixel_y = -27 }, /obj/item/radio/intercom{ - anyai = 1; - broadcasting = 0; freerange = 1; frequency = 1447; name = "Private Channel"; @@ -38211,9 +37588,7 @@ c_tag = "Engineering - Transit Tube Access"; dir = 8 }, -/obj/effect/turf_decal/stripes/corner{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/corner, /turf/open/floor/plasteel/dark, /area/engine/break_room) "bvq" = ( @@ -38279,7 +37654,6 @@ "bvw" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/showcase/cyborg/old{ - dir = 2; pixel_y = 20 }, /turf/open/floor/plasteel/grimy, @@ -38296,7 +37670,6 @@ pixel_y = 28 }, /obj/structure/showcase/cyborg/old{ - dir = 2; pixel_y = 20 }, /turf/open/floor/plasteel/grimy, @@ -38416,9 +37789,7 @@ /obj/structure/cable/yellow{ icon_state = "1-8" }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/structure/cable/yellow{ icon_state = "1-2" }, @@ -38598,9 +37969,7 @@ /obj/machinery/computer/security/telescreen/entertainment{ pixel_y = 30 }, -/turf/open/floor/plasteel/cult{ - dir = 2 - }, +/turf/open/floor/plasteel/cult, /area/library) "bwg" = ( /obj/structure/table/wood, @@ -38609,9 +37978,7 @@ }, /obj/item/folder, /obj/item/folder, -/turf/open/floor/plasteel/cult{ - dir = 2 - }, +/turf/open/floor/plasteel/cult, /area/library) "bwh" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -38762,8 +38129,7 @@ /area/bridge) "bwv" = ( /obj/machinery/camera{ - c_tag = "Council Chamber"; - dir = 2 + c_tag = "Council Chamber" }, /obj/machinery/light{ dir = 1 @@ -38853,9 +38219,7 @@ /turf/open/floor/carpet, /area/crew_quarters/heads/captain/private) "bwE" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable/yellow{ icon_state = "4-8" }, @@ -38957,8 +38321,7 @@ /area/crew_quarters/bar) "bwM" = ( /obj/machinery/camera{ - c_tag = "Bar"; - dir = 2 + c_tag = "Bar" }, /obj/machinery/requests_console{ department = "Bar"; @@ -39030,9 +38393,9 @@ /area/crew_quarters/bar) "bwR" = ( /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/crew_quarters/bar"; dir = 1; name = "Bar APC"; - areastring = "/area/crew_quarters/bar"; pixel_y = 25 }, /obj/structure/cable/yellow{ @@ -39060,8 +38423,6 @@ /area/crew_quarters/bar) "bwU" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -39072,8 +38433,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Club - Fore"; - dir = 2 + c_tag = "Club - Fore" }, /turf/open/floor/wood, /area/crew_quarters/bar) @@ -39341,15 +38701,11 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/blue{ - dir = 2 - }, +/obj/effect/turf_decal/tile/blue, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bxC" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/machinery/firealarm{ dir = 1; pixel_y = -24 @@ -39376,8 +38732,6 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -25 }, @@ -39413,7 +38767,6 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/firealarm{ - dir = 2; pixel_y = -24 }, /obj/effect/turf_decal/tile/neutral, @@ -39563,17 +38916,14 @@ "bxS" = ( /obj/item/cigbutt, /obj/machinery/power/apc/highcap/five_k{ - dir = 2; - name = "Port Maintenance APC"; areastring = "/area/maintenance/port"; + name = "Port Maintenance APC"; pixel_y = -24 }, /obj/structure/cable/yellow{ icon_state = "0-4" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/port) "bxT" = ( @@ -39601,17 +38951,13 @@ /turf/open/floor/wood, /area/library) "bxW" = ( -/turf/open/floor/plasteel/cult{ - dir = 2 - }, +/turf/open/floor/plasteel/cult, /area/library) "bxX" = ( /obj/structure/chair/comfy/brown{ dir = 1 }, -/turf/open/floor/plasteel/cult{ - dir = 2 - }, +/turf/open/floor/plasteel/cult, /area/library) "bxY" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -39645,7 +38991,6 @@ /obj/machinery/door/firedoor, /obj/machinery/door/window/northleft{ dir = 2; - icon_state = "left"; name = "Reception Window" }, /obj/machinery/door/poddoor/preopen{ @@ -39814,9 +39159,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "byx" = ( -/obj/machinery/porta_turret/ai{ - dir = 2 - }, +/obj/machinery/porta_turret/ai, /obj/machinery/flasher{ id = "AI"; pixel_y = 24 @@ -39901,9 +39244,7 @@ /turf/open/floor/wood, /area/crew_quarters/bar) "byG" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/structure/disposalpipe/junction/flip{ dir = 4 }, @@ -39943,9 +39284,9 @@ /area/engine/break_room) "byL" = ( /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/theatre"; dir = 1; name = "Theatre APC"; - areastring = "/area/crew_quarters/theatre"; pixel_y = 25 }, /obj/structure/cable/yellow{ @@ -39978,9 +39319,8 @@ /obj/item/stack/sheet/metal/fifty, /obj/item/stack/sheet/glass/fifty, /obj/machinery/power/apc{ - dir = 2; - name = "MiniSat Maint APC"; areastring = "/area/ai_monitored/storage/satellite"; + name = "MiniSat Maint APC"; pixel_y = -26 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -40010,8 +39350,6 @@ /area/hallway/primary/starboard) "byR" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = -30 }, @@ -40125,9 +39463,9 @@ /area/engine/atmos) "byX" = ( /obj/machinery/power/apc/highcap/ten_k{ + areastring = "/area/engine/atmos"; dir = 1; name = "Atmospherics APC"; - areastring = "/area/engine/atmos"; pixel_y = 28 }, /obj/structure/cable/yellow{ @@ -40148,7 +39486,6 @@ "byZ" = ( /obj/machinery/space_heater, /obj/machinery/firealarm{ - dir = 2; pixel_y = 24 }, /obj/effect/turf_decal/stripes/line{ @@ -40359,9 +39696,9 @@ /area/tcommsat/computer) "bzt" = ( /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/tcommsat/computer"; dir = 4; name = "Telecomms Control Room APC"; - areastring = "/area/tcommsat/computer"; pixel_x = 26 }, /obj/machinery/computer/telecomms/server{ @@ -40419,7 +39756,6 @@ /obj/machinery/door/firedoor, /obj/machinery/door/airlock/grunge/abandoned{ name = "Vacant Office"; - opacity = 1; req_access_txt = "32" }, /obj/structure/cable/yellow{ @@ -40474,17 +39810,13 @@ /obj/machinery/door/morgue{ name = "Study #1" }, -/turf/open/floor/plasteel/cult{ - dir = 2 - }, +/turf/open/floor/plasteel/cult, /area/library) "bzH" = ( /obj/machinery/door/morgue{ name = "Study #2" }, -/turf/open/floor/plasteel/cult{ - dir = 2 - }, +/turf/open/floor/plasteel/cult, /area/library) "bzI" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -40509,8 +39841,6 @@ /area/hallway/secondary/command) "bzM" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -40529,8 +39859,6 @@ /area/hallway/secondary/command) "bzO" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -40727,9 +40055,7 @@ /area/crew_quarters/bar) "bAk" = ( /obj/structure/table/reinforced, -/obj/item/clothing/head/that{ - throwforce = 1 - }, +/obj/item/clothing/head/that, /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ dir = 1 @@ -41637,7 +40963,6 @@ /obj/structure/table/reinforced, /obj/machinery/door/window/northleft{ dir = 4; - icon_state = "left"; name = "Atmospherics Desk"; req_access_txt = "24" }, @@ -41929,9 +41254,8 @@ dir = 9 }, /obj/machinery/power/apc/highcap/five_k{ - dir = 2; - name = "Auxiliary Restrooms APC"; areastring = "/area/crew_quarters/toilet/auxiliary"; + name = "Auxiliary Restrooms APC"; pixel_y = -24 }, /obj/structure/cable/yellow, @@ -42071,8 +41395,6 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -42168,9 +41490,9 @@ dir = 4 }, /obj/machinery/power/apc/highcap/ten_k{ + areastring = "/area/hallway/secondary/command"; dir = 1; name = "Command Hallway APC"; - areastring = "/area/hallway/secondary/command"; pixel_y = 25 }, /obj/structure/cable/yellow{ @@ -42214,14 +41536,11 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, /obj/machinery/camera{ - c_tag = "Command Hallway - Starboard"; - dir = 2 + c_tag = "Command Hallway - Starboard" }, /obj/effect/turf_decal/tile/neutral{ dir = 4 @@ -42258,9 +41577,7 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/disposalpipe/segment{ dir = 5 }, @@ -42348,8 +41665,7 @@ "bDG" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/grunge{ - name = "Club"; - opacity = 1 + name = "Club" }, /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ @@ -42536,14 +41852,12 @@ /obj/machinery/telecomms/processor/preset_one, /obj/machinery/camera{ c_tag = "Telecomms - Server Room - Fore-Port"; - dir = 2; network = list("ss13","tcomms") }, /turf/open/floor/circuit/green/telecomms/mainframe, /area/tcommsat/server) "bEg" = ( /obj/structure/showcase/cyborg/old{ - dir = 2; pixel_y = 20 }, /turf/open/floor/plasteel/dark/telecomms, @@ -42567,7 +41881,6 @@ /obj/machinery/telecomms/processor/preset_three, /obj/machinery/camera{ c_tag = "Telecomms - Server Room - Fore-Starboard"; - dir = 2; network = list("ss13","tcomms") }, /turf/open/floor/circuit/green/telecomms/mainframe, @@ -42718,9 +42031,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bED" = ( @@ -42862,9 +42173,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/machinery/newscaster{ pixel_y = -29 }, @@ -42893,9 +42202,7 @@ icon_state = "4-8" }, /obj/machinery/light, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 8 }, @@ -42946,9 +42253,7 @@ /obj/structure/cable/yellow{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bET" = ( @@ -42959,9 +42264,7 @@ icon_state = "4-8" }, /obj/machinery/light, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bEU" = ( @@ -42977,9 +42280,7 @@ /obj/structure/cable/yellow{ icon_state = "1-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bEV" = ( @@ -42995,9 +42296,7 @@ /obj/machinery/newscaster{ pixel_y = -29 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bEW" = ( @@ -43007,9 +42306,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bEX" = ( @@ -43023,9 +42320,7 @@ /obj/structure/cable/yellow{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bEY" = ( @@ -43035,9 +42330,7 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bEZ" = ( @@ -43050,9 +42343,7 @@ /obj/structure/extinguisher_cabinet{ pixel_y = -30 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bFa" = ( @@ -43067,9 +42358,7 @@ dir = 1; pixel_y = -24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bFb" = ( @@ -43079,34 +42368,24 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bFc" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/structure/cable/yellow{ icon_state = "4-8" }, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bFd" = ( /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bFe" = ( @@ -43122,9 +42401,7 @@ /obj/structure/cable/yellow{ icon_state = "2-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bFf" = ( @@ -43138,9 +42415,7 @@ /obj/machinery/door/airlock/public/glass{ name = "Command Hallway" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bFg" = ( @@ -43178,9 +42453,7 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bFj" = ( @@ -43250,9 +42523,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/bar) "bFo" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable/yellow{ icon_state = "4-8" }, @@ -43271,8 +42542,7 @@ }, /obj/machinery/door/firedoor, /obj/machinery/door/airlock/grunge{ - name = "Club"; - opacity = 1 + name = "Club" }, /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ @@ -43506,9 +42776,7 @@ dir = 4 }, /obj/machinery/atmospherics/components/unary/vent_pump/on, -/turf/open/floor/plasteel/dark/corner{ - dir = 2 - }, +/turf/open/floor/plasteel/dark/corner, /area/engine/atmos) "bFK" = ( /obj/machinery/disposal/bin, @@ -43782,9 +43050,7 @@ c_tag = "Central Primary Hallway - Port"; dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bGx" = ( @@ -43905,9 +43171,7 @@ c_tag = "Command Hallway - Central"; dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bGM" = ( @@ -44021,9 +43285,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bGY" = ( @@ -44044,9 +43306,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/bar) "bHa" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/tile/bar, /obj/effect/turf_decal/tile/bar{ dir = 1 @@ -44098,9 +43358,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/wood, /area/crew_quarters/bar) "bHg" = ( @@ -44221,9 +43479,7 @@ /obj/machinery/light/small{ dir = 4 }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/engine/atmos) @@ -44595,19 +43851,16 @@ /turf/open/floor/plasteel/dark, /area/teleporter) "bIh" = ( -/obj/structure/closet/crate{ - icon_state = "crate"; - opened = 0 - }, +/obj/structure/closet/crate, /obj/item/stack/cable_coil, /obj/item/crowbar, /obj/item/screwdriver{ pixel_y = 16 }, /obj/machinery/power/apc{ + areastring = "/area/teleporter"; dir = 4; name = "Teleporter APC"; - areastring = "/area/teleporter"; pixel_x = 24 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -44660,9 +43913,7 @@ /obj/structure/cable/yellow{ icon_state = "1-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bIl" = ( @@ -44719,9 +43970,9 @@ /obj/item/storage/toolbox/emergency, /obj/item/flashlight, /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/gateway"; dir = 4; name = "Gateway APC"; - areastring = "/area/gateway"; pixel_x = 28 }, /obj/structure/cable/yellow{ @@ -44754,9 +44005,7 @@ /area/hallway/primary/central) "bIs" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bIt" = ( @@ -44777,8 +44026,6 @@ /area/crew_quarters/bar) "bIu" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -28 }, @@ -44912,9 +44159,7 @@ /area/engine/atmos) "bIK" = ( /obj/machinery/portable_atmospherics/canister/nitrogen, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/engine/atmos) @@ -45158,9 +44403,7 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/stripes/line{ dir = 8 }, @@ -45184,8 +44427,6 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = -29 }, @@ -45368,10 +44609,7 @@ /turf/open/floor/plasteel, /area/teleporter) "bJL" = ( -/obj/structure/closet/crate{ - icon_state = "crate"; - opened = 0 - }, +/obj/structure/closet/crate, /obj/item/stack/sheet/rglass{ amount = 50 }, @@ -45429,9 +44667,7 @@ /obj/structure/chair{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bJQ" = ( @@ -45452,9 +44688,7 @@ /obj/structure/cable/yellow{ icon_state = "1-4" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/command) "bJS" = ( @@ -45607,9 +44841,7 @@ "bKd" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bKe" = ( @@ -45681,9 +44913,7 @@ name = "Kitchen"; req_access_txt = "28" }, -/turf/open/floor/plasteel/cafeteria{ - dir = 2 - }, +/turf/open/floor/plasteel/cafeteria, /area/crew_quarters/kitchen) "bKl" = ( /obj/machinery/vending/snack/random, @@ -45776,9 +45006,7 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bKx" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bKy" = ( @@ -45903,7 +45131,6 @@ }, /obj/machinery/door/window{ base_state = "right"; - dir = 2; icon_state = "right"; name = "MiniSat Walkway Access" }, @@ -45980,9 +45207,9 @@ /area/maintenance/port) "bKY" = ( /obj/machinery/power/apc{ + areastring = "/area/security/vacantoffice"; dir = 8; name = "Vacant Office APC"; - areastring = "/area/security/vacantoffice"; pixel_x = -25 }, /obj/structure/cable/yellow{ @@ -46083,9 +45310,9 @@ pixel_y = -1 }, /obj/machinery/power/apc{ + areastring = "/area/ai_monitored/storage/eva"; dir = 8; name = "E.V.A. Storage APC"; - areastring = "/area/ai_monitored/storage/eva"; pixel_x = -24 }, /obj/structure/cable/yellow{ @@ -46354,9 +45581,7 @@ pixel_x = -26; req_access_txt = "28" }, -/turf/open/floor/plasteel/cafeteria{ - dir = 2 - }, +/turf/open/floor/plasteel/cafeteria, /area/crew_quarters/kitchen) "bLJ" = ( /obj/structure/table, @@ -46375,9 +45600,7 @@ pixel_x = 6; pixel_y = 26 }, -/turf/open/floor/plasteel/cafeteria{ - dir = 2 - }, +/turf/open/floor/plasteel/cafeteria, /area/crew_quarters/kitchen) "bLK" = ( /turf/open/floor/plasteel/cafeteria{ @@ -46543,8 +45766,6 @@ "bMe" = ( /obj/structure/reagent_dispensers/fueltank, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -26 }, @@ -46661,9 +45882,9 @@ /area/tcommsat/server) "bMs" = ( /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/tcommsat/server"; dir = 4; name = "Telecomms Server Room APC"; - areastring = "/area/tcommsat/server"; pixel_x = 25 }, /obj/machinery/light/small{ @@ -46708,8 +45929,6 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -25 }, @@ -46729,9 +45948,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/blue{ - dir = 2 - }, +/obj/effect/turf_decal/tile/blue, /turf/open/floor/plasteel, /area/hallway/secondary/entry) "bMz" = ( @@ -46747,9 +45964,7 @@ /turf/open/floor/plasteel/white/corner, /area/hallway/secondary/entry) "bMA" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable/yellow{ icon_state = "4-8" }, @@ -46833,9 +46048,9 @@ "bMH" = ( /obj/machinery/light/small, /obj/machinery/power/apc{ + areastring = "/area/library"; dir = 8; name = "Library APC"; - areastring = "/area/library"; pixel_x = -25 }, /obj/structure/cable/yellow{ @@ -46949,7 +46164,6 @@ /area/ai_monitored/storage/eva) "bMU" = ( /obj/structure/tank_dispenser/oxygen{ - layer = 2.9; pixel_x = -1; pixel_y = 2 }, @@ -47075,8 +46289,6 @@ dir = 1 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -47100,8 +46312,7 @@ /obj/item/clothing/under/suit_jacket/really_black, /obj/item/clothing/glasses/sunglasses, /obj/machinery/camera{ - c_tag = "Corporate Showroom"; - dir = 2 + c_tag = "Corporate Showroom" }, /turf/open/floor/wood, /area/bridge/showroom/corporate) @@ -47269,9 +46480,7 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bNv" = ( @@ -47347,9 +46556,7 @@ pixel_x = 24 }, /obj/machinery/vending/dinnerware, -/turf/open/floor/plasteel/cafeteria{ - dir = 2 - }, +/turf/open/floor/plasteel/cafeteria, /area/crew_quarters/kitchen) "bND" = ( /obj/structure/extinguisher_cabinet{ @@ -47410,9 +46617,9 @@ dir = 8 }, /obj/machinery/power/apc{ + areastring = "/area/storage/tcom"; dir = 8; name = "Telecomms Storage APC"; - areastring = "/area/storage/tcom"; pixel_x = -28 }, /obj/structure/cable/yellow{ @@ -47495,7 +46702,6 @@ /obj/machinery/atmospherics/pipe/simple/green/visible, /obj/machinery/door/window/northleft{ dir = 8; - icon_state = "left"; name = "Inner Pipe Access"; req_access_txt = "24" }, @@ -47506,7 +46712,6 @@ dir = 4 }, /obj/machinery/door/window{ - dir = 2; name = "MiniSat Walkway Access" }, /obj/machinery/camera{ @@ -47600,8 +46805,7 @@ "bOk" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/grunge{ - name = "Quiet Room"; - opacity = 1 + name = "Quiet Room" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/wood, @@ -47609,8 +46813,7 @@ "bOl" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/grunge{ - name = "Quiet Room"; - opacity = 1 + name = "Quiet Room" }, /obj/structure/cable/yellow{ icon_state = "1-2" @@ -47809,9 +47012,9 @@ /area/bridge/showroom/corporate) "bOF" = ( /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/bridge/showroom/corporate"; dir = 4; name = "Nanotrasen Corporate Showroom APC"; - areastring = "/area/bridge/showroom/corporate"; pixel_x = 28 }, /obj/structure/cable/yellow{ @@ -48262,9 +47465,7 @@ /obj/machinery/light/small{ dir = 8 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/hallway/secondary/entry) "bPC" = ( @@ -48519,12 +47720,10 @@ icon_state = "1-2" }, /obj/item/bodypart/chest/robot{ - name = "cyborg torso"; pixel_x = -2; pixel_y = 2 }, /obj/item/bodypart/head/robot{ - name = "cyborg head"; pixel_x = 3; pixel_y = 2 }, @@ -48613,12 +47812,8 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/gateway) "bQs" = ( @@ -48800,9 +47995,7 @@ pixel_x = 30 }, /obj/machinery/processor, -/turf/open/floor/plasteel/cafeteria{ - dir = 2 - }, +/turf/open/floor/plasteel/cafeteria, /area/crew_quarters/kitchen) "bQI" = ( /obj/machinery/vending/wardrobe/chef_wardrobe, @@ -48997,9 +48190,7 @@ /turf/open/floor/plasteel, /area/ai_monitored/storage/eva) "bRq" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/ai_monitored/storage/eva) "bRr" = ( @@ -49078,7 +48269,6 @@ }, /obj/item/toy/beach_ball{ desc = "The simple beach ball is one of Nanotrasen's most popular products. 'Why do we make beach balls? Because we can! (TM)' - Nanotrasen"; - item_state = "beachball"; name = "Nanotrasen-brand beach ball"; pixel_y = 7 }, @@ -49111,12 +48301,10 @@ pixel_y = 3 }, /obj/item/clothing/mask/cigarette/cigar{ - name = "premium cigar"; pixel_x = 4; pixel_y = 1 }, /obj/item/clothing/mask/cigarette/cigar{ - name = "premium cigar"; pixel_x = -4; pixel_y = 1 }, @@ -49156,7 +48344,6 @@ pixel_y = -1 }, /obj/item/disk/tech_disk{ - name = "technology disk"; pixel_x = -2; pixel_y = -3 }, @@ -49179,12 +48366,8 @@ /obj/structure/cable/yellow{ icon_state = "2-8" }, -/obj/item/toy/gun{ - name = "cap gun" - }, -/obj/item/restraints/handcuffs{ - name = "handcuffs" - }, +/obj/item/toy/gun, +/obj/item/restraints/handcuffs, /obj/structure/table/wood, /obj/item/clothing/head/collectable/HoS{ name = "novelty HoS hat" @@ -49256,9 +48439,7 @@ }, /area/gateway) "bRL" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/gateway) "bRM" = ( @@ -49270,9 +48451,7 @@ c_tag = "Gateway - Access"; dir = 8 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/gateway) "bRN" = ( @@ -49302,15 +48481,12 @@ pixel_x = -23 }, /obj/machinery/power/apc{ - dir = 2; - name = "Kitchen APC"; areastring = "/area/crew_quarters/kitchen"; + name = "Kitchen APC"; pixel_y = -24 }, /obj/structure/cable/yellow, -/turf/open/floor/plasteel/cafeteria{ - dir = 2 - }, +/turf/open/floor/plasteel/cafeteria, /area/crew_quarters/kitchen) "bRQ" = ( /obj/structure/table, @@ -49320,9 +48496,7 @@ /obj/item/reagent_containers/food/condiment/enzyme{ layer = 5 }, -/turf/open/floor/plasteel/cafeteria{ - dir = 2 - }, +/turf/open/floor/plasteel/cafeteria, /area/crew_quarters/kitchen) "bRR" = ( /obj/structure/table, @@ -49351,9 +48525,7 @@ c_tag = "Kitchen"; dir = 1 }, -/turf/open/floor/plasteel/cafeteria{ - dir = 2 - }, +/turf/open/floor/plasteel/cafeteria, /area/crew_quarters/kitchen) "bRT" = ( /obj/structure/extinguisher_cabinet{ @@ -49659,9 +48831,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -49831,9 +49001,7 @@ /area/hallway/primary/central) "bSR" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/green{ - dir = 2 - }, +/obj/effect/turf_decal/tile/green, /turf/open/floor/plasteel, /area/hallway/primary/central) "bSS" = ( @@ -49945,9 +49113,9 @@ /area/maintenance/starboard) "bTc" = ( /obj/machinery/power/apc{ + areastring = "/area/maintenance/starboard"; dir = 1; name = "Starboard Maintenance APC"; - areastring = "/area/maintenance/starboard"; pixel_x = -1; pixel_y = 26 }, @@ -49984,9 +49152,7 @@ /turf/open/floor/plating, /area/maintenance/starboard) "bTf" = ( -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/general/visible, /obj/machinery/meter, /turf/open/floor/plating, /area/maintenance/starboard) @@ -50177,7 +49343,6 @@ dir = 4 }, /obj/machinery/firealarm{ - dir = 2; pixel_y = 24 }, /obj/effect/turf_decal/stripes/corner{ @@ -50230,8 +49395,6 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -50293,9 +49456,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "bTR" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -50333,9 +49494,9 @@ dir = 1 }, /obj/machinery/power/apc/highcap/ten_k{ + areastring = "/area/hallway/primary/central"; dir = 1; name = "Central Primary Hallway APC"; - areastring = "/area/hallway/primary/central"; pixel_y = 24 }, /obj/structure/cable/yellow{ @@ -50379,8 +49540,6 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -50406,9 +49565,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "bTZ" = ( -/obj/structure/bookcase{ - name = "bookcase" - }, +/obj/structure/bookcase, /turf/open/floor/wood, /area/bridge/showroom/corporate) "bUa" = ( @@ -50694,8 +49851,6 @@ /area/engine/atmos) "bUC" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 28 }, @@ -50783,9 +49938,9 @@ /area/aisat) "bUN" = ( /obj/machinery/power/apc{ + areastring = "/area/maintenance/solars/port/aft"; dir = 8; name = "Port Quarter Solar APC"; - areastring = "/area/maintenance/solars/port/aft"; pixel_x = -26; pixel_y = 3 }, @@ -51175,12 +50330,8 @@ dir = 4; pixel_x = 11 }, -/obj/effect/turf_decal/bot{ - dir = 2 - }, -/turf/open/floor/plasteel{ - dir = 2 - }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, /area/hydroponics) "bVz" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -51287,9 +50438,7 @@ }, /area/engine/atmos) "bVJ" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible, /obj/machinery/meter, /obj/structure/cable/yellow{ icon_state = "1-2" @@ -51492,9 +50641,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/tile/neutral{ dir = 8 }, @@ -51574,9 +50721,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "bWo" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel, /area/hallway/primary/central) "bWp" = ( @@ -51596,9 +50741,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "bWr" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/plaque{ icon_state = "L2" }, @@ -51697,9 +50840,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bWC" = ( @@ -51710,9 +50851,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bWD" = ( @@ -51722,16 +50861,12 @@ /obj/structure/disposalpipe/segment{ dir = 10 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bWE" = ( /obj/machinery/light, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/extinguisher_cabinet{ pixel_y = -30 }, @@ -51739,46 +50874,34 @@ c_tag = "Central Primary Hallway - Aft-Starboard Corner"; dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bWF" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bWG" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/machinery/airalarm{ dir = 1; pixel_y = -22 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/central) "bWH" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/green{ - dir = 2 - }, +/obj/effect/turf_decal/tile/green, /turf/open/floor/plasteel, /area/hallway/primary/central) "bWI" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable/yellow{ icon_state = "1-2" }, @@ -52180,8 +51303,7 @@ /obj/machinery/power/solar_control{ dir = 1; id = "aftport"; - name = "Port Quarter Solar Control"; - track = 0 + name = "Port Quarter Solar Control" }, /obj/structure/cable{ icon_state = "0-4" @@ -52193,9 +51315,7 @@ /obj/structure/cable{ icon_state = "2-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/solars/port/aft) "bXv" = ( @@ -52261,9 +51381,7 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/port) "bXH" = ( @@ -52353,22 +51471,16 @@ /area/hallway/primary/central) "bXT" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/purple{ - dir = 2 - }, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel, /area/hallway/primary/central) "bXU" = ( /obj/machinery/light/small, -/obj/effect/turf_decal/tile/purple{ - dir = 2 - }, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel, /area/hallway/primary/central) "bXV" = ( -/obj/effect/turf_decal/tile/purple{ - dir = 2 - }, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel, /area/hallway/primary/central) "bXW" = ( @@ -52376,16 +51488,12 @@ c_tag = "Central Primary Hallway - Aft-Starboard"; dir = 1 }, -/obj/effect/turf_decal/tile/purple{ - dir = 2 - }, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel, /area/hallway/primary/central) "bXX" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/tile/purple{ - dir = 2 - }, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel, /area/hallway/primary/central) "bXY" = ( @@ -52394,9 +51502,7 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/purple{ - dir = 2 - }, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel, /area/hallway/primary/central) "bXZ" = ( @@ -52407,9 +51513,7 @@ /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-10" }, -/obj/effect/turf_decal/tile/purple{ - dir = 2 - }, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel, /area/hallway/primary/central) "bYa" = ( @@ -52737,9 +51841,7 @@ /area/maintenance/port/aft) "bYI" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/port/aft) "bYJ" = ( @@ -52850,7 +51952,6 @@ /obj/item/clothing/neck/stethoscope, /obj/item/radio/intercom{ broadcasting = 1; - freerange = 0; frequency = 1485; listening = 0; name = "Station Intercom (Medbay)"; @@ -52914,9 +52015,9 @@ /area/medical/storage) "bYX" = ( /obj/machinery/power/apc{ + areastring = "/area/security/checkpoint/medical"; dir = 8; name = "Medical Security Checkpoint APC"; - areastring = "/area/security/checkpoint/medical"; pixel_x = -24 }, /obj/machinery/airalarm{ @@ -52952,7 +52053,6 @@ }, /obj/machinery/camera{ c_tag = "Security Post - Medbay"; - dir = 2; network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/red{ @@ -53004,16 +52104,12 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/firedoor, -/turf/open/floor/plasteel/white/side{ - dir = 2 - }, +/turf/open/floor/plasteel/white/side, /area/medical/medbay/central) "bZd" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/turf/open/floor/plasteel/white/side{ - dir = 2 - }, +/turf/open/floor/plasteel/white/side, /area/medical/medbay/central) "bZe" = ( /obj/structure/sign/directions/security{ @@ -53056,9 +52152,7 @@ /obj/machinery/door/airlock/public/glass{ name = "Aft Primary Hallway" }, -/obj/effect/turf_decal/tile/purple{ - dir = 2 - }, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel, /area/hallway/primary/aft) "bZi" = ( @@ -53084,9 +52178,7 @@ "bZl" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/white/side{ - dir = 2 - }, +/turf/open/floor/plasteel/white/side, /area/science/research) "bZm" = ( /obj/structure/cable/yellow{ @@ -53095,9 +52187,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, /obj/structure/disposalpipe/segment, -/turf/open/floor/plasteel/white/side{ - dir = 2 - }, +/turf/open/floor/plasteel/white/side, /area/science/research) "bZn" = ( /turf/closed/wall, @@ -53225,8 +52315,6 @@ dir = 5 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = -30 }, @@ -53611,9 +52699,7 @@ /area/hallway/primary/aft) "cas" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/purple{ - dir = 2 - }, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel, /area/hallway/primary/aft) "cat" = ( @@ -53731,7 +52817,6 @@ }, /obj/machinery/camera{ c_tag = "Research Division - Lobby"; - dir = 2; network = list("ss13","rd") }, /obj/effect/turf_decal/tile/purple{ @@ -53935,12 +53020,8 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/effect/turf_decal/bot{ - dir = 2 - }, -/turf/open/floor/plasteel{ - dir = 2 - }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, /area/hydroponics) "caQ" = ( /obj/structure/disposalpipe/segment{ @@ -53954,15 +53035,11 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/effect/turf_decal/bot{ - dir = 2 - }, +/obj/effect/turf_decal/bot, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 }, -/turf/open/floor/plasteel{ - dir = 2 - }, +/turf/open/floor/plasteel, /area/hydroponics) "caR" = ( /obj/structure/disposalpipe/segment{ @@ -54070,8 +53147,6 @@ /area/maintenance/disposal/incinerator) "cbb" = ( /obj/machinery/door/window/northleft{ - dir = 1; - icon_state = "left"; name = "Inner Pipe Access"; req_access_txt = "24" }, @@ -54156,8 +53231,6 @@ dir = 8 }, /obj/machinery/door/window/northleft{ - dir = 1; - icon_state = "left"; name = "Inner Pipe Access"; req_access_txt = "24" }, @@ -54232,8 +53305,6 @@ dir = 4 }, /obj/machinery/door/window/northleft{ - dir = 1; - icon_state = "left"; name = "Inner Pipe Access"; req_access_txt = "24" }, @@ -54370,7 +53441,6 @@ /area/maintenance/port/aft) "cby" = ( /obj/machinery/mecha_part_fabricator{ - dir = 2; name = "counterfeit exosuit fabricator"; req_access = null }, @@ -54506,9 +53576,7 @@ /turf/open/floor/plasteel/white, /area/medical/storage) "cbL" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable/yellow{ icon_state = "4-8" }, @@ -54551,7 +53619,6 @@ /area/medical/storage) "cbP" = ( /obj/machinery/requests_console{ - announcementConsole = 0; department = "Medbay"; departmentType = 1; name = "Medbay RC" @@ -54636,9 +53703,7 @@ /obj/structure/cable/yellow{ icon_state = "1-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/machinery/holopad, /turf/open/floor/plasteel/white, /area/medical/medbay/central) @@ -54881,9 +53946,8 @@ /obj/machinery/hydroponics/constructable, /obj/machinery/light, /obj/machinery/power/apc{ - dir = 2; - name = "Hydroponics APC"; areastring = "/area/hydroponics"; + name = "Hydroponics APC"; pixel_y = -28 }, /obj/structure/cable/yellow, @@ -55158,13 +54222,11 @@ "ccZ" = ( /obj/machinery/door/window/northleft{ dir = 8; - icon_state = "left"; name = "glass door"; req_access_txt = "24" }, /obj/machinery/door/window/northleft{ dir = 4; - icon_state = "left"; name = "glass door"; req_access_txt = "24" }, @@ -55293,9 +54355,8 @@ }, /obj/structure/closet/l3closet, /obj/machinery/power/apc{ - dir = 2; - name = "Medbay Storage APC"; areastring = "/area/medical/storage"; + name = "Medbay Storage APC"; pixel_y = -24 }, /obj/structure/cable/yellow, @@ -55490,9 +54551,7 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/purple{ - dir = 2 - }, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel, /area/hallway/primary/aft) "cdJ" = ( @@ -55711,7 +54770,6 @@ pixel_x = 32 }, /obj/machinery/atmospherics/components/binary/pump{ - dir = 2; name = "Fuel Pipe to Incinerator" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -55967,10 +55025,7 @@ "ceF" = ( /obj/structure/bed/roller, /obj/item/radio/intercom{ - broadcasting = 0; - freerange = 0; frequency = 1485; - listening = 1; name = "Station Intercom (Medbay)"; pixel_y = -30 }, @@ -56095,8 +55150,6 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -30 }, @@ -56226,9 +55279,7 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/starboard/aft) "cfc" = ( @@ -56329,9 +55380,7 @@ /obj/structure/disposalpipe/segment{ dir = 9 }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plating, /area/maintenance/starboard) "cfk" = ( @@ -56556,9 +55605,9 @@ }, /obj/item/pen, /obj/machinery/power/apc{ + areastring = "/area/medical/sleeper"; dir = 1; name = "Sleeper Room APC"; - areastring = "/area/medical/sleeper"; pixel_y = 24 }, /obj/structure/cable/yellow{ @@ -56844,9 +55893,7 @@ dir = 8; pixel_x = 24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/aft) "cgd" = ( @@ -56913,9 +55960,9 @@ /area/science/research) "cgj" = ( /obj/machinery/power/apc{ + areastring = "/area/security/checkpoint/science/research"; dir = 8; name = "Security Post - Research Division APC"; - areastring = "/area/security/checkpoint/science/research"; pixel_x = -24 }, /obj/structure/cable/yellow, @@ -56957,9 +56004,7 @@ }, /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/starboard/aft) "cgn" = ( @@ -56989,9 +56034,9 @@ /area/maintenance/starboard/aft) "cgt" = ( /obj/machinery/power/apc{ + areastring = "/area/maintenance/disposal/incinerator"; dir = 8; name = "Incinerator APC"; - areastring = "/area/maintenance/disposal/incinerator"; pixel_x = -24 }, /obj/structure/cable/yellow{ @@ -57144,12 +56189,8 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/port/aft) "cgM" = ( @@ -57494,9 +56535,7 @@ /area/hallway/primary/aft) "chh" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/aft) "chi" = ( @@ -57511,8 +56550,6 @@ dir = 4 }, /obj/structure/noticeboard{ - desc = "A board for pinning important notices upon."; - name = "notice board"; pixel_y = 31 }, /turf/open/floor/plasteel, @@ -57656,7 +56693,6 @@ }, /obj/machinery/camera{ c_tag = "Experimentation Lab - Test Chamber"; - dir = 2; network = list("ss13","rd") }, /obj/machinery/light{ @@ -57746,7 +56782,6 @@ "chI" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/components/binary/valve{ - dir = 2; name = "output gas to space" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -57777,7 +56812,6 @@ }, /obj/machinery/camera{ c_tag = "MiniSat Exterior - Aft"; - dir = 2; network = list("minisat") }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -57987,9 +57021,7 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/tile/blue{ dir = 1 }, @@ -58025,9 +57057,9 @@ /area/medical/medbay/central) "cip" = ( /obj/machinery/power/apc{ + areastring = "/area/medical/medbay/central"; dir = 1; name = "Medbay Central APC"; - areastring = "/area/medical/medbay/central"; pixel_y = 24 }, /obj/structure/cable/yellow{ @@ -58038,7 +57070,6 @@ }, /obj/machinery/camera{ c_tag = "Medbay Hallway Fore"; - dir = 2; network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/blue{ @@ -58047,9 +57078,7 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/central) "ciq" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/tile/blue{ dir = 1 }, @@ -58291,9 +57320,9 @@ /area/science/research) "ciJ" = ( /obj/machinery/power/apc/highcap/ten_k{ + areastring = "/area/science/research"; dir = 1; name = "Research Division APC"; - areastring = "/area/science/research"; pixel_y = 25 }, /obj/structure/cable/yellow{ @@ -58304,7 +57333,6 @@ }, /obj/machinery/camera{ c_tag = "Research Division - Airlock"; - dir = 2; network = list("ss13","rd") }, /obj/effect/turf_decal/stripes/line{ @@ -58419,12 +57447,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/maintenance/disposal/incinerator) -"ciZ" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 2 - }, -/turf/closed/wall/r_wall, -/area/maintenance/disposal/incinerator) "cja" = ( /obj/effect/mapping_helpers/airlock/locked, /obj/machinery/door/airlock/public/glass/incinerator/atmos_interior, @@ -58488,9 +57510,7 @@ /turf/open/floor/engine/air, /area/engine/atmos) "cjl" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 2 - }, +/obj/machinery/atmospherics/components/binary/pump, /turf/closed/wall/r_wall, /area/engine/atmos) "cjm" = ( @@ -58633,7 +57653,6 @@ /obj/structure/bed/roller, /obj/item/radio/intercom{ broadcasting = 1; - freerange = 0; frequency = 1485; listening = 0; name = "Station Intercom (Medbay)"; @@ -58673,12 +57692,8 @@ /turf/open/floor/plasteel/white, /area/medical/sleeper) "cjH" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, +/obj/effect/turf_decal/tile/blue, /turf/open/floor/plasteel/white, /area/medical/sleeper) "cjI" = ( @@ -58753,9 +57768,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "cjO" = ( @@ -58799,9 +57812,7 @@ dir = 8; name = "emergency shower" }, -/obj/effect/turf_decal/tile/yellow{ - dir = 2 - }, +/obj/effect/turf_decal/tile/yellow, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "cjS" = ( @@ -59063,8 +58074,6 @@ "ckq" = ( /obj/machinery/vending/coffee, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, @@ -59170,7 +58179,6 @@ "ckC" = ( /obj/structure/lattice, /obj/machinery/atmospherics/components/binary/pump/on{ - dir = 2; name = "Incinerator Output Pump" }, /obj/structure/disposalpipe/segment, @@ -59211,9 +58219,7 @@ /obj/machinery/light/small{ dir = 4 }, -/obj/machinery/atmospherics/components/binary/pump/on{ - dir = 2 - }, +/obj/machinery/atmospherics/components/binary/pump/on, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, @@ -59464,7 +58470,6 @@ "clm" = ( /obj/item/radio/intercom{ broadcasting = 1; - freerange = 0; frequency = 1485; listening = 0; name = "Station Intercom (Medbay)"; @@ -59473,9 +58478,7 @@ /turf/open/floor/plasteel/white, /area/medical/medbay/central) "cln" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 2 - }, +/obj/effect/turf_decal/tile/blue, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "clo" = ( @@ -59500,9 +58503,7 @@ pixel_y = -22 }, /obj/effect/landmark/event_spawn, -/obj/effect/turf_decal/tile/yellow{ - dir = 2 - }, +/obj/effect/turf_decal/tile/yellow, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "clr" = ( @@ -59624,9 +58625,7 @@ dir = 8; pixel_x = 24 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/aft) "clz" = ( @@ -59703,9 +58702,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel/white, /area/science/research) "clH" = ( @@ -59754,9 +58751,7 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/starboard/aft) "clN" = ( @@ -60115,9 +59110,7 @@ /obj/structure/sign/departments/science{ pixel_x = 32 }, -/obj/effect/turf_decal/tile/purple{ - dir = 2 - }, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel, /area/hallway/primary/aft) "cmF" = ( @@ -60246,9 +59239,7 @@ }, /obj/machinery/disposal/bin, /obj/structure/disposalpipe/trunk, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/explab) "cmR" = ( @@ -60258,9 +59249,7 @@ pixel_y = 6 }, /obj/item/pen, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/explab) "cmS" = ( @@ -60271,25 +59260,19 @@ /obj/item/stack/packageWrap, /obj/item/taperecorder, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/explab) "cmT" = ( /obj/machinery/computer/rdconsole/experiment, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/explab) "cmU" = ( /obj/structure/table/reinforced, /obj/item/clipboard, /obj/item/book/manual/wiki/experimentor, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/explab) "cmV" = ( @@ -60317,18 +59300,14 @@ }, /obj/item/stack/medical/ointment, /obj/item/healthanalyzer, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/explab) "cmW" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/explab) "cmX" = ( @@ -60440,9 +59419,7 @@ /obj/structure/table, /obj/item/surgicaldrill, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plasteel/white/side{ - dir = 2 - }, +/turf/open/floor/plasteel/white/side, /area/medical/surgery) "cno" = ( /obj/structure/table, @@ -60450,9 +59427,7 @@ pixel_y = 12 }, /obj/item/circular_saw, -/turf/open/floor/plasteel/white/side{ - dir = 2 - }, +/turf/open/floor/plasteel/white/side, /area/medical/surgery) "cnp" = ( /obj/structure/table, @@ -60463,9 +59438,7 @@ /obj/item/razor{ pixel_y = 5 }, -/turf/open/floor/plasteel/white/side{ - dir = 2 - }, +/turf/open/floor/plasteel/white/side, /area/medical/surgery) "cnq" = ( /obj/structure/table, @@ -60479,21 +59452,16 @@ /obj/structure/extinguisher_cabinet{ pixel_x = -27 }, -/turf/open/floor/plasteel/white/side{ - dir = 2 - }, +/turf/open/floor/plasteel/white/side, /area/medical/surgery) "cns" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/white/side{ - dir = 2 - }, +/turf/open/floor/plasteel/white/side, /area/medical/surgery) "cnt" = ( /obj/structure/table/reinforced, /obj/item/radio/intercom{ broadcasting = 1; - freerange = 0; frequency = 1485; listening = 0; name = "Station Intercom (Medbay)"; @@ -60511,15 +59479,13 @@ /obj/item/storage/belt/medical{ pixel_y = 2 }, -/turf/open/floor/plasteel/white/side{ - dir = 2 - }, +/turf/open/floor/plasteel/white/side, /area/medical/surgery) "cnu" = ( /obj/machinery/power/apc{ + areastring = "/area/medical/cryo"; dir = 1; name = "Cryogenics APC"; - areastring = "/area/medical/cryo"; pixel_y = 24 }, /obj/structure/cable/yellow{ @@ -60962,7 +59928,6 @@ }, /obj/machinery/camera{ c_tag = "Research Division Hallway - Central"; - dir = 2; network = list("ss13","rd") }, /turf/open/floor/plasteel/white, @@ -60990,9 +59955,7 @@ }, /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel/white/side{ - dir = 2 - }, +/turf/open/floor/plasteel/white/side, /area/science/research) "cof" = ( /turf/open/floor/plasteel/white/side{ @@ -61001,8 +59964,6 @@ /area/science/research) "cog" = ( /obj/item/radio/intercom{ - broadcasting = 0; - listening = 1; name = "Station Intercom (General)"; pixel_y = 20 }, @@ -61033,9 +59994,7 @@ /obj/item/twohanded/required/kirbyplants{ icon_state = "plant-10" }, -/obj/effect/turf_decal/tile/purple{ - dir = 2 - }, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel/white, /area/science/research) "cok" = ( @@ -61204,9 +60163,9 @@ /area/medical/surgery) "coC" = ( /obj/machinery/power/apc{ + areastring = "/area/medical/surgery"; dir = 4; name = "Surgery APC"; - areastring = "/area/medical/surgery"; pixel_x = 26 }, /obj/structure/cable/yellow{ @@ -61288,9 +60247,7 @@ /turf/open/floor/plasteel, /area/medical/cryo) "coK" = ( -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/general/visible, /obj/effect/landmark/start/medical_doctor, /turf/open/floor/plasteel, /area/medical/cryo) @@ -61371,9 +60328,9 @@ /area/crew_quarters/heads/cmo) "coS" = ( /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/heads/cmo"; dir = 4; name = "CMO's Office APC"; - areastring = "/area/crew_quarters/heads/cmo"; pixel_x = 26 }, /obj/structure/cable/yellow{ @@ -61516,7 +60473,6 @@ "cpc" = ( /obj/structure/table/reinforced, /obj/machinery/door/window/eastright{ - dir = 4; name = "Research and Development Desk"; req_one_access_txt = "7;29" }, @@ -61673,9 +60629,7 @@ /obj/structure/disposalpipe/junction/flip{ dir = 2 }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel/white, /area/science/research) "cpr" = ( @@ -61710,9 +60664,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel/white, /area/science/research) "cpv" = ( @@ -62262,9 +61214,9 @@ /area/maintenance/aft) "cqr" = ( /obj/machinery/power/apc{ + areastring = "/area/medical/chemistry"; dir = 8; name = "Chemistry APC"; - areastring = "/area/medical/chemistry"; pixel_x = -24 }, /obj/structure/closet/secure_closet/chemical{ @@ -62364,9 +61316,8 @@ maxcharge = 15000 }, /obj/machinery/power/apc{ - dir = 2; - name = "Research Lab APC"; areastring = "/area/science/lab"; + name = "Research Lab APC"; pixel_y = -26 }, /obj/structure/cable/yellow, @@ -62532,9 +61483,7 @@ /area/science/research) "cqL" = ( /obj/machinery/light, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plasteel/white, /area/science/research) "cqM" = ( @@ -62548,12 +61497,8 @@ /turf/open/floor/plasteel/white, /area/science/research) "cqN" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel/white, /area/science/research) "cqO" = ( @@ -62599,9 +61544,8 @@ dir = 4 }, /obj/machinery/power/apc{ - dir = 2; - name = "Experimentation Lab APC"; areastring = "/area/science/explab"; + name = "Experimentation Lab APC"; pixel_y = -24 }, /obj/structure/cable/yellow, @@ -62695,9 +61639,7 @@ /turf/open/space, /area/space/nearstation) "crd" = ( -/obj/structure/disposaloutlet{ - dir = 2 - }, +/obj/structure/disposaloutlet, /obj/structure/disposalpipe/trunk{ dir = 8 }, @@ -62828,7 +61770,6 @@ }, /obj/item/radio/intercom{ broadcasting = 1; - freerange = 0; frequency = 1485; listening = 0; name = "Station Intercom (Medbay)"; @@ -62846,9 +61787,7 @@ name = "Connector Port (Air Supply)" }, /obj/machinery/portable_atmospherics/canister/oxygen, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/medical/cryo) "crv" = ( @@ -62876,9 +61815,7 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/blue{ - dir = 2 - }, +/obj/effect/turf_decal/tile/blue, /turf/open/floor/plasteel/white, /area/medical/medbay/central) "cry" = ( @@ -62985,8 +61922,6 @@ "crF" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = -29 }, @@ -63007,9 +61942,9 @@ /area/hallway/primary/aft) "crH" = ( /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/hallway/primary/aft"; dir = 4; name = "Aft Hallway APC"; - areastring = "/area/hallway/primary/aft"; pixel_x = 24 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -63276,7 +62211,6 @@ "csn" = ( /obj/item/radio/intercom{ broadcasting = 1; - freerange = 0; frequency = 1485; listening = 0; name = "Station Intercom (Medbay)"; @@ -63563,9 +62497,7 @@ dir = 8; sortType = 23 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/aft) "csI" = ( @@ -63609,9 +62541,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/aft) "csM" = ( @@ -63695,9 +62625,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/aft) "csT" = ( @@ -63855,9 +62783,9 @@ "cti" = ( /obj/machinery/portable_atmospherics/canister/oxygen, /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/science/storage"; dir = 1; name = "Toxins Storage APC"; - areastring = "/area/science/storage"; pixel_y = 25 }, /obj/structure/cable/yellow{ @@ -64055,9 +62983,7 @@ "ctG" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/firedoor, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/aft) "ctH" = ( @@ -64174,9 +63100,7 @@ /turf/open/floor/plasteel/white, /area/crew_quarters/heads/hor) "ctU" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel/white, /area/crew_quarters/heads/hor) "ctV" = ( @@ -64326,9 +63250,9 @@ icon_state = "0-2" }, /obj/machinery/power/apc{ + areastring = "/area/maintenance/port/aft"; dir = 1; name = "Port Quarter Maintenance APC"; - areastring = "/area/maintenance/port/aft"; pixel_y = 24 }, /turf/open/floor/plating, @@ -64344,9 +63268,9 @@ dir = 8 }, /obj/machinery/power/apc{ + areastring = "/area/medical/patients_rooms/room_a"; dir = 8; name = "Patient Room A APC"; - areastring = "/area/medical/patients_rooms/room_a"; pixel_x = -26 }, /obj/structure/cable/yellow{ @@ -64434,8 +63358,6 @@ }, /obj/item/storage/box/bodybags, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = -29 }, @@ -64475,7 +63397,6 @@ "cut" = ( /obj/machinery/requests_console{ department = "Genetics"; - departmentType = 0; name = "Genetics Requests Console"; pixel_y = 30 }, @@ -64493,8 +63414,6 @@ pixel_y = 3 }, /obj/structure/noticeboard{ - desc = "A board for pinning important notices upon."; - name = "notice board"; pixel_x = -32; pixel_y = 32 }, @@ -64513,9 +63432,9 @@ /area/medical/genetics) "cuu" = ( /obj/machinery/power/apc{ + areastring = "/area/medical/genetics"; dir = 1; name = "Genetics Lab APC"; - areastring = "/area/medical/genetics"; pixel_y = 24 }, /obj/structure/cable/yellow{ @@ -64708,9 +63627,7 @@ /area/science/research) "cuK" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/tile/blue{ - dir = 2 - }, +/obj/effect/turf_decal/tile/blue, /turf/open/floor/plasteel/white, /area/science/research) "cuL" = ( @@ -64979,7 +63896,6 @@ dir = 4 }, /obj/machinery/door/window/southleft{ - dir = 2; name = "Cloning Shower" }, /obj/structure/mirror{ @@ -65000,7 +63916,6 @@ "cvv" = ( /obj/machinery/door/window/southleft{ base_state = "right"; - dir = 2; icon_state = "right"; name = "Cloning Shower" }, @@ -65026,8 +63941,6 @@ pixel_y = 2 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, @@ -65195,9 +64108,7 @@ /obj/structure/extinguisher_cabinet{ pixel_x = 27 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/aft) "cvH" = ( @@ -65373,8 +64284,6 @@ "cvY" = ( /obj/machinery/portable_atmospherics/canister/toxins, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, @@ -65661,8 +64570,6 @@ pixel_y = 2 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = -29 }, @@ -65734,8 +64641,6 @@ "cwJ" = ( /obj/machinery/computer/mech_bay_power_console, /obj/item/radio/intercom{ - broadcasting = 0; - listening = 1; name = "Station Intercom (General)"; pixel_y = 20 }, @@ -65790,9 +64695,8 @@ /area/science/research) "cwP" = ( /obj/machinery/power/apc{ - dir = 2; - name = "RD Office APC"; areastring = "/area/crew_quarters/heads/hor"; + name = "RD Office APC"; pixel_y = -27 }, /obj/structure/cable/yellow, @@ -66008,9 +64912,7 @@ dir = 8 }, /obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/blue{ - dir = 2 - }, +/obj/effect/turf_decal/tile/blue, /turf/open/floor/plasteel/white, /area/medical/medbay/aft) "cxl" = ( @@ -66042,9 +64944,7 @@ /turf/open/floor/plasteel/white, /area/medical/genetics/cloning) "cxo" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/machinery/dna_scannernew, /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -66194,9 +65094,7 @@ codes_txt = "patrol;next_patrol=9.1-Escape-1"; location = "8.1-Aft-to-Escape" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/aft) "cxC" = ( @@ -66252,8 +65150,6 @@ /area/science/misc_lab/range) "cxJ" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, @@ -66567,9 +65463,7 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/aft) "cyp" = ( @@ -66649,9 +65543,7 @@ /obj/structure/closet/l3closet/scientist{ pixel_x = -2 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/mixing) "cyA" = ( @@ -66659,20 +65551,15 @@ /obj/structure/window/reinforced{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/mixing) "cyB" = ( /obj/machinery/firealarm{ - dir = 2; pixel_y = 24 }, /obj/machinery/atmospherics/components/unary/thermomachine/freezer, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/mixing) "cyC" = ( @@ -66681,16 +65568,12 @@ }, /obj/machinery/atmospherics/components/unary/portables_connector/visible, /obj/machinery/portable_atmospherics/canister/oxygen, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/mixing) "cyD" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/portable_atmospherics/canister, /turf/open/floor/plasteel, /area/science/mixing) @@ -66700,14 +65583,11 @@ }, /obj/machinery/camera{ c_tag = "Toxins - Lab"; - dir = 2; network = list("ss13","rd") }, /obj/machinery/atmospherics/components/unary/portables_connector/visible, /obj/machinery/portable_atmospherics/canister, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/mixing) "cyF" = ( @@ -66715,9 +65595,7 @@ /obj/structure/window/reinforced{ dir = 8 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /obj/machinery/airalarm/unlocked{ pixel_y = 24 }, @@ -66732,9 +65610,7 @@ /obj/machinery/light{ dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/mixing) "cyH" = ( @@ -66743,9 +65619,7 @@ dir = 4 }, /obj/machinery/portable_atmospherics/canister, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/mixing) "cyI" = ( @@ -66787,9 +65661,7 @@ pixel_y = 4 }, /obj/structure/table/glass, -/turf/open/floor/plasteel/white/side{ - dir = 2 - }, +/turf/open/floor/plasteel/white/side, /area/medical/medbay/aft) "cyO" = ( /obj/machinery/disposal/bin, @@ -66797,9 +65669,7 @@ /obj/machinery/status_display{ pixel_y = 32 }, -/turf/open/floor/plasteel/white/side{ - dir = 2 - }, +/turf/open/floor/plasteel/white/side, /area/medical/medbay/aft) "cyP" = ( /obj/machinery/vending/coffee, @@ -66808,9 +65678,7 @@ icon_state = "map-left-MS"; pixel_y = 32 }, -/turf/open/floor/plasteel/white/side{ - dir = 2 - }, +/turf/open/floor/plasteel/white/side, /area/medical/medbay/aft) "cyQ" = ( /obj/structure/sign/map/right{ @@ -66819,18 +65687,14 @@ pixel_y = 32 }, /obj/machinery/vending/cola/random, -/turf/open/floor/plasteel/white/side{ - dir = 2 - }, +/turf/open/floor/plasteel/white/side, /area/medical/medbay/aft) "cyR" = ( /obj/machinery/vending/cigarette, /obj/structure/noticeboard{ pixel_y = 32 }, -/turf/open/floor/plasteel/white/side{ - dir = 2 - }, +/turf/open/floor/plasteel/white/side, /area/medical/medbay/aft) "cyT" = ( /obj/structure/cable/yellow{ @@ -66886,9 +65750,9 @@ dir = 9 }, /obj/machinery/power/apc/unlocked{ + areastring = "/area/medical/genetics/cloning"; dir = 4; name = "Cloning Lab APC"; - areastring = "/area/medical/genetics/cloning"; pixel_x = 24 }, /obj/structure/cable/yellow, @@ -66988,8 +65852,6 @@ "czf" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = -26 }, @@ -67015,21 +65877,17 @@ dir = 4 }, /obj/machinery/button/door{ - dir = 2; id = "Skynet_launch"; name = "Mech Bay Door Control"; pixel_x = 26; pixel_y = 6; req_one_access_txt = "29" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/aft) "czi" = ( /obj/machinery/button/door{ - dir = 2; id = "Skynet_launch"; name = "Mech Bay Door Control"; pixel_x = -26; @@ -67132,9 +65990,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/purple{ - dir = 2 - }, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel/white, /area/science/research) "czr" = ( @@ -67405,9 +66261,9 @@ /area/medical/medbay/aft) "czW" = ( /obj/machinery/power/apc{ + areastring = "/area/medical/medbay/aft"; dir = 4; name = "Medbay Aft APC"; - areastring = "/area/medical/medbay/aft"; pixel_x = 26 }, /obj/structure/cable/yellow{ @@ -67611,9 +66467,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/primary/aft) "cAk" = ( @@ -67668,9 +66522,9 @@ /area/science/robotics/mechbay) "cAo" = ( /obj/machinery/power/apc{ + areastring = "/area/science/robotics/mechbay"; dir = 4; name = "Mech Bay APC"; - areastring = "/area/science/robotics/mechbay"; pixel_x = 28 }, /obj/structure/cable/yellow{ @@ -67973,7 +66827,6 @@ /obj/structure/chair/stool, /obj/item/radio/intercom{ broadcasting = 1; - freerange = 0; frequency = 1485; listening = 0; name = "Station Intercom (Medbay)"; @@ -68024,9 +66877,7 @@ /turf/open/floor/plating, /area/medical/medbay/aft) "cAY" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/tile/blue{ dir = 1 }, @@ -68046,7 +66897,6 @@ /obj/structure/disposalpipe/segment, /obj/item/radio/intercom{ broadcasting = 1; - freerange = 0; frequency = 1485; listening = 0; name = "Station Intercom (Medbay)"; @@ -68063,7 +66913,6 @@ /obj/machinery/door/firedoor, /obj/machinery/door/airlock/grunge{ name = "Genetics"; - opacity = 1; req_access_txt = "9" }, /turf/open/floor/plasteel/dark, @@ -68109,8 +66958,6 @@ "cBj" = ( /obj/structure/table, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = -25 }, @@ -68143,9 +66990,8 @@ "cBl" = ( /obj/item/gun/energy/laser/practice, /obj/machinery/power/apc{ - dir = 2; - name = "Research Firing Range APC"; areastring = "/area/science/misc_lab/range"; + name = "Research Firing Range APC"; pixel_y = -28 }, /obj/structure/table, @@ -68378,7 +67224,6 @@ dir = 4 }, /obj/machinery/button/massdriver{ - dir = 2; id = "toxinsdriver"; pixel_x = 24; pixel_y = -24 @@ -68520,16 +67365,12 @@ pixel_x = -24 }, /obj/structure/closet/secure_closet/personal/patient, -/turf/open/floor/plasteel/white/corner{ - dir = 2 - }, +/turf/open/floor/plasteel/white/corner, /area/medical/medbay/aft) "cCc" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/closet/secure_closet/personal/patient, -/turf/open/floor/plasteel/white/side{ - dir = 2 - }, +/turf/open/floor/plasteel/white/side, /area/medical/medbay/aft) "cCd" = ( /obj/structure/closet/secure_closet/personal/patient, @@ -68550,7 +67391,6 @@ /area/medical/morgue) "cCi" = ( /obj/machinery/firealarm{ - dir = 2; pixel_y = 24 }, /obj/machinery/light/small{ @@ -68582,14 +67422,10 @@ "cCm" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, -/obj/effect/turf_decal/tile/purple{ - dir = 2 - }, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel, /area/hallway/primary/aft) "cCn" = ( @@ -68706,8 +67542,6 @@ "cCx" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/item/radio/intercom{ - broadcasting = 0; - listening = 1; name = "Station Intercom (General)"; pixel_y = -28 }, @@ -68768,9 +67602,9 @@ pixel_y = -1 }, /obj/machinery/power/apc{ + areastring = "/area/science/mixing"; dir = 4; name = "Toxins Lab APC"; - areastring = "/area/science/mixing"; pixel_x = 26 }, /obj/structure/cable/yellow{ @@ -68804,9 +67638,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/corner{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/corner, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/science/mixing) @@ -68914,9 +67746,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel/white, /area/medical/medbay/aft) "cCT" = ( @@ -68963,8 +67793,6 @@ /obj/item/storage/box/bodybags, /obj/item/pen, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, @@ -69006,12 +67834,8 @@ /turf/open/floor/plasteel, /area/science/robotics/lab) "cDd" = ( -/obj/machinery/mecha_part_fabricator{ - dir = 2 - }, +/obj/machinery/mecha_part_fabricator, /obj/item/radio/intercom{ - broadcasting = 0; - listening = 1; name = "Station Intercom (General)"; pixel_y = 20 }, @@ -69036,12 +67860,9 @@ /turf/open/floor/plasteel, /area/science/robotics/lab) "cDf" = ( -/obj/machinery/mecha_part_fabricator{ - dir = 2 - }, +/obj/machinery/mecha_part_fabricator, /obj/machinery/camera{ c_tag = "Robotics - Fore"; - dir = 2; network = list("ss13","rd") }, /obj/effect/turf_decal/delivery, @@ -69049,9 +67870,9 @@ /area/science/robotics/lab) "cDg" = ( /obj/machinery/power/apc{ + areastring = "/area/science/robotics/lab"; dir = 1; name = "Robotics Lab APC"; - areastring = "/area/science/robotics/lab"; pixel_y = 25 }, /obj/structure/cable/yellow{ @@ -69246,9 +68067,9 @@ }, /obj/item/storage/box/syringes, /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/medical/virology"; dir = 1; name = "Virology APC"; - areastring = "/area/medical/virology"; pixel_y = 24 }, /obj/structure/cable/yellow{ @@ -69490,7 +68311,6 @@ }, /obj/machinery/door/airlock/grunge{ name = "Morgue"; - opacity = 1; req_access_txt = "5" }, /turf/open/floor/plasteel/dark, @@ -69514,9 +68334,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel/dark, /area/medical/morgue) "cEa" = ( @@ -69555,9 +68373,9 @@ "cEd" = ( /obj/structure/table, /obj/machinery/power/apc{ + areastring = "/area/medical/morgue"; dir = 4; name = "Morgue APC"; - areastring = "/area/medical/morgue"; pixel_x = 26 }, /obj/structure/cable/yellow{ @@ -69626,7 +68444,6 @@ /obj/structure/table/reinforced, /obj/item/pen, /obj/machinery/door/window/eastright{ - dir = 4; name = "Robotics Desk"; req_access_txt = "29" }, @@ -69746,7 +68563,6 @@ /area/science/mixing) "cEt" = ( /obj/machinery/sparker/toxmix{ - dir = 2; pixel_x = 25 }, /obj/machinery/atmospherics/components/unary/vent_pump/siphon/atmos/toxins_mixing_output{ @@ -70054,7 +68870,6 @@ /obj/machinery/door/firedoor, /obj/machinery/door/airlock/grunge{ name = "Morgue"; - opacity = 1; req_access_txt = "6" }, /turf/open/floor/plasteel/dark, @@ -70184,9 +68999,7 @@ /turf/open/floor/engine, /area/science/mixing) "cFp" = ( -/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_toxmix{ - dir = 2 - }, +/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_toxmix, /obj/effect/landmark/blobstart, /turf/open/floor/engine, /area/science/mixing) @@ -70237,9 +69050,7 @@ /turf/open/floor/plating/airless, /area/science/test_area) "cFw" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating/airless, /area/science/test_area) "cFx" = ( @@ -70310,9 +69121,7 @@ /turf/open/floor/plasteel/white, /area/medical/virology) "cFB" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/turf_decal/tile/green{ dir = 1 }, @@ -70372,9 +69181,7 @@ /turf/open/floor/plasteel/white, /area/medical/virology) "cFG" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel/white, /area/medical/virology) "cFH" = ( @@ -70463,7 +69270,6 @@ /area/medical/virology) "cFO" = ( /obj/machinery/firealarm{ - dir = 2; pixel_y = 24 }, /obj/machinery/iv_drip, @@ -70485,8 +69291,6 @@ /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, @@ -70653,7 +69457,6 @@ /area/science/research) "cGj" = ( /obj/machinery/sparker/toxmix{ - dir = 2; pixel_x = 25 }, /obj/machinery/atmospherics/components/unary/outlet_injector/atmos/toxins_mixing_input{ @@ -70939,8 +69742,8 @@ }, /obj/machinery/doorButtons/airlock_controller{ idExterior = "virology_airlock_exterior"; - idSelf = "virology_airlock_control"; idInterior = "virology_airlock_interior"; + idSelf = "virology_airlock_control"; name = "Virology Access Console"; pixel_x = 26; pixel_y = 26; @@ -71279,9 +70082,7 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 8 }, -/obj/effect/turf_decal/tile/blue{ - dir = 2 - }, +/obj/effect/turf_decal/tile/blue, /turf/open/floor/plasteel/white, /area/science/research) "cHd" = ( @@ -71301,9 +70102,7 @@ /turf/closed/wall/r_wall, /area/science/server) "cHf" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/closed/wall/r_wall, /area/science/server) "cHg" = ( @@ -71464,9 +70263,7 @@ /turf/open/floor/plasteel/white, /area/medical/virology) "cHu" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/tile/green, /obj/effect/turf_decal/tile/green{ dir = 8 @@ -71520,9 +70317,7 @@ dir = 1; pixel_y = -24 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel/white, /area/medical/virology) "cHy" = ( @@ -71691,9 +70486,7 @@ /obj/structure/disposalpipe/segment{ dir = 9 }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/structure/cable/yellow{ icon_state = "4-8" }, @@ -71750,18 +70543,14 @@ /turf/open/floor/plasteel, /area/science/robotics/lab) "cHR" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/robotics/lab) "cHS" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/robotics/lab) "cHT" = ( @@ -71862,14 +70651,13 @@ "cIb" = ( /obj/machinery/camera{ c_tag = "Research Division - Server Room"; - dir = 2; network = list("ss13","rd"); pixel_x = 22 }, /obj/machinery/power/apc{ + areastring = "/area/science/server"; dir = 1; name = "Research Division Server Room APC"; - areastring = "/area/science/server"; pixel_y = 25 }, /obj/structure/cable/yellow{ @@ -72330,8 +71118,6 @@ dir = 9 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, @@ -72746,9 +71532,7 @@ /obj/machinery/door/airlock/public/glass{ name = "Departure Lounge" }, -/obj/effect/turf_decal/tile/neutral{ - dir = 2 - }, +/obj/effect/turf_decal/tile/neutral, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "cJH" = ( @@ -72756,8 +71540,6 @@ /obj/item/retractor, /obj/item/hemostat, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = -29 }, @@ -72836,9 +71618,7 @@ pixel_x = -12; pixel_y = 2 }, -/obj/effect/turf_decal/tile/purple{ - dir = 2 - }, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel/white, /area/science/research) "cJP" = ( @@ -72871,8 +71651,6 @@ /area/science/server) "cJS" = ( /obj/item/radio/intercom{ - broadcasting = 0; - listening = 1; name = "Station Intercom (General)"; pixel_y = -28 }, @@ -72918,26 +71696,20 @@ lootcount = 2; name = "2maintenance loot spawner" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/starboard/aft) "cJZ" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/reagent_dispensers/watertank, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/starboard/aft) "cKa" = ( /obj/structure/closet, /obj/item/clothing/glasses/science, /obj/effect/spawner/lootdrop/maintenance, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/starboard/aft) "cKb" = ( @@ -72951,9 +71723,7 @@ icon_state = "1-2" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/starboard/aft) "cKe" = ( @@ -73058,7 +71828,6 @@ }, /obj/machinery/camera{ c_tag = "Virology - Break Room"; - dir = 2; network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/green{ @@ -73071,8 +71840,6 @@ /area/medical/virology) "cKm" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, @@ -73174,9 +71941,9 @@ /area/hallway/secondary/exit/departure_lounge) "cKy" = ( /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/hallway/secondary/exit/departure_lounge"; dir = 1; name = "Departure Lounge APC"; - areastring = "/area/hallway/secondary/exit/departure_lounge"; pixel_y = 24 }, /obj/structure/cable/yellow{ @@ -73830,9 +72597,9 @@ /area/maintenance/solars/starboard/aft) "cLM" = ( /obj/machinery/power/apc{ + areastring = "/area/maintenance/solars/starboard/aft"; dir = 1; name = "Starboard Quarter Solar APC"; - areastring = "/area/maintenance/solars/starboard/aft"; pixel_y = 24 }, /obj/structure/cable/yellow{ @@ -73972,9 +72739,7 @@ name = "Relic Closet"; req_access_txt = "22" }, -/turf/open/floor/plasteel/cult{ - dir = 2 - }, +/turf/open/floor/plasteel/cult, /area/chapel/office) "cMa" = ( /obj/structure/table/wood, @@ -73982,7 +72747,6 @@ name = "mysterious old book of " }, /obj/item/reagent_containers/food/drinks/bottle/holywater{ - name = "flask of holy water"; pixel_x = -2; pixel_y = 2 }, @@ -73991,9 +72755,7 @@ }, /obj/item/organ/heart, /obj/item/soulstone/anybody/chaplain, -/turf/open/floor/plasteel/cult{ - dir = 2 - }, +/turf/open/floor/plasteel/cult, /area/chapel/office) "cMb" = ( /obj/machinery/door/airlock/maintenance{ @@ -74012,9 +72774,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "cMe" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/corner, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "cMf" = ( @@ -74063,9 +72823,8 @@ /area/hallway/secondary/exit/departure_lounge) "cMk" = ( /obj/machinery/power/apc/highcap/five_k{ - dir = 2; - name = "Aft Maintenance APC"; areastring = "/area/maintenance/aft"; + name = "Aft Maintenance APC"; pixel_y = -24 }, /obj/structure/cable/yellow, @@ -74356,8 +73115,7 @@ pixel_y = 32 }, /obj/machinery/camera{ - c_tag = "Chapel - Fore"; - dir = 2 + c_tag = "Chapel - Fore" }, /obj/structure/table/wood, /obj/effect/turf_decal/tile/neutral{ @@ -74565,7 +73323,6 @@ /obj/structure/table/reinforced, /obj/machinery/door/window/westleft{ base_state = "right"; - dir = 8; icon_state = "right"; name = "Outer Window" }, @@ -74784,8 +73541,7 @@ /obj/machinery/power/solar_control{ dir = 8; id = "aftstarboard"; - name = "Starboard Quarter Solar Control"; - track = 0 + name = "Starboard Quarter Solar Control" }, /obj/structure/cable, /obj/structure/cable{ @@ -75168,9 +73924,9 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ + areastring = "/area/chapel/main"; dir = 8; name = "Chapel APC"; - areastring = "/area/chapel/main"; pixel_x = -25 }, /turf/open/floor/carpet, @@ -75360,8 +74116,6 @@ pixel_x = 4 }, /obj/item/radio/intercom{ - broadcasting = 0; - listening = 1; name = "Station Intercom (General)"; pixel_y = -32 }, @@ -75425,10 +74179,8 @@ /area/chapel/office) "cOI" = ( /obj/machinery/power/apc{ - dir = 2; - lighting = 3; - name = "Chapel Office APC"; areastring = "/area/chapel/office"; + name = "Chapel Office APC"; pixel_y = -25 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -75510,9 +74262,7 @@ /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "cOU" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "cOV" = ( @@ -75967,8 +74717,6 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, @@ -76050,8 +74798,6 @@ /area/chapel/main) "cQc" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -76064,12 +74810,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/chapel/main) -"cQd" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, -/turf/open/floor/plasteel/dark, -/area/chapel/main) "cQf" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -76102,9 +74842,7 @@ /turf/open/floor/plasteel/chapel, /area/chapel/main) "cQj" = ( -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel/chapel{ dir = 8 }, @@ -76126,21 +74864,13 @@ }, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) -"cQn" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, -/turf/open/floor/plasteel, -/area/hallway/secondary/exit/departure_lounge) "cQo" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/navbeacon{ codes_txt = "patrol;next_patrol=9.4-Escape-4"; location = "9.3-Escape-3" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "cQp" = ( @@ -76149,9 +74879,7 @@ codes_txt = "patrol;next_patrol=9.3-Escape-3"; location = "9.2-Escape-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/hallway/secondary/exit/departure_lounge) "cQq" = ( @@ -76172,7 +74900,6 @@ }, /obj/machinery/camera{ c_tag = "Research Division Hallway - Xenobiology Lab Access"; - dir = 2; network = list("ss13","rd") }, /obj/effect/turf_decal/tile/purple{ @@ -76188,7 +74915,6 @@ dir = 1 }, /obj/machinery/firealarm{ - dir = 2; pixel_y = 24 }, /obj/structure/cable/yellow{ @@ -76215,9 +74941,7 @@ /obj/structure/cable/yellow{ icon_state = "1-4" }, -/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden, /obj/effect/landmark/blobstart, /obj/effect/turf_decal/tile/purple{ dir = 1 @@ -76230,7 +74954,6 @@ "cQv" = ( /obj/machinery/camera{ c_tag = "Toxins - Launch Area"; - dir = 2; network = list("ss13","rd") }, /obj/machinery/suit_storage_unit/rd, @@ -76262,8 +74985,6 @@ dir = 4 }, /obj/item/radio/intercom{ - broadcasting = 0; - listening = 1; name = "Station Intercom (General)"; pixel_y = 22 }, @@ -76399,8 +75120,6 @@ /area/science/xenobiology) "cQS" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, @@ -76562,7 +75281,6 @@ /area/chapel/main) "cRm" = ( /obj/machinery/mass_driver{ - dir = 2; id = "chapelgun" }, /obj/structure/sign/warning/vacuum/external{ @@ -76761,17 +75479,13 @@ /obj/machinery/light/small{ dir = 1 }, -/turf/open/floor/plasteel/cult{ - dir = 2 - }, +/turf/open/floor/plasteel/cult, /area/chapel/main) "cRF" = ( /obj/machinery/door/morgue{ name = "Chapel Garden" }, -/turf/open/floor/plasteel/cult{ - dir = 2 - }, +/turf/open/floor/plasteel/cult, /area/chapel/main) "cRG" = ( /obj/machinery/light/small, @@ -76856,9 +75570,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 1 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel/dark, /area/chapel/main) "cRL" = ( @@ -76871,9 +75583,7 @@ /area/chapel/main) "cRM" = ( /obj/machinery/processor/slime, -/obj/effect/turf_decal/stripes/corner{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/corner, /turf/open/floor/plasteel/white, /area/science/xenobiology) "cRN" = ( @@ -77000,9 +75710,7 @@ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/corner{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/corner, /turf/open/floor/plasteel/white, /area/science/xenobiology) "cSc" = ( @@ -77477,7 +76185,6 @@ dir = 8 }, /obj/machinery/firealarm{ - dir = 2; pixel_y = 26 }, /obj/effect/turf_decal/stripes/line{ @@ -77647,9 +76354,7 @@ pixel_y = 2 }, /obj/structure/table/reinforced, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/xenobiology) "cTs" = ( @@ -77671,9 +76376,7 @@ name = "Maximum Security Test Chamber"; req_access_txt = "55" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/xenobiology) "cTw" = ( @@ -77699,9 +76402,7 @@ /obj/item/clothing/glasses/science, /obj/item/clothing/glasses/science, /obj/structure/table, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel, /area/science/xenobiology) "cTA" = ( @@ -77805,9 +76506,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel/white, /area/science/xenobiology) "cVb" = ( @@ -77832,7 +76531,6 @@ }, /obj/item/radio/intercom{ freerange = 1; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = -30 }, @@ -78034,7 +76732,6 @@ /area/construction/mining/aux_base) "cYJ" = ( /obj/docking_port/stationary{ - dheight = 0; dir = 2; dwidth = 9; height = 25; @@ -78102,8 +76799,6 @@ /area/science/xenobiology) "cZc" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, @@ -78182,7 +76877,6 @@ /area/security/main) "daA" = ( /obj/machinery/door/window/southleft{ - dir = 2; name = "Maximum Security Test Chamber"; req_access_txt = "55" }, @@ -78204,9 +76898,7 @@ /turf/closed/wall/r_wall, /area/science/xenobiology) "daD" = ( -/obj/structure/disposaloutlet{ - dir = 2 - }, +/obj/structure/disposaloutlet, /obj/structure/disposalpipe/trunk{ dir = 1 }, @@ -78453,7 +77145,6 @@ "dbr" = ( /obj/machinery/camera{ c_tag = "Morgue"; - dir = 2; network = list("ss13","medbay") }, /obj/structure/bodycontainer/morgue{ @@ -78700,7 +77391,6 @@ pixel_y = -8 }, /obj/machinery/firealarm{ - dir = 2; pixel_y = 24 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on, @@ -78714,7 +77404,6 @@ /area/science/xenobiology) "dca" = ( /obj/machinery/firealarm{ - dir = 2; pixel_y = 26 }, /obj/effect/turf_decal/tile/purple{ @@ -78731,7 +77420,6 @@ }, /obj/machinery/camera{ c_tag = "Xenobiology Lab - Fore"; - dir = 2; network = list("ss13","rd") }, /obj/effect/turf_decal/tile/purple{ @@ -78766,9 +77454,9 @@ }, /obj/item/reagent_containers/dropper, /obj/machinery/power/apc/highcap/ten_k{ + areastring = "/area/science/xenobiology"; dir = 1; name = "Xenobiology APC"; - areastring = "/area/science/xenobiology"; pixel_y = 27 }, /obj/structure/cable/yellow{ @@ -78847,8 +77535,6 @@ dir = 4 }, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = -29 }, @@ -78870,9 +77556,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ - dir = 2 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, /obj/effect/turf_decal/stripes/line{ dir = 4 }, @@ -79020,9 +77704,7 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel/white, /area/science/xenobiology) "dcu" = ( @@ -79114,9 +77796,7 @@ /area/science/xenobiology) "dcG" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel/white, /area/science/xenobiology) "dcH" = ( @@ -79126,9 +77806,7 @@ /obj/structure/disposalpipe/segment{ dir = 6 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel/white, /area/science/xenobiology) "dcI" = ( @@ -79136,9 +77814,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel/white, /area/science/xenobiology) "dcJ" = ( @@ -79164,9 +77840,7 @@ /obj/structure/disposalpipe/trunk{ dir = 8 }, -/obj/effect/turf_decal/tile/purple{ - dir = 2 - }, +/obj/effect/turf_decal/tile/purple, /turf/open/floor/plasteel/white, /area/science/xenobiology) "dcL" = ( @@ -79474,9 +78148,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel/white, /area/science/xenobiology) "ddm" = ( @@ -79489,18 +78161,14 @@ /obj/structure/cable/yellow{ icon_state = "1-4" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel/white, /area/science/xenobiology) "ddn" = ( /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plasteel/white, /area/science/xenobiology) "ddo" = ( @@ -79579,9 +78247,9 @@ "ddw" = ( /obj/structure/cable/yellow, /obj/machinery/power/apc{ + areastring = "/area/maintenance/department/science/xenobiology"; dir = 4; name = "Test Chamber Maintenance APC"; - areastring = "/area/maintenance/department/science/xenobiology"; pixel_x = 26 }, /turf/open/floor/plating, @@ -79794,7 +78462,6 @@ /area/engine/engineering) "dek" = ( /obj/machinery/atmospherics/components/binary/pump{ - dir = 2; name = "Mix to Gas" }, /obj/structure/cable/white{ @@ -79849,8 +78516,6 @@ /area/engine/engineering) "deq" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -79974,7 +78639,6 @@ "deK" = ( /obj/structure/cable/white, /obj/machinery/power/emitter/anchored{ - dir = 2; state = 2 }, /turf/open/floor/plating, @@ -80631,7 +79295,6 @@ /obj/machinery/atmospherics/pipe/simple/green/visible, /obj/machinery/door/window/northleft{ dir = 8; - icon_state = "left"; name = "Inner Pipe Access"; req_access_txt = "24" }, @@ -80966,9 +79629,8 @@ /obj/structure/table, /obj/item/analyzer, /obj/machinery/power/apc{ - dir = 2; - name = "Tool Storage APC"; areastring = "/area/storage/primary"; + name = "Tool Storage APC"; pixel_y = -27 }, /obj/structure/cable/yellow, @@ -80987,8 +79649,6 @@ /area/storage/primary) "dhM" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 21 }, @@ -81198,8 +79858,6 @@ /obj/item/instrument/violin, /obj/structure/table/wood, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 29 }, @@ -81764,8 +80422,8 @@ height = 15; id = "arrivals_stationary"; name = "arrivals"; - width = 7; - roundstart_template = /datum/map_template/shuttle/arrival/box + roundstart_template = /datum/map_template/shuttle/arrival/box; + width = 7 }, /turf/open/space/basic, /area/space) @@ -81873,9 +80531,9 @@ icon_state = "0-8" }, /obj/machinery/power/apc{ + areastring = "/area/maintenance/port/fore"; dir = 4; name = "Port Bow Maintenance APC"; - areastring = "/area/maintenance/port/fore"; pixel_x = 26 }, /turf/open/floor/plating{ @@ -82039,9 +80697,7 @@ /obj/structure/cable/yellow{ icon_state = "1-2" }, -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/open/floor/plating, /area/maintenance/port/fore) "dtE" = ( @@ -82080,9 +80736,8 @@ "dtS" = ( /obj/item/cigbutt, /obj/machinery/power/apc{ - dir = 2; - name = "Starboard Bow Maintenance APC"; areastring = "/area/maintenance/starboard/fore"; + name = "Starboard Bow Maintenance APC"; pixel_y = -28 }, /obj/structure/cable/yellow{ @@ -82304,9 +80959,8 @@ /area/maintenance/starboard/aft) "dAd" = ( /obj/machinery/power/apc/highcap/five_k{ - dir = 2; - name = "Starboard Quarter Maintenance APC"; areastring = "/area/maintenance/starboard/aft"; + name = "Starboard Quarter Maintenance APC"; pixel_y = -24 }, /obj/structure/cable/yellow, @@ -83225,8 +81879,8 @@ /area/science/circuit) "eFN" = ( /obj/structure/bodycontainer/crematorium{ - id = "crematoriumChapel"; - dir = 1 + dir = 1; + id = "crematoriumChapel" }, /turf/open/floor/plasteel/dark, /area/chapel/office) @@ -83297,7 +81951,6 @@ /area/science/circuit) "gqA" = ( /obj/machinery/button/door{ - dir = 2; id = "abandoned_kitchen"; name = "Shutters Control"; pixel_x = 26; @@ -83716,8 +82369,7 @@ "mAU" = ( /obj/machinery/cryopod, /obj/machinery/camera{ - c_tag = "Fitness Room - Fore"; - dir = 2 + c_tag = "Fitness Room - Fore" }, /turf/open/floor/plasteel/dark, /area/crew_quarters/cryopod) @@ -83798,7 +82450,6 @@ /obj/docking_port/stationary{ area_type = /area/construction/mining/aux_base; dheight = 4; - dir = 1; dwidth = 4; height = 9; id = "aux_base_zone"; @@ -83853,7 +82504,6 @@ /obj/machinery/requests_console{ department = "Science"; departmentType = 2; - dir = 2; name = "Science Requests Console"; pixel_y = 30; receive_ore_updates = 1 @@ -84057,7 +82707,6 @@ /area/crew_quarters/cryopod) "ram" = ( /obj/machinery/computer/arcade{ - icon_state = "arcade"; dir = 1 }, /turf/open/floor/plasteel, @@ -84419,9 +83068,7 @@ /turf/open/floor/plating, /area/maintenance/starboard/aft) "wKo" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/line, /turf/closed/wall, /area/science/circuit) "wOE" = ( @@ -106323,7 +104970,7 @@ cOg cOJ cPl cPH -cQd +djr cTo cRm cRK @@ -109921,7 +108568,7 @@ cOq cLm cLm cLm -cQn +cMf cQK cPv cPv @@ -110435,7 +109082,7 @@ cOr cOU dDG cPQ -cQn +cMf cQK cPv cPv @@ -110692,7 +109339,7 @@ cMT cOV cMT cPR -cQn +cMf cQK cPv aaa @@ -110949,7 +109596,7 @@ cOs cOW cMU cPS -cQn +cMf cQM cPv aaa @@ -111206,7 +109853,7 @@ cMV cOX cMV cPT -cQn +cMf cQK cPv aaa @@ -111463,7 +110110,7 @@ cLm cOq cLm cPQ -cQn +cMf cQK cPv cPv @@ -111977,7 +110624,7 @@ cOt cOZ cPt cLm -cQn +cMf cQO cPv cPv @@ -124277,9 +122924,9 @@ ced cfq cgw cfs -ciZ +cjb ckD -ciZ +cjb cnd cgz cgz @@ -124465,7 +123112,7 @@ aie aja ajY alp -amF +dtE anN dnS doh diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index b9462f214d..84ea2dfca1 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -108,8 +108,6 @@ }, /obj/effect/landmark/start/ai/secondary, /obj/item/radio/intercom{ - anyai = 1; - broadcasting = 0; freerange = 1; frequency = 1447; name = "Private Channel"; @@ -129,7 +127,6 @@ }, /obj/machinery/camera/motion{ c_tag = "MiniSat AI Chamber Center"; - dir = 2; network = list("minisat") }, /obj/machinery/light/small{ @@ -148,15 +145,13 @@ icon_state = "0-8" }, /obj/machinery/power/apc{ + areastring = "/area/ai_monitored/turret_protected/ai"; dir = 1; name = "AI Chamber APC"; - areastring = "/area/ai_monitored/turret_protected/ai"; pixel_y = 24 }, /obj/effect/landmark/start/ai/secondary, /obj/item/radio/intercom{ - anyai = 1; - broadcasting = 0; freerange = 1; frequency = 1447; name = "Private Channel"; @@ -279,23 +274,18 @@ "acy" = ( /obj/effect/landmark/start/ai, /obj/item/radio/intercom{ - broadcasting = 0; freerange = 1; - listening = 1; name = "Common Channel"; pixel_x = -27; pixel_y = -9 }, /obj/item/radio/intercom{ - anyai = 1; freerange = 1; listening = 0; name = "Custom Channel"; pixel_y = -31 }, /obj/item/radio/intercom{ - anyai = 1; - broadcasting = 0; freerange = 1; frequency = 1447; name = "Private Channel"; @@ -339,7 +329,6 @@ "acD" = ( /obj/machinery/camera/motion{ c_tag = "MiniSat AI Chamber South"; - dir = 2; network = list("minisat") }, /obj/machinery/light{ @@ -576,9 +565,9 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ + areastring = "/area/ai_monitored/turret_protected/aisat_interior"; dir = 8; name = "MiniSat Antechamber APC"; - areastring = "/area/ai_monitored/turret_protected/aisat_interior"; pixel_x = -24 }, /obj/machinery/recharger, @@ -866,7 +855,6 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/camera/motion{ c_tag = "MiniSat Bridge Port Fore"; - dir = 2; network = list("minisat") }, /turf/open/space, @@ -894,7 +882,6 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/camera/motion{ c_tag = "MiniSat Bridge Starboard Fore"; - dir = 2; network = list("minisat") }, /turf/open/space, @@ -1233,9 +1220,9 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ + areastring = "/area/ai_monitored/turret_protected/AIsatextAP"; dir = 8; name = "MiniSat Port Maintenance APC"; - areastring = "/area/ai_monitored/turret_protected/AIsatextAP"; pixel_x = -24 }, /turf/open/floor/plating, @@ -1261,7 +1248,6 @@ }, /obj/machinery/camera{ c_tag = "MiniSat Maintenance Port Aft"; - dir = 2; network = list("minisat") }, /turf/open/floor/plating, @@ -1334,7 +1320,6 @@ }, /obj/machinery/camera/motion{ c_tag = "MiniSat Foyer"; - dir = 2; network = list("minisat") }, /obj/effect/turf_decal/tile/blue, @@ -1386,7 +1371,6 @@ }, /obj/machinery/camera{ c_tag = "MiniSat Maintenance Starboard Aft"; - dir = 2; network = list("minisat") }, /turf/open/floor/plating, @@ -1406,9 +1390,9 @@ icon_state = "0-8" }, /obj/machinery/power/apc{ + areastring = "/area/ai_monitored/turret_protected/AIsatextAS"; dir = 4; name = "MiniSat Starboard Maintenance APC"; - areastring = "/area/ai_monitored/turret_protected/AIsatextAS"; pixel_x = 24 }, /turf/open/floor/plating, @@ -1482,6 +1466,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "afy" = ( @@ -1494,6 +1479,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "afA" = ( @@ -1564,7 +1550,6 @@ /area/security/prison) "afI" = ( /obj/machinery/computer/arcade{ - icon_state = "arcade"; dir = 8 }, /turf/open/floor/plasteel/dark, @@ -1607,6 +1592,7 @@ "afP" = ( /obj/machinery/holopad, /mob/living/simple_animal/bot/secbot/pingsky, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "afQ" = ( @@ -1665,7 +1651,6 @@ }, /obj/machinery/door/window/westleft{ base_state = "right"; - dir = 8; icon_state = "right"; name = "Unisex Showers" }, @@ -1697,6 +1682,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "agh" = ( @@ -1710,8 +1696,7 @@ /area/ai_monitored/turret_protected/aisat_interior) "agi" = ( /obj/machinery/door/poddoor{ - id = "executionspaceblast"; - name = "blast door" + id = "executionspaceblast" }, /turf/open/floor/plating, /area/security/execution/transfer) @@ -1855,8 +1840,7 @@ /area/security/prison) "agC" = ( /obj/machinery/door/airlock{ - name = "Unisex Restroom"; - req_access_txt = "0" + name = "Unisex Restroom" }, /turf/open/floor/plasteel/freezer, /area/security/prison) @@ -1896,7 +1880,6 @@ }, /obj/item/radio/intercom{ desc = "Talk through this. It looks like it has been modified to not broadcast."; - dir = 2; name = "Prison Intercom (General)"; pixel_y = 24; prison_radio = 1 @@ -1916,7 +1899,6 @@ name = "Cell Bolt Control"; normaldoorcontrol = 1; pixel_y = 25; - req_access_txt = "0"; specialfunctions = 4 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ @@ -1933,7 +1915,6 @@ }, /obj/item/radio/intercom{ desc = "Talk through this. It looks like it has been modified to not broadcast."; - dir = 2; name = "Prison Intercom (General)"; pixel_y = 24; prison_radio = 1 @@ -1962,7 +1943,6 @@ name = "Cell Bolt Control"; normaldoorcontrol = 1; pixel_y = 25; - req_access_txt = "0"; specialfunctions = 4 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ @@ -2069,7 +2049,6 @@ "ahh" = ( /obj/structure/lattice/catwalk, /obj/structure/showcase/cyborg/old{ - dir = 2; pixel_y = 20 }, /turf/open/space, @@ -2121,8 +2100,6 @@ /area/security/execution/transfer) "ahl" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = 28 }, @@ -2179,7 +2156,6 @@ /obj/structure/lattice, /obj/machinery/camera/motion{ c_tag = "MiniSat Entrance"; - dir = 2; network = list("minisat") }, /turf/open/space, @@ -2321,7 +2297,6 @@ network = list("ss13","prison") }, /obj/machinery/computer/security/telescreen/prison{ - network = list("prison"); pixel_y = 30 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -2596,8 +2571,7 @@ "aik" = ( /obj/structure/closet/secure_closet/lethalshots, /obj/machinery/camera/motion{ - c_tag = "Armory Motion Sensor"; - dir = 2 + c_tag = "Armory Motion Sensor" }, /turf/open/floor/plasteel/dark, /area/security/armory) @@ -3630,7 +3604,6 @@ name = "Door Bolt Control"; normaldoorcontrol = 1; pixel_x = 25; - req_access_txt = "0"; specialfunctions = 4 }, /turf/open/floor/plating, @@ -3729,8 +3702,6 @@ /area/security/brig) "akD" = ( /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_y = 24 }, @@ -4099,9 +4070,7 @@ /area/security/brig) "alt" = ( /obj/machinery/door/window/westleft{ - base_state = "left"; dir = 4; - icon_state = "left"; name = "Brig Infirmary" }, /obj/machinery/atmospherics/pipe/simple/cyan/hidden{ @@ -4872,8 +4841,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Brig Control Room"; - dir = 2 + c_tag = "Brig Control Room" }, /obj/item/radio/intercom{ dir = 4; @@ -4993,8 +4961,7 @@ /area/space/nearstation) "anm" = ( /obj/machinery/door/airlock/maintenance/abandoned{ - name = "Pete's Speakeasy"; - req_access_txt = "0" + name = "Pete's Speakeasy" }, /turf/open/floor/plating, /area/maintenance/department/crew_quarters/dorms) @@ -5325,7 +5292,6 @@ icon_state = "0-8" }, /obj/machinery/power/apc{ - dir = 2; name = "Head of Security's Office APC"; pixel_y = -24 }, @@ -6320,8 +6286,7 @@ /area/security/brig) "aqq" = ( /obj/machinery/camera{ - c_tag = "Brig Cells"; - dir = 2 + c_tag = "Brig Cells" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -6645,7 +6610,6 @@ /area/crew_quarters/dorms) "aqY" = ( /obj/docking_port/stationary{ - dir = 1; dwidth = 2; height = 6; id = "monastery_shuttle_station"; @@ -6941,8 +6905,7 @@ "arL" = ( /obj/machinery/computer/card, /obj/machinery/camera{ - c_tag = "Bridge - Central"; - dir = 2 + c_tag = "Bridge - Central" }, /obj/effect/turf_decal/tile/blue{ dir = 1 @@ -8112,8 +8075,8 @@ "aud" = ( /obj/machinery/camera/motion{ c_tag = "Vault"; - network = list("vault"); - dir = 1 + dir = 1; + network = list("vault") }, /obj/machinery/light, /obj/structure/cable{ @@ -8147,8 +8110,6 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/item/radio/intercom{ - freerange = 0; - frequency = 1459; name = "Station Intercom (General)"; pixel_x = -30 }, @@ -8280,7 +8241,6 @@ "aux" = ( /obj/item/radio/intercom{ desc = "Talk through this. It looks like it has been modified to not broadcast."; - dir = 2; name = "Prison Intercom (General)"; pixel_x = -25; pixel_y = -2; @@ -8649,8 +8609,7 @@ dir = 10 }, /obj/machinery/camera{ - c_tag = "Dormitories Fore"; - dir = 2 + c_tag = "Dormitories Fore" }, /obj/machinery/light{ dir = 1 @@ -9308,8 +9267,7 @@ dir = 8 }, /obj/machinery/camera{ - c_tag = "Fitness Room"; - dir = 2 + c_tag = "Fitness Room" }, /obj/machinery/computer/security/telescreen/entertainment{ pixel_y = 32 @@ -9335,9 +9293,9 @@ icon_state = "plant-05" }, /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/fitness/recreation"; dir = 1; name = "Fitness Room APC"; - areastring = "/area/crew_quarters/fitness/recreation"; pixel_y = 24 }, /obj/structure/cable{ @@ -9487,9 +9445,7 @@ name = "Brig Desk"; req_access_txt = "1" }, -/obj/item/reagent_containers/food/snacks/donut{ - layer = 3 - }, +/obj/item/reagent_containers/food/snacks/donut, /obj/machinery/door/poddoor/preopen{ id = "Secure Gate"; name = "brig shutters" @@ -9503,9 +9459,7 @@ /area/security/brig) "awQ" = ( /obj/structure/table/reinforced, -/obj/item/pen{ - layer = 3 - }, +/obj/item/pen, /obj/machinery/door/poddoor/preopen{ id = "Secure Gate"; name = "brig shutters" @@ -9844,8 +9798,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Captain's Quarters"; - dir = 2 + c_tag = "Captain's Quarters" }, /obj/item/clothing/suit/armor/riot/knight/blue, /obj/item/clothing/head/helmet/knight/blue, @@ -10033,8 +9986,7 @@ /obj/machinery/button/door{ id = "Dorm2Shutters"; name = "Privacy Shutters Control"; - pixel_y = 26; - req_access_txt = "0" + pixel_y = 26 }, /obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/carpet, @@ -10057,7 +10009,6 @@ name = "Dorm Bolt Control"; normaldoorcontrol = 1; pixel_x = 25; - req_access_txt = "0"; specialfunctions = 4 }, /obj/structure/closet/secure_closet/personal/cabinet, @@ -10160,8 +10111,7 @@ /obj/machinery/power/solar_control{ dir = 4; id = "portsolar"; - name = "Port Solar Control"; - track = 0 + name = "Port Solar Control" }, /obj/structure/cable{ icon_state = "0-2" @@ -10526,9 +10476,9 @@ "azo" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/power/apc/highcap/ten_k{ + areastring = "/area/bridge"; dir = 4; name = "Bridge APC"; - areastring = "/area/bridge"; pixel_x = 24 }, /obj/structure/cable{ @@ -11338,9 +11288,9 @@ /area/ai_monitored/turret_protected/ai_upload) "aBx" = ( /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/ai_monitored/turret_protected/ai_upload"; dir = 1; name = "Upload APC"; - areastring = "/area/ai_monitored/turret_protected/ai_upload"; pixel_y = 24 }, /obj/structure/cable{ @@ -11409,8 +11359,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Head of Personnel's Office"; - dir = 2 + c_tag = "Head of Personnel's Office" }, /obj/machinery/newscaster{ pixel_y = 32 @@ -11490,8 +11439,7 @@ /obj/machinery/button/door{ id = "Dorm1Shutters"; name = "Privacy Shutters Control"; - pixel_y = 26; - req_access_txt = "0" + pixel_y = 26 }, /obj/effect/spawner/lootdrop/bedsheet, /turf/open/floor/plasteel/grimy, @@ -11514,7 +11462,6 @@ name = "Dorm Bolt Control"; normaldoorcontrol = 1; pixel_x = 25; - req_access_txt = "0"; specialfunctions = 4 }, /obj/structure/closet/secure_closet/personal/cabinet, @@ -11755,7 +11702,6 @@ /obj/item/analyzer, /obj/machinery/requests_console{ department = "Tool Storage"; - departmentType = 0; pixel_y = 30 }, /obj/effect/turf_decal/tile/neutral{ @@ -12220,7 +12166,6 @@ /area/crew_quarters/dorms) "aDk" = ( /obj/machinery/vr_sleeper{ - icon_state = "sleeper"; dir = 8 }, /turf/open/floor/plasteel/white/corner{ @@ -12627,8 +12572,7 @@ "aEc" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock{ - name = "Dormitories"; - req_access_txt = "0" + name = "Dormitories" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, @@ -12638,8 +12582,7 @@ /area/crew_quarters/toilet/restrooms) "aEe" = ( /obj/machinery/door/airlock{ - name = "Unisex Restrooms"; - req_access_txt = "0" + name = "Unisex Restrooms" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/freezer, @@ -12915,9 +12858,7 @@ /obj/item/aiModule/supplied/oxygen, /obj/item/aiModule/zeroth/oneHuman, /obj/machinery/door/window{ - base_state = "left"; dir = 8; - icon_state = "left"; name = "High-Risk Modules"; req_access_txt = "20" }, @@ -13301,7 +13242,6 @@ /obj/machinery/door/firedoor, /obj/machinery/door/window/northleft{ dir = 2; - icon_state = "left"; name = "Reception Window" }, /obj/machinery/door/poddoor/preopen{ @@ -13377,8 +13317,7 @@ /area/crew_quarters/toilet/restrooms) "aFK" = ( /obj/machinery/door/airlock{ - name = "Unisex Showers"; - req_access_txt = "0" + name = "Unisex Showers" }, /obj/structure/cable{ icon_state = "4-8" @@ -13648,7 +13587,6 @@ dir = 8 }, /obj/machinery/computer/arcade{ - icon_state = "arcade"; dir = 1 }, /turf/open/floor/plasteel/dark, @@ -14057,8 +13995,7 @@ /area/hallway/primary/central) "aHn" = ( /obj/machinery/door/airlock/abandoned{ - name = "Starboard Emergency Storage"; - req_access_txt = "0" + name = "Starboard Emergency Storage" }, /obj/structure/cable{ icon_state = "1-2" @@ -14821,8 +14758,7 @@ /area/hallway/primary/central) "aJn" = ( /obj/machinery/door/airlock{ - name = "Unisex Restrooms"; - req_access_txt = "0" + name = "Unisex Restrooms" }, /obj/structure/cable{ icon_state = "4-8" @@ -14931,8 +14867,7 @@ dir = 8 }, /obj/machinery/camera{ - c_tag = "Departure Lounge Fore"; - dir = 2 + c_tag = "Departure Lounge Fore" }, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -14954,9 +14889,9 @@ dir = 8 }, /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/hallway/secondary/exit/departure_lounge"; dir = 1; name = "Departure Lounge APC"; - areastring = "/area/hallway/secondary/exit/departure_lounge"; pixel_y = 24 }, /obj/structure/cable{ @@ -15234,8 +15169,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Dormitory Cyborg Recharging Station"; - dir = 2 + c_tag = "Dormitory Cyborg Recharging Station" }, /obj/effect/decal/cleanable/oil, /turf/open/floor/plasteel/freezer, @@ -15819,9 +15753,7 @@ pixel_y = -5; req_access_txt = "17" }, -/obj/effect/turf_decal/stripes/corner{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/corner, /obj/effect/turf_decal/tile/blue, /turf/open/floor/plasteel, /area/teleporter) @@ -15866,8 +15798,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Cargo Security Post"; - dir = 2 + c_tag = "Cargo Security Post" }, /obj/machinery/airalarm{ pixel_y = 22 @@ -16036,8 +15967,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Cargo Warehouse"; - dir = 2 + c_tag = "Cargo Warehouse" }, /obj/structure/cable{ icon_state = "4-8" @@ -16059,9 +15989,9 @@ dir = 9 }, /obj/machinery/power/apc{ + areastring = "/area/quartermaster/warehouse"; dir = 4; name = "Cargo Warehouse APC"; - areastring = "/area/quartermaster/warehouse"; pixel_x = 26 }, /obj/structure/cable, @@ -16313,7 +16243,6 @@ "aNa" = ( /obj/structure/cable, /obj/machinery/power/apc{ - dir = 2; name = "Cafeteria APC"; pixel_y = -24 }, @@ -16344,7 +16273,6 @@ "aNe" = ( /obj/structure/cable, /obj/machinery/power/apc/highcap/five_k{ - dir = 2; name = "Auxiliary Restrooms APC"; pixel_y = -24 }, @@ -17819,8 +17747,7 @@ "aQU" = ( /obj/machinery/vending/coffee, /obj/machinery/camera{ - c_tag = "Bar Backroom"; - dir = 2 + c_tag = "Bar Backroom" }, /turf/open/floor/wood, /area/crew_quarters/bar) @@ -17863,7 +17790,6 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ - dir = 2; name = "EVA Storage APC"; pixel_y = -24 }, @@ -18398,7 +18324,6 @@ /obj/structure/disposalpipe/segment, /obj/machinery/door/airlock/mining/glass{ name = "Mailroom"; - req_access_txt = "0"; req_one_access_txt = "48;50" }, /obj/machinery/door/firedoor, @@ -18603,9 +18528,7 @@ location = "Kitchen" }, /obj/machinery/door/window/southleft{ - base_state = "left"; dir = 8; - icon_state = "left"; name = "Kitchen Delivery"; req_access_txt = "28" }, @@ -19009,7 +18932,6 @@ /area/solar/starboard) "aTH" = ( /obj/docking_port/stationary{ - dheight = 0; dir = 8; dwidth = 4; height = 15; @@ -19152,8 +19074,7 @@ /area/crew_quarters/kitchen) "aTZ" = ( /obj/machinery/camera{ - c_tag = "Kitchen Cold Room"; - dir = 2 + c_tag = "Kitchen Cold Room" }, /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 @@ -19270,7 +19191,6 @@ "aUo" = ( /obj/machinery/door/airlock/mining/glass{ name = "Cargo Bay"; - req_access_txt = "0"; req_one_access_txt = "31;48" }, /obj/structure/disposalpipe/segment{ @@ -19615,9 +19535,6 @@ /area/crew_quarters/kitchen) "aVc" = ( /obj/machinery/door/window/southleft{ - base_state = "left"; - dir = 2; - icon_state = "left"; name = "Bar Delivery"; req_access_txt = "25" }, @@ -19894,7 +19811,6 @@ pixel_y = -8 }, /obj/machinery/button/door{ - dir = 2; id = "QMLoaddoor"; layer = 4; name = "Loading Doors"; @@ -20042,7 +19958,6 @@ /area/crew_quarters/kitchen) "aVX" = ( /obj/machinery/power/apc{ - dir = 2; name = "Kitchen APC"; pixel_y = -24 }, @@ -20107,8 +20022,7 @@ receive_ore_updates = 1 }, /obj/machinery/camera{ - c_tag = "Bar Access"; - dir = 2 + c_tag = "Bar Access" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -20535,9 +20449,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, -/obj/machinery/light/small{ - dir = 2 - }, +/obj/machinery/light/small, /turf/open/floor/plasteel/dark, /area/crew_quarters/bar) "aXb" = ( @@ -20553,9 +20465,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/light/small{ - dir = 2 - }, +/obj/machinery/light/small, /turf/open/floor/plasteel/dark, /area/crew_quarters/bar) "aXd" = ( @@ -20623,7 +20533,6 @@ }, /obj/machinery/requests_console{ department = "Theatre"; - departmentType = 0; name = "theatre RC"; pixel_x = -32; pixel_y = -32 @@ -21066,7 +20975,6 @@ "aYd" = ( /obj/machinery/door/airlock{ name = "Service Access"; - req_access_txt = "0"; req_one_access_txt = "25; 26; 28; 35" }, /obj/structure/disposalpipe/segment, @@ -21544,7 +21452,6 @@ pixel_y = 32 }, /obj/item/reagent_containers/food/condiment/saltshaker{ - layer = 3; pixel_x = -2; pixel_y = 2 }, @@ -22270,9 +22177,8 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ - dir = 2; - name = "Cargo Office APC"; areastring = "/area/quartermaster/office"; + name = "Cargo Office APC"; pixel_x = 1; pixel_y = -24 }, @@ -22319,7 +22225,6 @@ dir = 4 }, /obj/machinery/power/apc{ - dir = 2; name = "Cargo Bay APC"; pixel_y = -24 }, @@ -22430,7 +22335,6 @@ dir = 4 }, /obj/machinery/button/door{ - dir = 2; id = "papersplease"; name = "Shutters Control Button"; pixel_x = -26; @@ -22486,7 +22390,6 @@ /area/security/checkpoint/customs) "baU" = ( /obj/machinery/power/apc{ - dir = 2; name = "Security Checkpoint APC"; pixel_x = 1; pixel_y = -24 @@ -22516,7 +22419,6 @@ dir = 8 }, /obj/machinery/button/door{ - dir = 2; id = "jangarage"; name = "Custodial Closet Shutters Control"; pixel_x = 25; @@ -22535,7 +22437,6 @@ dir = 8 }, /obj/machinery/button/door{ - dir = 2; id = "jangarage"; name = "Custodial Closet Shutters Control"; pixel_x = -25; @@ -22691,9 +22592,7 @@ /area/crew_quarters/bar) "bbs" = ( /obj/item/cane, -/obj/item/clothing/head/that{ - throwforce = 1 - }, +/obj/item/clothing/head/that, /obj/structure/table/wood/fancy, /turf/open/floor/carpet{ icon_state = "carpetsymbol" @@ -23304,8 +23203,7 @@ /obj/machinery/power/solar_control{ dir = 8; id = "starboardsolar"; - name = "Starboard Solar Control"; - track = 0 + name = "Starboard Solar Control" }, /obj/structure/cable, /turf/open/floor/plating, @@ -23587,9 +23485,9 @@ icon_state = "0-4" }, /obj/machinery/power/apc{ + areastring = "/area/quartermaster/qm"; dir = 8; name = "Quartermaster APC"; - areastring = "/area/quartermaster/qm"; pixel_x = -24 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ @@ -23653,7 +23551,6 @@ "bdM" = ( /obj/machinery/requests_console{ department = "Mining"; - departmentType = 0; pixel_x = 32 }, /obj/machinery/computer/security/mining{ @@ -25348,7 +25245,6 @@ dir = 4 }, /obj/machinery/button/door{ - dir = 2; id = "Skynet_launch"; name = "Mech Bay Door Control"; pixel_x = 25; @@ -25362,7 +25258,6 @@ dir = 8 }, /obj/machinery/button/door{ - dir = 2; id = "Skynet_launch"; name = "Mech Bay Door Control"; pixel_x = -25; @@ -25550,8 +25445,7 @@ /obj/machinery/door/firedoor, /obj/machinery/door/airlock/research{ name = "Mech Bay"; - req_access_txt = "29"; - req_one_access_txt = "0" + req_access_txt = "29" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -25691,9 +25585,8 @@ pixel_y = 5 }, /obj/machinery/power/apc{ - dir = 2; - name = "Lounge APC"; areastring = "/area/crew_quarters/lounge"; + name = "Lounge APC"; pixel_y = -24 }, /obj/structure/cable, @@ -25770,9 +25663,7 @@ "biW" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/airlock/maintenance{ - name = "Port Emergency Storage"; - req_access_txt = "0"; - req_one_access_txt = "0" + name = "Port Emergency Storage" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper, /turf/open/floor/plating, @@ -25788,7 +25679,6 @@ /obj/machinery/door/firedoor, /obj/machinery/door/airlock/grunge{ name = "Morgue"; - opacity = 1; req_access_txt = "6" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -26291,8 +26181,7 @@ /obj/machinery/door/firedoor, /obj/machinery/door/airlock/research{ name = "Mech Bay"; - req_access_txt = "29"; - req_one_access_txt = "0" + req_access_txt = "29" }, /turf/open/floor/plasteel, /area/science/robotics/lab) @@ -26305,7 +26194,6 @@ "bkz" = ( /obj/machinery/camera{ c_tag = "Experimentation Lab Chamber"; - dir = 2; network = list("ss13","rd") }, /turf/open/floor/engine, @@ -26412,8 +26300,7 @@ }, /obj/machinery/camera{ c_tag = "Genetics Cloning Foyer"; - network = list("ss13","medbay"); - dir = 2 + network = list("ss13","medbay") }, /obj/machinery/atmospherics/components/unary/vent_pump/on, /obj/machinery/power/apc{ @@ -26743,7 +26630,6 @@ "blH" = ( /obj/machinery/camera{ c_tag = "Robotics Lab"; - dir = 2; network = list("ss13","rd") }, /obj/structure/sink/kitchen{ @@ -27003,7 +26889,6 @@ }, /obj/machinery/door/airlock/maintenance{ name = "Genetics Maintenance"; - req_access_txt = "0"; req_one_access_txt = "12;45;5;9" }, /turf/open/floor/plating, @@ -27086,9 +26971,9 @@ /area/medical/morgue) "bms" = ( /obj/machinery/power/apc{ + areastring = "/area/security/checkpoint/medical"; dir = 8; name = "Medbay Security APC"; - areastring = "/area/security/checkpoint/medical"; pixel_x = -25 }, /obj/structure/cable{ @@ -27096,8 +26981,8 @@ }, /obj/machinery/camera{ c_tag = "Medbay Security Post"; - network = list("ss13","medbay"); - dir = 4 + dir = 4; + network = list("ss13","medbay") }, /obj/structure/closet/secure_closet/security/med, /obj/effect/turf_decal/tile/red{ @@ -27489,7 +27374,6 @@ /obj/machinery/door/firedoor, /obj/machinery/door/airlock/medical/glass{ name = "Cloning"; - req_access_txt = "0"; req_one_access_txt = "5;9" }, /obj/structure/cable{ @@ -28028,17 +27912,13 @@ /area/medical/medbay/central) "boH" = ( /obj/machinery/requests_console{ - announcementConsole = 0; department = "Medbay"; departmentType = 1; name = "Medbay RC"; pixel_x = -32 }, /obj/item/radio/intercom{ - broadcasting = 0; - freerange = 0; frequency = 1485; - listening = 1; name = "Station Intercom (Medbay)"; pixel_y = 26 }, @@ -28093,8 +27973,8 @@ /obj/structure/bed/roller, /obj/machinery/camera{ c_tag = "Medbay Entrance"; - network = list("ss13","medbay"); - dir = 1 + dir = 1; + network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -28202,7 +28082,6 @@ dir = 4 }, /obj/machinery/button/door{ - dir = 2; id = "robotics"; name = "Shutters Control Button"; pixel_x = -26; @@ -28252,7 +28131,6 @@ /obj/effect/decal/cleanable/cobweb/cobweb2, /obj/machinery/camera{ c_tag = "Server Room"; - dir = 2; network = list("ss13","rd"); pixel_x = 22 }, @@ -28334,7 +28212,6 @@ /obj/machinery/requests_console{ department = "Science"; departmentType = 2; - dir = 2; name = "Science Requests Console"; pixel_y = 30; receive_ore_updates = 1 @@ -28346,7 +28223,6 @@ /obj/structure/disposalpipe/trunk, /obj/machinery/camera{ c_tag = "Experimentation Lab Central"; - dir = 2; network = list("ss13","rd") }, /obj/effect/turf_decal/tile/neutral{ @@ -28451,10 +28327,7 @@ "bpy" = ( /obj/machinery/clonepod, /obj/item/radio/intercom{ - broadcasting = 0; - freerange = 0; frequency = 1485; - listening = 1; name = "Station Intercom (Medbay)"; pixel_x = -30 }, @@ -28536,7 +28409,6 @@ /obj/machinery/door/firedoor, /obj/machinery/door/airlock/centcom{ name = "Morgue"; - opacity = 1; req_access_txt = "6" }, /obj/structure/cable{ @@ -28568,7 +28440,6 @@ icon_state = "4-8" }, /obj/machinery/light{ - dir = 2; light_color = "#e8eaff" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -28602,7 +28473,6 @@ }, /obj/machinery/door/airlock/grunge{ name = "Morgue"; - opacity = 1; req_access_txt = "6" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -29056,7 +28926,6 @@ "bqH" = ( /obj/machinery/door/window/northleft{ base_state = "right"; - dir = 1; icon_state = "right"; name = "Containment Pen #5"; req_access_txt = "55" @@ -29099,7 +28968,6 @@ "bqK" = ( /obj/machinery/door/window/northleft{ base_state = "right"; - dir = 1; icon_state = "right"; name = "Containment Pen #6"; req_access_txt = "55" @@ -29129,7 +28997,6 @@ /area/science/xenobiology) "bqO" = ( /obj/machinery/door/airlock/maintenance{ - req_access_txt = "0"; req_one_access_txt = "12; 55" }, /obj/structure/cable{ @@ -29141,9 +29008,9 @@ /area/maintenance/department/cargo) "bqS" = ( /obj/machinery/power/apc{ + areastring = "/area/hallway/secondary/entry"; dir = 4; name = "Arrivals APC"; - areastring = "/area/hallway/secondary/entry"; pixel_x = 24 }, /obj/structure/cable{ @@ -29236,7 +29103,6 @@ /obj/machinery/door/airlock/medical/glass{ id_tag = "GeneticsDoor"; name = "Cloning"; - req_access_txt = "0"; req_one_access_txt = "5;9" }, /obj/structure/cable{ @@ -29807,7 +29673,6 @@ "bsf" = ( /obj/machinery/camera{ c_tag = "Xenobiology Starboard"; - dir = 2; network = list("ss13","rd") }, /obj/structure/sign/departments/xenobio{ @@ -29867,8 +29732,8 @@ /obj/machinery/dna_scannernew, /obj/machinery/camera{ c_tag = "Genetics Cloning"; - network = list("ss13","medbay"); - dir = 4 + dir = 4; + network = list("ss13","medbay") }, /obj/machinery/airalarm/unlocked{ dir = 4; @@ -30017,10 +29882,7 @@ /obj/machinery/portable_atmospherics/canister/oxygen, /obj/machinery/atmospherics/components/unary/portables_connector/visible, /obj/item/radio/intercom{ - broadcasting = 0; - freerange = 0; frequency = 1485; - listening = 1; name = "Station Intercom (Medbay)"; pixel_x = 28 }, @@ -30491,8 +30353,7 @@ dir = 4 }, /obj/machinery/door/airlock/external{ - name = "Port Docking Bay 2"; - req_access_txt = "0" + name = "Port Docking Bay 2" }, /turf/open/floor/plating, /area/hallway/secondary/entry) @@ -30501,8 +30362,7 @@ dir = 8 }, /obj/machinery/door/airlock/external{ - name = "Port Docking Bay 2"; - req_access_txt = "0" + name = "Port Docking Bay 2" }, /turf/open/floor/plating, /area/hallway/secondary/entry) @@ -30822,8 +30682,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/airlock/research{ name = "Robotics Lab"; - req_access_txt = "29"; - req_one_access_txt = "0" + req_access_txt = "29" }, /obj/effect/turf_decal/delivery, /obj/machinery/door/firedoor, @@ -31089,8 +30948,8 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/camera{ c_tag = "Medbay Port Hallway"; - network = list("ss13","medbay"); - dir = 4 + dir = 4; + network = list("ss13","medbay") }, /obj/machinery/airalarm{ dir = 4; @@ -31370,7 +31229,6 @@ /obj/effect/turf_decal/stripes/line, /obj/machinery/camera{ c_tag = "Science Access Airlock"; - dir = 2; network = list("ss13","rd") }, /turf/open/floor/plasteel/white, @@ -31608,7 +31466,6 @@ /area/maintenance/department/science) "bwn" = ( /obj/machinery/door/airlock/maintenance{ - req_access_txt = "0"; req_one_access_txt = "12; 55" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -31743,7 +31600,6 @@ /area/medical/genetics) "bwB" = ( /obj/machinery/requests_console{ - announcementConsole = 0; department = "Medbay"; departmentType = 1; name = "Medbay RC"; @@ -32000,7 +31856,6 @@ }, /obj/machinery/door/airlock/research{ name = "R&D Lab"; - req_access_txt = "0"; req_one_access_txt = "7;29;30" }, /obj/effect/turf_decal/delivery, @@ -32194,9 +32049,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 2 - }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on, /turf/open/floor/plasteel/dark, /area/science/explab) "bxw" = ( @@ -32325,7 +32178,6 @@ "bxN" = ( /obj/machinery/door/window/northleft{ base_state = "right"; - dir = 1; icon_state = "right"; name = "Containment Pen #1"; req_access_txt = "55" @@ -32362,7 +32214,6 @@ "bxQ" = ( /obj/machinery/door/window/northleft{ base_state = "right"; - dir = 1; icon_state = "right"; name = "Containment Pen #2"; req_access_txt = "55" @@ -32395,7 +32246,6 @@ "bxS" = ( /obj/machinery/door/window/northleft{ base_state = "right"; - dir = 1; icon_state = "right"; name = "Containment Pen #3"; req_access_txt = "55" @@ -32691,7 +32541,6 @@ }, /obj/machinery/door/airlock/research{ name = "R&D Lab"; - req_access_txt = "0"; req_one_access_txt = "7;29;30" }, /obj/effect/turf_decal/delivery, @@ -33568,8 +33417,7 @@ /obj/structure/disposalpipe/segment, /obj/machinery/door/airlock/research{ name = "Research Director's Office"; - req_access_txt = "30"; - req_one_access_txt = "0" + req_access_txt = "30" }, /obj/machinery/door/firedoor, /obj/structure/cable{ @@ -33814,7 +33662,6 @@ }, /obj/machinery/requests_console{ department = "Genetics"; - departmentType = 0; name = "Genetics Requests Console"; pixel_x = 32 }, @@ -34206,7 +34053,6 @@ "bBF" = ( /obj/machinery/portable_atmospherics/scrubber/huge, /obj/machinery/airalarm{ - dir = 2; pixel_y = 22 }, /turf/open/floor/engine, @@ -34335,7 +34181,6 @@ /obj/machinery/atmospherics/components/unary/portables_connector/visible, /obj/machinery/camera{ c_tag = "Toxins Lab Starboard"; - dir = 2; network = list("ss13","rd") }, /obj/machinery/light{ @@ -34494,8 +34339,7 @@ /obj/structure/closet/emcloset, /obj/machinery/camera{ c_tag = "Virology Airlock"; - network = list("ss13","medbay"); - dir = 2 + network = list("ss13","medbay") }, /obj/effect/turf_decal/stripes/line{ dir = 5 @@ -35056,9 +34900,7 @@ /turf/open/space, /area/space/nearstation) "bDg" = ( -/obj/machinery/atmospherics/components/unary/tank/air{ - dir = 2 - }, +/obj/machinery/atmospherics/components/unary/tank/air, /turf/open/floor/plating, /area/maintenance/department/engine) "bDh" = ( @@ -35214,9 +35056,9 @@ /area/crew_quarters/heads/cmo) "bDx" = ( /obj/machinery/power/apc{ + areastring = "/area/crew_quarters/heads/cmo"; dir = 4; name = "CMO's Office APC"; - areastring = "/area/crew_quarters/heads/cmo"; pixel_x = 26 }, /obj/structure/cable, @@ -36346,7 +36188,6 @@ normaldoorcontrol = 1; pixel_x = 25; pixel_y = 4; - req_access_txt = "0"; specialfunctions = 4 }, /turf/open/floor/plating, @@ -36453,7 +36294,6 @@ pixel_y = 2 }, /obj/machinery/requests_console{ - announcementConsole = 0; department = "Medbay"; departmentType = 1; name = "Medbay RC"; @@ -36899,9 +36739,7 @@ /turf/open/floor/plating, /area/chapel/dock) "bGG" = ( -/obj/machinery/atmospherics/components/unary/outlet_injector/on{ - dir = 2 - }, +/obj/machinery/atmospherics/components/unary/outlet_injector/on, /obj/structure/window/reinforced, /obj/structure/window/reinforced{ dir = 8; @@ -37022,10 +36860,7 @@ dir = 4 }, /obj/item/radio/intercom{ - broadcasting = 0; - freerange = 0; frequency = 1485; - listening = 1; name = "Station Intercom (Medbay)"; pixel_x = -28 }, @@ -37385,7 +37220,6 @@ /area/science/mixing) "bHC" = ( /obj/machinery/atmospherics/components/binary/pump{ - dir = 2; name = "Incinerator Output Pump" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -37405,12 +37239,8 @@ /area/science/mixing) "bHE" = ( /obj/structure/window/reinforced, -/obj/machinery/doppler_array/research/science{ - dir = 2 - }, -/obj/effect/turf_decal/bot{ - dir = 2 - }, +/obj/machinery/doppler_array/research/science, +/obj/effect/turf_decal/bot, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 9 }, @@ -37516,8 +37346,7 @@ "bHY" = ( /obj/machinery/camera{ c_tag = "Virology"; - network = list("ss13","medbay"); - dir = 2 + network = list("ss13","medbay") }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -37552,10 +37381,7 @@ "bIb" = ( /obj/machinery/atmospherics/pipe/simple/cyan/hidden, /obj/item/radio/intercom{ - broadcasting = 0; - freerange = 0; frequency = 1485; - listening = 1; name = "Station Intercom (Medbay)"; pixel_x = 28 }, @@ -37589,8 +37415,8 @@ /obj/machinery/light, /obj/machinery/camera{ c_tag = "Medbay Equipment Room"; - network = list("ss13","medbay"); - dir = 1 + dir = 1; + network = list("ss13","medbay") }, /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/blue{ @@ -37670,17 +37496,14 @@ "bIm" = ( /obj/machinery/camera{ c_tag = "Medbay Recovery Room"; - network = list("ss13","medbay"); - dir = 8 + dir = 8; + network = list("ss13","medbay") }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /obj/item/radio/intercom{ - broadcasting = 0; - freerange = 0; frequency = 1485; - listening = 1; name = "Station Intercom (Medbay)"; pixel_x = 28 }, @@ -37733,7 +37556,6 @@ }, /obj/machinery/camera{ c_tag = "Surgery"; - dir = 2; network = list("ss13","surgery") }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -37938,11 +37760,9 @@ /turf/open/floor/engine, /area/science/storage) "bIK" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 2 - }, -/turf/closed/wall/r_wall, -/area/science/mixing) +/obj/effect/landmark/start/cyborg, +/turf/open/floor/plasteel/dark, +/area/ai_monitored/turret_protected/aisat_interior) "bIL" = ( /obj/machinery/door/airlock/research/glass/incinerator/toxmix_interior, /turf/open/floor/engine, @@ -38019,9 +37839,7 @@ /turf/open/floor/plasteel/dark, /area/chapel/dock) "bIX" = ( -/obj/machinery/atmospherics/components/unary/tank/air{ - dir = 2 - }, +/obj/machinery/atmospherics/components/unary/tank/air, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -38200,7 +38018,6 @@ /area/medical/virology) "bJo" = ( /obj/machinery/requests_console{ - announcementConsole = 0; department = "Medbay"; departmentType = 1; name = "Medbay RC"; @@ -38359,9 +38176,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/stripes/corner{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/corner, /obj/effect/turf_decal/tile/green, /obj/effect/turf_decal/tile/green{ dir = 8 @@ -38402,9 +38217,7 @@ c_tag = "Research Division Entrance"; dir = 1 }, -/obj/machinery/light{ - dir = 2 - }, +/obj/machinery/light, /obj/effect/turf_decal/tile/green, /obj/effect/turf_decal/tile/green{ dir = 8 @@ -38494,9 +38307,7 @@ /turf/closed/wall/r_wall, /area/engine/atmos) "bJQ" = ( -/obj/machinery/atmospherics/components/binary/pump/on{ - dir = 2 - }, +/obj/machinery/atmospherics/components/binary/pump/on, /obj/machinery/light/small{ dir = 8 }, @@ -38530,8 +38341,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/effect/mapping_helpers/airlock/cyclelink_helper, /obj/machinery/door/airlock/external{ - req_access_txt = "8"; - req_one_access_txt = "0" + req_access_txt = "8" }, /turf/open/floor/plating, /area/science/mixing) @@ -38739,8 +38549,7 @@ pixel_y = 25 }, /obj/machinery/camera{ - c_tag = "Patient Room"; - dir = 2 + c_tag = "Patient Room" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -38908,7 +38717,6 @@ dir = 4 }, /obj/machinery/airalarm{ - dir = 2; pixel_y = 22 }, /obj/structure/cable{ @@ -39092,8 +38900,7 @@ /area/chapel/dock) "bLq" = ( /obj/machinery/door/airlock/grunge{ - name = "Monastery Transit"; - opacity = 1 + name = "Monastery Transit" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -39172,8 +38979,7 @@ /obj/structure/table, /obj/structure/disposalpipe/segment, /obj/item/stack/sheet/mineral/plasma{ - amount = 2; - layer = 3 + amount = 2 }, /obj/item/storage/box/monkeycubes{ layer = 3.1 @@ -39201,9 +39007,7 @@ /area/medical/virology) "bLF" = ( /obj/structure/table, -/obj/item/clipboard{ - toppaper = null - }, +/obj/item/clipboard, /obj/item/pen{ layer = 3.1 }, @@ -39480,7 +39284,6 @@ "bMh" = ( /obj/machinery/computer/atmos_control/tank{ dir = 8; - frequency = 1441; input_tag = "mix_in"; name = "Gas Mix Tank Control"; output_tag = "mix_in"; @@ -39498,7 +39301,6 @@ /area/engine/atmos) "bMj" = ( /obj/machinery/air_sensor{ - frequency = 1441; id_tag = "mix_sensor" }, /turf/open/floor/engine/vacuum, @@ -39539,8 +39341,7 @@ dir = 1 }, /obj/machinery/door/airlock/external{ - req_access_txt = "8"; - req_one_access_txt = "0" + req_access_txt = "8" }, /turf/open/floor/plating, /area/science/mixing) @@ -39849,7 +39650,6 @@ "bMU" = ( /obj/machinery/camera{ c_tag = "Aft Primary Hallway Atmospherics"; - dir = 2; start_active = 1 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -40833,8 +40633,7 @@ /area/space/nearstation) "bPn" = ( /obj/machinery/door/airlock/grunge{ - name = "Chapel"; - opacity = 1 + name = "Chapel" }, /obj/structure/cable{ icon_state = "1-2" @@ -40853,8 +40652,7 @@ /area/chapel/dock) "bPo" = ( /obj/machinery/door/airlock/grunge{ - name = "Chapel"; - opacity = 1 + name = "Chapel" }, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -41088,7 +40886,6 @@ "bPX" = ( /obj/machinery/computer/atmos_control/tank{ dir = 8; - frequency = 1441; input_tag = "n2o_in"; name = "Nitrous Oxide Supply Control"; output_tag = "n2o_out"; @@ -41107,7 +40904,6 @@ /area/engine/atmos) "bPZ" = ( /obj/machinery/air_sensor{ - frequency = 1441; id_tag = "n2o_sensor" }, /turf/open/floor/engine/n2o, @@ -41192,8 +40988,7 @@ /area/engine/gravity_generator) "bQo" = ( /obj/machinery/camera{ - c_tag = "Gravity Generator"; - dir = 2 + c_tag = "Gravity Generator" }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 4 @@ -41290,13 +41085,11 @@ light_color = "#cee5d2" }, /obj/machinery/camera{ - c_tag = "Tech Storage"; - dir = 2 + c_tag = "Tech Storage" }, /obj/item/circuitboard/computer/monastery_shuttle, /obj/effect/spawner/lootdrop/techstorage/service, /obj/machinery/airalarm{ - dir = 2; pixel_y = 22 }, /obj/effect/turf_decal/tile/green{ @@ -41379,8 +41172,8 @@ /area/storage/tech) "bQB" = ( /obj/machinery/power/apc{ - name = "Aft Hall APC"; dir = 8; + name = "Aft Hall APC"; pixel_x = -25; pixel_y = 1 }, @@ -41415,7 +41208,6 @@ /obj/machinery/door/firedoor/heavy, /obj/machinery/door/window/northleft{ dir = 4; - icon_state = "left"; name = "Atmospherics Desk"; req_access_txt = "24" }, @@ -41469,12 +41261,8 @@ dir = 4 }, /obj/machinery/portable_atmospherics/canister, -/obj/effect/turf_decal/bot{ - dir = 2 - }, -/turf/open/floor/plasteel{ - dir = 2 - }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, /area/engine/atmos) "bQL" = ( /obj/machinery/atmospherics/pipe/manifold/general/visible{ @@ -41486,17 +41274,12 @@ /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 8 }, -/obj/effect/turf_decal/bot{ - dir = 2 - }, -/turf/open/floor/plasteel{ - dir = 2 - }, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, /area/engine/atmos) "bQN" = ( /obj/machinery/atmospherics/components/trinary/filter/atmos/n2o{ - dir = 1; - on = 1 + dir = 1 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -41631,7 +41414,6 @@ dir = 1 }, /obj/machinery/airalarm{ - dir = 2; pixel_y = 22 }, /obj/effect/turf_decal/stripes/line{ @@ -41642,8 +41424,7 @@ "bRe" = ( /obj/structure/closet/radiation, /obj/machinery/camera{ - c_tag = "Gravity Generator Foyer"; - dir = 2 + c_tag = "Gravity Generator Foyer" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -41697,9 +41478,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/effect/turf_decal/stripes/corner{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/corner, /obj/structure/cable{ icon_state = "4-8" }, @@ -41778,7 +41557,6 @@ /obj/machinery/door/firedoor/heavy, /obj/machinery/door/window/northleft{ dir = 4; - icon_state = "left"; name = "Atmospherics Desk"; req_access_txt = "24" }, @@ -42506,7 +42284,6 @@ "bSV" = ( /obj/machinery/computer/atmos_control/tank{ dir = 8; - frequency = 1441; input_tag = "tox_in"; name = "Plasma Supply Control"; output_tag = "tox_out"; @@ -42520,7 +42297,6 @@ /area/engine/atmos) "bSW" = ( /obj/machinery/air_sensor{ - frequency = 1441; id_tag = "tox_sensor" }, /turf/open/floor/engine/plasma, @@ -42575,7 +42351,6 @@ /area/maintenance/department/engine) "bTf" = ( /obj/machinery/atmospherics/components/binary/pump/on{ - dir = 2; name = "Virology Waste to Space" }, /turf/open/floor/plating{ @@ -42584,7 +42359,6 @@ /area/maintenance/department/engine) "bTg" = ( /obj/machinery/atmospherics/components/binary/pump{ - dir = 2; name = "Virology Waste to Atmospherics" }, /turf/open/floor/plating, @@ -42665,9 +42439,7 @@ pixel_y = 1 }, /obj/structure/table, -/obj/item/paper/guides/jobs/engi/gravity_gen{ - layer = 3 - }, +/obj/item/paper/guides/jobs/engi/gravity_gen, /obj/item/pen/blue, /obj/machinery/power/terminal{ dir = 8 @@ -42822,9 +42594,8 @@ /area/storage/tech) "bTB" = ( /obj/machinery/power/apc{ - dir = 2; - name = "Tech Storage APC"; areastring = "/area/storage/tech"; + name = "Tech Storage APC"; pixel_y = -24 }, /obj/structure/cable, @@ -42912,8 +42683,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Atmospherics Entrance"; - dir = 2 + c_tag = "Atmospherics Entrance" }, /obj/effect/turf_decal/tile/yellow{ dir = 1 @@ -42988,8 +42758,7 @@ }, /obj/structure/reagent_dispensers/fueltank, /obj/machinery/camera{ - c_tag = "Atmospherics Mixing"; - dir = 2 + c_tag = "Atmospherics Mixing" }, /obj/effect/turf_decal/tile/yellow{ dir = 1 @@ -43019,8 +42788,7 @@ /area/engine/atmos) "bTU" = ( /obj/machinery/atmospherics/components/trinary/filter/atmos/plasma{ - dir = 1; - on = 1 + dir = 1 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -43346,8 +43114,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Chief Engineer's Office"; - dir = 2 + c_tag = "Chief Engineer's Office" }, /obj/machinery/computer/security/telescreen/ce{ pixel_y = 30 @@ -43362,7 +43129,6 @@ /area/crew_quarters/heads/chief) "bUK" = ( /obj/machinery/airalarm{ - dir = 2; pixel_y = 22 }, /obj/machinery/computer/apc_control, @@ -43437,8 +43203,7 @@ }, /obj/machinery/power/smes/engineering, /obj/machinery/camera{ - c_tag = "Engineering Power Storage"; - dir = 2 + c_tag = "Engineering Power Storage" }, /obj/effect/turf_decal/tile/yellow{ dir = 1 @@ -43891,9 +43656,9 @@ pixel_y = 4 }, /obj/machinery/power/apc{ + areastring = "/area/security/checkpoint/engineering"; dir = 8; name = "Engineering Security APC"; - areastring = "/area/security/checkpoint/engineering"; pixel_x = -24 }, /obj/structure/cable{ @@ -44115,7 +43880,6 @@ dir = 8 }, /obj/machinery/light_switch{ - dir = 2; pixel_x = 22 }, /obj/effect/turf_decal/tile/yellow, @@ -44436,8 +44200,7 @@ /area/chapel/main/monastery) "bWW" = ( /obj/machinery/door/airlock/grunge{ - name = "Chapel"; - opacity = 1 + name = "Chapel" }, /obj/structure/cable{ icon_state = "1-2" @@ -44446,8 +44209,7 @@ /area/chapel/main/monastery) "bWX" = ( /obj/machinery/door/airlock/grunge{ - name = "Chapel"; - opacity = 1 + name = "Chapel" }, /turf/open/floor/plasteel/dark, /area/chapel/main/monastery) @@ -44551,9 +44313,9 @@ /obj/item/stack/rods/fifty, /obj/item/stack/cable_coil, /obj/machinery/power/apc/highcap/ten_k{ + areastring = "/area/engine/engine_smes"; dir = 8; name = "Engine Room APC"; - areastring = "/area/engine/engine_smes"; pixel_x = -26 }, /obj/structure/cable, @@ -45100,8 +44862,7 @@ dir = 4 }, /obj/machinery/camera{ - c_tag = "Engineering Port Fore"; - dir = 2 + c_tag = "Engineering Port Fore" }, /obj/structure/sign/map{ icon_state = "map-pubby"; @@ -45183,7 +44944,6 @@ dir = 4 }, /obj/machinery/airalarm{ - dir = 2; pixel_y = 22 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -45339,8 +45099,7 @@ dir = 4 }, /obj/machinery/camera{ - c_tag = "Engineering Starboard Fore"; - dir = 2 + c_tag = "Engineering Starboard Fore" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -45411,7 +45170,6 @@ pixel_x = -24 }, /obj/machinery/airalarm{ - dir = 2; pixel_y = 22 }, /obj/structure/cable{ @@ -45912,9 +45670,7 @@ /obj/structure/cable/yellow{ icon_state = "4-8" }, -/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_atmos{ - dir = 2 - }, +/obj/machinery/atmospherics/components/binary/dp_vent_pump/high_volume/incinerator_atmos, /turf/open/floor/engine, /area/maintenance/disposal/incinerator) "caN" = ( @@ -45950,7 +45706,6 @@ }, /obj/machinery/camera{ c_tag = "Turbine Chamber"; - dir = 2; network = list("turbine") }, /turf/open/floor/engine, @@ -46257,8 +46012,7 @@ /area/chapel/main/monastery) "cbR" = ( /obj/machinery/door/airlock/grunge{ - name = "Chapel Access"; - opacity = 1 + name = "Chapel Access" }, /turf/open/floor/plasteel/dark, /area/chapel/main/monastery) @@ -46390,7 +46144,6 @@ /area/maintenance/disposal/incinerator) "ccr" = ( /obj/machinery/atmospherics/components/binary/pump/on{ - dir = 2; name = "Incinerator Output Pump" }, /obj/effect/turf_decal/tile/yellow, @@ -46617,7 +46370,6 @@ }, /obj/machinery/camera{ c_tag = "Chapel Port Access"; - dir = 2; network = list("ss13","monastery") }, /turf/open/floor/plasteel/dark, @@ -46770,7 +46522,6 @@ "ceg" = ( /obj/machinery/door/airlock/centcom{ name = "Chapel Office"; - opacity = 1; req_access_txt = "22" }, /obj/structure/cable{ @@ -46790,8 +46541,7 @@ /area/chapel/office) "cei" = ( /obj/machinery/door/airlock/grunge{ - name = "Chapel"; - opacity = 1 + name = "Chapel" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -46803,24 +46553,21 @@ /area/chapel/main/monastery) "cej" = ( /obj/machinery/door/airlock/grunge{ - name = "Chapel"; - opacity = 1 + name = "Chapel" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, /area/chapel/main/monastery) "cek" = ( /obj/machinery/door/airlock/grunge{ - name = "Chapel"; - opacity = 1 + name = "Chapel" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/dark, /area/chapel/main/monastery) "cel" = ( /obj/machinery/door/airlock/grunge{ - name = "Chapel Access"; - opacity = 1 + name = "Chapel Access" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel/dark, @@ -46903,7 +46650,6 @@ }, /obj/machinery/camera{ c_tag = "Chapel Crematorium"; - dir = 2; network = list("ss13","monastery") }, /turf/open/floor/plasteel/dark, @@ -46993,7 +46739,6 @@ }, /obj/machinery/computer/security/telescreen{ desc = "Used for watching telecomms."; - dir = 2; layer = 4; name = "Telecomms Telescreen"; network = list("tcomms"); @@ -47055,8 +46800,7 @@ /area/chapel/office) "cfl" = ( /obj/machinery/door/airlock/grunge{ - name = "Chapel Access"; - opacity = 1 + name = "Chapel Access" }, /obj/structure/cable{ icon_state = "1-2" @@ -47359,7 +47103,6 @@ /obj/structure/flora/ausbushes/sparsegrass, /obj/machinery/camera{ c_tag = "Monastery Garden"; - dir = 2; network = list("ss13","monastery") }, /turf/open/floor/grass, @@ -48035,8 +47778,7 @@ /area/chapel/main/monastery) "cjl" = ( /obj/machinery/door/airlock/grunge{ - name = "Monastery Cemetary"; - opacity = 1 + name = "Monastery Cemetary" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -48116,8 +47858,7 @@ /area/chapel/main/monastery) "cjH" = ( /obj/machinery/door/airlock/grunge{ - name = "Chapel Garden"; - opacity = 1 + name = "Chapel Garden" }, /turf/open/floor/plasteel/dark, /area/chapel/main/monastery) @@ -48832,9 +48573,9 @@ /area/tcommsat/computer) "cmk" = ( /obj/machinery/power/apc{ + areastring = "/area/tcommsat/computer"; dir = 1; name = "Telecomms Monitoring APC"; - areastring = "/area/tcommsat/computer"; pixel_y = 25 }, /obj/structure/cable{ @@ -49239,7 +48980,6 @@ /obj/structure/lattice, /obj/machinery/camera/motion{ c_tag = "Telecomms External Port Aft"; - dir = 2; network = list("tcomms") }, /turf/open/space, @@ -49248,7 +48988,6 @@ /obj/structure/lattice, /obj/machinery/camera/motion{ c_tag = "Telecomms External Starboard Aft"; - dir = 2; network = list("tcomms") }, /turf/open/space, @@ -49266,6 +49005,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/effect/landmark/start/cyborg, /turf/open/floor/plasteel/dark, /area/ai_monitored/turret_protected/aisat_interior) "cnD" = ( @@ -49292,8 +49032,7 @@ "cnN" = ( /obj/structure/closet/secure_closet/security/sec, /obj/machinery/camera{ - c_tag = "Brig Equipment Room"; - dir = 2 + c_tag = "Brig Equipment Room" }, /obj/item/radio/intercom{ name = "Station Intercom (General)"; @@ -49413,8 +49152,7 @@ /obj/structure/disposalpipe/segment, /obj/machinery/door/firedoor, /obj/machinery/door/airlock{ - name = "Dormitories"; - req_access_txt = "0" + name = "Dormitories" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, @@ -49424,8 +49162,7 @@ dir = 8 }, /obj/machinery/door/airlock/external{ - name = "public external airlock"; - req_access_txt = "0" + name = "public external airlock" }, /turf/open/floor/plating, /area/storage/emergency/starboard) @@ -49595,8 +49332,7 @@ /obj/machinery/chem_dispenser/drinks, /obj/structure/table, /obj/machinery/camera{ - c_tag = "Bar Drinks"; - dir = 2 + c_tag = "Bar Drinks" }, /turf/open/floor/plasteel/dark, /area/crew_quarters/bar) @@ -50046,9 +49782,7 @@ c_tag = "Research Division Hallway"; dir = 1 }, -/obj/machinery/light{ - dir = 2 - }, +/obj/machinery/light, /obj/effect/turf_decal/tile/purple, /obj/effect/turf_decal/tile/purple{ dir = 8 @@ -50538,7 +50272,6 @@ "csC" = ( /obj/structure/table/wood, /obj/item/reagent_containers/food/drinks/bottle/holywater{ - name = "flask of holy water"; pixel_x = -2; pixel_y = 2 }, @@ -50641,7 +50374,6 @@ }, /obj/machinery/camera{ c_tag = "Chapel Starboard Access"; - dir = 2; network = list("ss13","monastery") }, /obj/structure/chair/wood/normal, @@ -50732,9 +50464,7 @@ /turf/open/floor/plasteel/dark, /area/chapel/office) "ctu" = ( -/obj/machinery/light/small{ - dir = 2 - }, +/obj/machinery/light/small, /obj/effect/turf_decal/tile/yellow{ dir = 4 }, @@ -50814,7 +50544,6 @@ }, /obj/machinery/camera{ c_tag = "Monastery Cloister Fore"; - dir = 2; network = list("ss13","monastery") }, /obj/effect/turf_decal/tile/neutral{ @@ -51047,9 +50776,7 @@ /area/hydroponics/garden/monastery) "cuG" = ( /obj/structure/closet/secure_closet/freezer/fridge, -/obj/machinery/light/small{ - dir = 2 - }, +/obj/machinery/light/small, /turf/open/floor/plasteel, /area/chapel/main/monastery) "cuH" = ( @@ -51887,9 +51614,7 @@ /turf/open/floor/plasteel/dark, /area/library/lounge) "cxD" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/corner, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 5 }, @@ -52116,7 +51841,6 @@ }, /obj/machinery/camera{ c_tag = "Monastery Archives Fore"; - dir = 2; network = list("ss13","monastery") }, /obj/machinery/firealarm{ @@ -52447,9 +52171,7 @@ dir = 4 }, /obj/machinery/door/window/northright{ - base_state = "right"; dir = 2; - icon_state = "right"; name = "Curator Desk Door"; req_access_txt = "37" }, @@ -52625,8 +52347,7 @@ /obj/machinery/button/door{ id = "supplybridge"; name = "Space Bridge Control"; - pixel_y = 27; - req_access_txt = "0" + pixel_y = 27 }, /turf/open/floor/plating, /area/maintenance/department/crew_quarters/dorms) @@ -52860,9 +52581,7 @@ /turf/open/floor/plasteel, /area/science/xenobiology) "cPy" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 2 - }, +/obj/machinery/atmospherics/components/binary/pump, /obj/structure/sign/warning/nosmoking{ pixel_x = -32; pixel_y = 32 @@ -52935,7 +52654,6 @@ /obj/effect/turf_decal/delivery, /obj/machinery/door/window/eastright{ base_state = "left"; - dir = 4; icon_state = "left"; name = "Research Division Delivery"; req_access_txt = "47" @@ -52972,7 +52690,6 @@ /area/maintenance/disposal) "dbi" = ( /obj/machinery/vr_sleeper{ - icon_state = "sleeper"; dir = 8 }, /turf/open/floor/plasteel, @@ -53090,7 +52807,6 @@ /area/science/xenobiology) "dnS" = ( /obj/machinery/atmospherics/components/binary/pump{ - dir = 2; name = "Mix Bypass" }, /obj/structure/cable/yellow{ @@ -53152,7 +52868,6 @@ /area/quartermaster/qm) "dqw" = ( /obj/machinery/door/airlock/maintenance{ - req_access_txt = "0"; req_one_access_txt = "12; 55" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -53678,7 +53393,6 @@ /area/medical/sleeper) "eFG" = ( /obj/machinery/mineral/stacking_unit_console{ - dir = 2; machinedir = 8; pixel_x = -32; pixel_y = 32 @@ -53858,9 +53572,7 @@ /area/hallway/primary/aft) "fdS" = ( /obj/machinery/door/window/southleft{ - base_state = "left"; dir = 4; - icon_state = "left"; name = "Engineering Delivery"; req_access_txt = "10" }, @@ -54249,7 +53961,6 @@ "gam" = ( /obj/machinery/door/airlock/medical/glass{ name = "Service Door"; - req_access_txt = "0"; req_one_access_txt = "35;28" }, /obj/machinery/door/poddoor/shutters/preopen{ @@ -54595,7 +54306,6 @@ pixel_y = 3 }, /obj/machinery/button/door{ - dir = 2; id = "research_shutters_2"; name = "Shutters Control Button"; pixel_x = -28; @@ -55007,7 +54717,6 @@ "hDG" = ( /obj/machinery/door/airlock/engineering{ name = "Auxillary Base Construction"; - req_access_txt = "0"; req_one_access_txt = "32;47;48" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -55433,7 +55142,6 @@ icon_state = "secbot1"; idcheck = 1; name = "Sergeant-at-Armsky"; - on = 1; weaponscheck = 1 }, /turf/open/floor/plasteel/dark, @@ -55477,8 +55185,8 @@ /area/crew_quarters/dorms) "izF" = ( /turf/open/floor/plating{ - luminosity = 2; - initial_gas_mix = "o2=0.01;n2=0.01" + initial_gas_mix = "o2=0.01;n2=0.01"; + luminosity = 2 }, /area/maintenance/department/science) "iAx" = ( @@ -55622,7 +55330,6 @@ /area/science/xenobiology) "iPH" = ( /obj/machinery/vr_sleeper{ - icon_state = "sleeper"; dir = 8 }, /obj/effect/turf_decal/tile/blue{ @@ -55761,7 +55468,6 @@ dir = 1 }, /obj/machinery/requests_console{ - announcementConsole = 0; department = "Engineering"; departmentType = 4; name = "Engineering RC"; @@ -56083,9 +55789,7 @@ /area/science/mixing) "kfM" = ( /obj/structure/closet, -/obj/machinery/light/small{ - dir = 2 - }, +/obj/machinery/light/small, /obj/item/storage/book/bible, /obj/item/storage/book/bible, /obj/item/storage/book/bible, @@ -56236,7 +55940,6 @@ dir = 1 }, /obj/machinery/airalarm{ - dir = 2; pixel_y = 22 }, /obj/effect/turf_decal/tile/yellow{ @@ -56264,9 +55967,7 @@ /turf/open/floor/plasteel/dark, /area/hallway/secondary/exit/departure_lounge) "kDf" = ( -/obj/machinery/light/small{ - dir = 2 - }, +/obj/machinery/light/small, /turf/open/floor/carpet/black, /area/chapel/office) "kDJ" = ( @@ -56405,7 +56106,6 @@ "kNf" = ( /obj/machinery/door/window/northleft{ base_state = "right"; - dir = 1; icon_state = "right"; name = "Containment Pen #4"; req_access_txt = "55" @@ -56491,9 +56191,7 @@ /area/engine/engineering) "kSO" = ( /obj/machinery/door/airlock/maintenance{ - name = "Port Emergency Storage"; - req_access_txt = "0"; - req_one_access_txt = "0" + name = "Port Emergency Storage" }, /turf/open/floor/plating, /area/storage/emergency/port) @@ -56800,8 +56498,7 @@ /area/hallway/primary/aft) "lKL" = ( /obj/machinery/door/airlock/abandoned{ - name = "Starboard Emergency Storage"; - req_access_txt = "0" + name = "Starboard Emergency Storage" }, /obj/structure/cable{ icon_state = "1-2" @@ -57203,9 +56900,7 @@ /area/bridge) "mzl" = ( /obj/structure/chair, -/obj/machinery/atmospherics/components/unary/outlet_injector/on{ - dir = 2 - }, +/obj/machinery/atmospherics/components/unary/outlet_injector/on, /turf/open/floor/plating, /area/security/execution/transfer) "mzU" = ( @@ -57428,7 +57123,6 @@ "nku" = ( /obj/machinery/door/airlock/centcom{ name = "Crematorium"; - opacity = 1; req_access_txt = "27" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -57485,9 +57179,9 @@ dir = 1 }, /obj/machinery/power/apc{ + areastring = "/area/construction/mining/aux_base"; dir = 8; name = "Auxillary Base Construction APC"; - areastring = "/area/construction/mining/aux_base"; pixel_x = -24 }, /obj/structure/cable{ @@ -57559,8 +57253,8 @@ dir = 6 }, /turf/open/floor/plating{ - luminosity = 2; - initial_gas_mix = "o2=0.01;n2=0.01" + initial_gas_mix = "o2=0.01;n2=0.01"; + luminosity = 2 }, /area/maintenance/department/science) "nAs" = ( @@ -57698,7 +57392,6 @@ }, /obj/machinery/camera/motion{ c_tag = "Telecomms Monitoring"; - dir = 2; network = list("tcomms") }, /obj/structure/cable{ @@ -57829,8 +57522,8 @@ /obj/item/paper_bin, /obj/item/pen, /turf/open/floor/plating{ - luminosity = 2; - initial_gas_mix = "o2=0.01;n2=0.01" + initial_gas_mix = "o2=0.01;n2=0.01"; + luminosity = 2 }, /area/maintenance/department/science) "odM" = ( @@ -57934,9 +57627,7 @@ /obj/item/paper_bin{ layer = 2.9 }, -/obj/effect/turf_decal/stripes/corner{ - dir = 2 - }, +/obj/effect/turf_decal/stripes/corner, /obj/structure/window/reinforced, /turf/open/floor/plasteel, /area/science/xenobiology) @@ -57976,8 +57667,7 @@ dir = 4 }, /obj/machinery/camera{ - c_tag = "Arrivals Port Fore"; - dir = 2 + c_tag = "Arrivals Port Fore" }, /obj/effect/turf_decal/tile/blue{ dir = 4 @@ -58505,7 +58195,6 @@ /area/engine/supermatter) "psd" = ( /obj/machinery/atmospherics/components/binary/pump{ - dir = 2; name = "Gas to Filter" }, /obj/effect/decal/cleanable/dirt, @@ -58671,7 +58360,6 @@ /obj/structure/closet/firecloset, /obj/machinery/camera{ c_tag = "Toxins Launch Area"; - dir = 2; network = list("ss13","rd") }, /obj/structure/sign/poster/official/random{ @@ -58806,7 +58494,6 @@ /area/maintenance/department/engine) "qar" = ( /obj/structure/chair/office/light{ - icon_state = "officechair_white"; dir = 4 }, /turf/open/floor/plasteel/white, @@ -59345,8 +59032,8 @@ dir = 4 }, /turf/open/floor/plating{ - luminosity = 2; - initial_gas_mix = "o2=0.01;n2=0.01" + initial_gas_mix = "o2=0.01;n2=0.01"; + luminosity = 2 }, /area/maintenance/department/science) "rrb" = ( @@ -59404,9 +59091,7 @@ location = "Medbay" }, /obj/machinery/door/window/southleft{ - base_state = "left"; dir = 4; - icon_state = "left"; name = "Medbay Delivery"; req_access_txt = "28" }, @@ -59485,7 +59170,6 @@ /obj/docking_port/stationary{ area_type = /area/construction/mining/aux_base; dheight = 4; - dir = 1; dwidth = 4; height = 9; id = "aux_base_zone"; @@ -59518,8 +59202,7 @@ /obj/machinery/button/door{ id = "shootshut"; name = "shutters control"; - pixel_x = 28; - req_access_txt = "0" + pixel_x = 28 }, /obj/item/ammo_casing/shotgun/improvised, /turf/open/floor/plating, @@ -59577,8 +59260,7 @@ dir = 4 }, /obj/machinery/door/airlock/external{ - name = "public external airlock"; - req_access_txt = "0" + name = "public external airlock" }, /turf/open/floor/plating, /area/storage/emergency/starboard) @@ -59937,7 +59619,6 @@ }, /obj/machinery/door/airlock/centcom{ name = "Chapel Office"; - opacity = 1; req_access_txt = "22" }, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -60132,7 +59813,6 @@ id = "aux_base_shutters"; name = "Public Shutters Control"; pixel_x = -26; - req_access_txt = "0"; req_one_access_txt = "32;47;48" }, /obj/effect/turf_decal/stripes/line, @@ -60416,7 +60096,6 @@ /area/science/xenobiology) "ugC" = ( /obj/structure/chair/office/light{ - icon_state = "officechair_white"; dir = 4 }, /obj/effect/turf_decal/tile/purple{ @@ -60493,8 +60172,8 @@ dir = 9 }, /turf/open/floor/plating{ - luminosity = 2; - initial_gas_mix = "o2=0.01;n2=0.01" + initial_gas_mix = "o2=0.01;n2=0.01"; + luminosity = 2 }, /area/maintenance/department/science) "uoq" = ( @@ -60673,7 +60352,6 @@ }, /obj/machinery/camera{ c_tag = "Experimentation Lab Mixing Area"; - dir = 2; network = list("ss13","rd") }, /turf/open/floor/engine, @@ -60954,8 +60632,8 @@ "vpz" = ( /obj/structure/girder, /turf/open/floor/plating{ - luminosity = 2; - initial_gas_mix = "o2=0.01;n2=0.01" + initial_gas_mix = "o2=0.01;n2=0.01"; + luminosity = 2 }, /area/maintenance/department/science) "vsk" = ( @@ -60988,7 +60666,6 @@ }, /obj/machinery/door/airlock/maintenance{ name = "Research Lab Maintenance"; - req_access_txt = "0"; req_one_access_txt = "7;29" }, /turf/open/floor/plating, @@ -61204,8 +60881,7 @@ dir = 1 }, /obj/machinery/camera{ - c_tag = "Engineering Port Storage"; - dir = 2 + c_tag = "Engineering Port Storage" }, /obj/effect/turf_decal/tile/yellow{ dir = 1 @@ -61265,7 +60941,6 @@ /area/science/xenobiology) "wbB" = ( /obj/machinery/atmospherics/components/binary/pump{ - dir = 2; name = "External Gas to Loop" }, /obj/effect/turf_decal/delivery, @@ -61962,8 +61637,8 @@ "xsO" = ( /obj/item/ectoplasm, /turf/open/floor/plating{ - luminosity = 2; - initial_gas_mix = "o2=0.01;n2=0.01" + initial_gas_mix = "o2=0.01;n2=0.01"; + luminosity = 2 }, /area/maintenance/department/science) "xuv" = ( @@ -61981,9 +61656,7 @@ /turf/open/floor/plasteel, /area/hallway/primary/central) "xxw" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 2 - }, +/obj/machinery/atmospherics/components/binary/pump, /turf/open/floor/plasteel/dark, /area/science/xenobiology) "xxO" = ( @@ -62066,10 +61739,10 @@ /area/hallway/primary/aft) "xFl" = ( /obj/machinery/power/apc/highcap/five_k{ + areastring = "/area/tcommsat/server"; dir = 1; layer = 4; name = "Telecomms Server APC"; - areastring = "/area/tcommsat/server"; pixel_y = 24 }, /obj/structure/cable{ @@ -62134,9 +61807,7 @@ /area/engine/engineering) "xOC" = ( /obj/machinery/door/airlock/external{ - name = "Construction Zone"; - req_access_txt = "0"; - req_one_access_txt = "0" + name = "Construction Zone" }, /obj/effect/turf_decal/delivery, /turf/open/floor/plating, @@ -62156,8 +61827,7 @@ /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/machinery/door/airlock{ - name = "Port Emergency Storage"; - req_access_txt = "0" + name = "Port Emergency Storage" }, /obj/effect/mapping_helpers/airlock/unres, /turf/open/floor/plasteel/freezer, @@ -95216,7 +94886,7 @@ aeO aff afy afP -agf +bIK agt agD agR @@ -104551,9 +104221,9 @@ bEb bFn bGt bHz -bIK +bIM bJQ -bIK +bIM bMl bNp bOt diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index a0d58709c8..efe6bbadaa 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -886,7 +886,7 @@ else O.anchored = initial(O.anchored) else - to_chat(user, "Not enough room in cargo compartment! Maximum of eight objects!") + to_chat(user, "Not enough room in cargo compartment! Maximum of [cargo_capacity] objects!") else to_chat(user, "[target] is firmly secured!") @@ -899,6 +899,12 @@ user.visible_message("[user] unloads [chosen_cargo] from its cargo.") playsound(loc, 'sound/effects/bin_close.ogg', 50, 0) +/obj/item/cyborg_clamp/Destroy() + for(var/atom/movable/target in cargo) + target.forceMove(get_turf(src)) + playsound(loc, 'sound/effects/bin_close.ogg', 50, 0) + return ..() + /obj/item/card/id/miningborg name = "mining point card" desc = "A robotic ID strip used for claiming and transferring mining points. Must be held in an active slot to transfer points." diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm index 48e6f8c288..eab0cc1d66 100644 --- a/code/modules/mob/living/silicon/robot/robot_modules.dm +++ b/code/modules/mob/living/silicon/robot/robot_modules.dm @@ -835,7 +835,7 @@ /obj/item/robot_module/miner/be_transformed_to(obj/item/robot_module/old_module) var/mob/living/silicon/robot/R = loc - var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Lavaland", "Heavy", "Sleek", "Marina", "Can", "Spider", "Asteroid", "Droid", "Blade") + var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Lavaland", "Heavy", "Sleek", "Marina", "Can", "Spider", "Asteroid", "Droid", "Blade", "Vale") if(!borg_icon) return FALSE switch(borg_icon) @@ -868,6 +868,11 @@ cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi' sleeper_overlay = "bladesleeper" dogborg = TRUE + if("Vale") + cyborg_base_icon = "valemine" + cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi' + sleeper_overlay = "valeminesleeper" + dogborg = TRUE return ..() /obj/item/robot_module/syndicate diff --git a/modular_citadel/icons/mob/widerobot.dmi b/modular_citadel/icons/mob/widerobot.dmi index 43a6863ece21162ee333d94919db051b2cc974ac..a77a109eb9f17b9a7b32697b8008a21d3508e64f 100644 GIT binary patch literal 695890 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

    CT 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

    R2wBlJ8Y-Fk>DP5U>i= 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

    SeEz4mW#b>K7+|fhH|gDd%KlUsz~! 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

    ufpW zcwX8&fWBmfSZzI+xK19h%Rv3YTKDeiZ>ul??Rum2poBZPks#2Np8G9u1@cm=*{$S3 z<)tb@oKbYmcu64K`&CE#QN>UvuOBpH!c6p9ZOP z)o}s(KcGe?8H#gJ~5XBd=JdkxoME*+WpzG!7o)qc84nFFWs=8FJ!I&=)Thruu#kRw6?AR5Wx4xqZ7j|k@nfO9U!FDmX~8+(k^QwSNo=RVQl8+3I;k+C8esR zW%uWIy|7a~&Dp>^pmFExexmuYo(QY25|hQzYFTwClBofsdq>{`5A_EGe;7LdApDo}?yLEIn9z9v7&Y|`w*qAUbT~o@f#KZ!@)?HNV z2CfzdG<>~dTWWJ88W~%TuTx1wT1U~lMEaHg)e#-wlG4E^<1i0g4_8)J%JBQF&O&uX zq>;1tIJ{>Z8$?*Y&5iBdv^kES!ia;^Vi=M315QmivE$};r9LN zve4M|td&^@^5VBQ;}=mex}6T`fm23vuQfU^zoGlX^Jfei_lnJEsbze7_5Q~<*%!m( zYr5G2N@+KjJfv3Uj(c}*?K%F(?>9aNmiA~N-;##POc!3771?gGOWOD7ndhNNVMsW& zh*8KG?T8g2v{a`DLW_VG%JIn_)V{4mDgCz^Gf6NH!$oT#7r)e~tGh<&r8eqHd^9*7q zj&HF*o9#g)D{VrC$$kNu$t;Zkf?ucDOU$aZIW|a#m)hs-Zfq+3-R`>(BciU9fS8Y_ zE^hW8PW3XqIUa&cH#z{@S;ui@B=%l+z7P zd!NDGbFG6^L)SuV3e7Ii#tqX|762CiJ*@WuPA*?!gTau6sjWFW+IdlHCvKHli-)gX z2R)WECj95sxSwnFH$J`rQ)!tilq?T?c+eGVd7JtVz(c|vFg-mzJxy=lzCFe&0-zEB zC~~>`Lek@#!E{6-wNXm-i@U2sU+Dr++MH}x?%Af1OV8@WIn$j6Kizf`M|R*>K)v~} zudmP7*Bz_r3*bEdA~Kjxwa=_Y_BOgj==k_7|4kHJ!lSTgDu#8Z*UWt}qJ&0w$2H!u zwao<8;9H*1s_-lSM%7C+*DLiYB1@rpD-wYug!b^_XmQZm&-M~lf2M{dg8<7;42q*h zK@tOPap2U{HRPMzWBTb~91Q4pHqcZ=x%+|6j++&3?$T2OY4i^}^9Z)Gyul|%Q6}X!r8hRx_V4n+J&~Wr(1SncNdN6&U>`) ztei&kTuS9|ysev9ZX_0piErA~MmXx^)B>pmN+s}}H{RmHyCIfVlLl=Zet*Ga)VqH` z<(M{pY(;O`O6i~Wa1gZSIVWT-ocC|O&e4gF`@@ks5%wT4{Mgdv=ITRrH8r0Bx(?W2 zjQ|!J1vF%xp(MuV75YYHZ?E$e>vE5k*YFv+!zuWd0K?oC=ww58@1D#Bs+&6AjNc}= zqvH-_^~+u>?Dpgu>QF>R4K-QzL za1f4gKwo!dnsSo*da%pcw98r1>-^~2`_n7l{q?9&nyaN=b~=d9^5@yYWe+NEh>3}v zWq#Y)rYZe(bNCKe);*dypjCghyO|svUuZYC!|t))9YO;m0wok@J*6cuFX3Z-h-TS? ziz*bHn{+eEm!O{Nf{bl!REPM_(}tK-SImzFV5Nd+*j{MHJ>-@IG&y+qukXhIn`UT(|$hTX12tdo$~P)?qDBdqVIIQ#5+Ai`ft&&0e4Lq(#m&c3y+;Bs8qSr@NPE?*Biz0qReJ-z^U2B*?H ztc_<28S%RMv z(RGhbSI3u8;?&#XJisLR0l0e1+nt|RRlvUkGSg0rU*y4>HvIER+N5U%^-@5P9ykjh zx_*r6RPM8Nr?oCf{nr>H6Glueq~4YM1k!9Tg2iMimU{u+mp6V4brk6_meSXk=?AU( zP^N~8wWP*F=ntfuRVRa9S?SRMYK{40S%`>Zf$UEIjFTI5H!}?@oLXB1u!z?PoqoX2 z4c>tc|2-eHahV!0-w`2YG*?Lig7$nJ-Zy=4Im0L$L9(YzMu$$)`nd{-`{w5Vtf@j{ zgy*;3M00a<=12h`2E*x}i;6A;a11RGw&gIp_j!=-^cA&E<=-7WmKaiV`dQX>-d&9d z(0Qe5`7&>T4DX?wAYWlbyH`>r(iI>c zDzR7q*fe6a?&J9jDL4&k3A+6W=<}tyB#l&35KT3CVY^(^(s<|X z(#MB+7mkDZ{s?DVTVgPZV;t4*Ln=u@vR{_lF_2fQZ{os$f}xR<7Vws#(k6PiC3H2; z@8IoMecZ6Z{PKAIs|b;%*x8K1V0w?}o2uLF4)BuX=GQ+GrMmmP@42dodN?B)>%J}9 zijfP{L^BZ&6Ih9o(#`v0K}$*!gZvca|Mn zwOJ-Mf>7m4Xyn1sZn^Ge^$9VKP+5ul51(|t0dHuvsV)WnG*G5G4F2%~TJA8ggY@SM`Vy7^Vr@wy6u!?oSj_(LBrOFeZM)W)^ z=(FGY`F?X*Y+uS-A?Nk8EjU!F?jrEKIGfzJ2=M)zs^PG2Udodn*vlf?PQU}T`(4#d zd2U!gtkC=+6UlO(i%_aoRq7n6e~VNRtk$Hv>o+1nH4+4J8BWu;M@b@K3<>*IWmfsX z0C?CXN{XrZI}a)EcFUI6Q$xc;q8}>#Ng5f+1xxFg(y`Q*>_(SDVkk3rcZH5DjbFfp zvWlz}X(-dVcIBrKU90L}`KIR~8v{2Rr?oLU*_zu`D?aQul5UDkiWIG|*}4)0sD1T` zsekvrhD2mbg$(zbPu5ae+~f*U6`D~%CAvJ-phQDbmkj1Y4+Wv?!Ztni6TQB|jkUIa zy=OyGV0bhe4QK@DD|Yi2ZYLj&={0aL7M>vK92k35-IBhnbe#!+)`_~(BpKtytRzbA z=E9dkwH2-!Eb-Sj^7+EUskBV14h0zCI1w*7+uGW?&Q*grM?f$Lsf@i;O!EHfkTpj_ z7^O6I_DbGHRsD8y_huv5vaf>YrYg58F#)sqxv3Anm^WpYAEL`2)?T2b-4@390z!X^ z!cBNI4|TT5H(`k78wVTuMwzIoeJl2j04x+su=OZ6%5<-HL*fRO5w6ZZ3A7G@9K0iEi`%@n?8~YHr8vA!e5{t2rWkb^>`Z1qnE&dA{djs%k)ec2ed?-owa$(5 z2o%3F-(}=4MMC&zQb2(Me5^9hB-|bQ!3eUI5Ua-ILEU_yq|5t(FGzU=E6_PX8*8^lrCq5#BMTZ(enRwckD=bVql*#&Ux2%sV6I5 z8g??N&P6UX3PRQ1KGv`TQ$%fh43H>%{Rlly_=Zeq8-&Q=x*VlixxcRbDz4NeLhQkj z0^E)(HBT2$?e6xz;FN&12inC^yoiM-xp269SGF5%B9%0p3&r zw@h$#KDtRIFqSqM?V9k5GLW^lqV;-Qt*5F6Y>radN#B02taz zC$RoIRvs$}tD}hi+j5?}tt33vBe;~1JC8)(8!|lW+vGc{Q|(Iw9xE{|9OEJlZP6!} zC7z6pjxMB=c3kIzt2f@j)cT-eyNQmK@3lTo5ZodmNi#8ET`N`lh8%3kdojuYAFIHt z_V9)y#^*;E?#=oi(ZtZd_%pKHwGSVNde|7~VG%2M(?0WPL+33}lw>~b0@2ymT9^M} zm~WMe@6@~&=+DBIx2&yxPX%Ru9;jV1HA79yG0dWq3U(KDCyTVeT4qbMYK;~e0p1dG zF@|HOigZf7fZUXY&>pKFS?fwth~Ki^z5zF7K0xAMmNqW0b;Tl zDXq19bG&rTDjE1TRS>IP07VKvE>s;RBcYdllYoflX`oT z>_CB-+NjJX^!~QfE4RSPSn%eOSw;zvW=((0KvoK@W7JW3OeJjsUe>b9?Da{QJd~*g z(JWp9-Q$qG(E|=6Y$H$Mb6uT9;vFA1UC&*TZ+EjavE{JXB%C4oEA8}i9;&Wzz@0uY zJve{rh-=@@uTEO31O?wCLd1i?LRQ#f;j!z4!V&n2vVNfwP96Ze_lw+=da??0G^owh z?x0f8ALUd>B=RiZK9kT309u$A5UNgA{Dr31GA=WA+-=8FL|zi|i!o);Amn*|&sVq3 zG=gpud)ic`YnKl=%6mBM^IJi7kA(|6hZ%=9z> zdG&^#Kbid5{tC=hs42XtW>zq|tjq|xoq|+bq;<^rf$F#UY2$)xM5lW-bCXd}u7jc1 zmd|S2l_LM*??xeJ8Kii7mP`0sQISiLAf56OEVl&vpbbNMHmH-2g=W z&s=}ovyKM5JYxdG7{YV>x|o+t^~Ee$q5Az9yFvHBb&-d+3?x(yd|E{0vj@C9 z?O4W3?xM$tHZ|^p&+pY2{yhf4|C~GE5)pAaulHdsS z5v@8OYlW5_e%H$3~0RdiB@0>c9n4?l!NsS>dO=Q-(KKoxFPL zND){Kz2HEZDGiF_=aeI%W0b*asT-{(~15sG@QSZcOKd3vl_k%}V-wa|xE<5TV zpPum1wfrbhkvOq$_0#TL6$KXJ=se(4#Vu(6`9L{EErS5KOx*}J>_GHjK62v`n1X{~ zDa~b9q8&!)yZyW*9un+NPDEh|}7KDg*r$O3EJ)pcB88uD)lba>deW!hjG zTp?pW&?>U^W=CQvp(FdcT(%?6=G}ep{I3eFS*ceNm~^<0{%$$cBVCNUYEj z<7k8tnT9>7mXCbHrdk%e`>w2vcR8KfY6`d=m^!Qea(bx~ZuL4LRqdXK&IrVY+3i zxh^3rIHomx_<*#HXY!A5N4A2r@)lLcxP)_ijs!lD;gj6Ijz+64DLvEx?kchL$=*Z! zdR*Q{bLfJVGO(Nip8g*Jkz)Uz1=Q^qw{8e3*qNOZ82a+%+T0qKW9#nz{+&;YO+*<~ z0UCl8(F_{^xKedYq;+&L;Hm9kMd7El>Ymt4rP^aZ;ncS8$O z<-XJz!umEdh|hCfkmz4}|4}YOZ9Dl&U-h>_`qD&_m19_4$W1svIxH@oGQ04uJ5Bi# zi4KZfoue*Te{a{j8_}Eown+A7PJfX{9B1yqI2Zx~1OUQ{LcWy*hY6fJ`D%d+Jv$H# z>Y)>=8=%f%q<{<~l zXAn0tYa&9DyL65sBEGF%Gj%Ow0eM@mAWu~5hhQo()5_HraNPfSJn^{y=10~&Tia3q z7N!5DKZdmnnf~Vs-~!CTq3qnJ8Xk)OSd#<)eIFa;VT7T&I(z`tR2jew-p+p7d{1g@)P4WK<0i9Wd~m<5v?Er7ueiKi zfj{5d%WK#;Vx8ZI*c|!|fm~0@zH91wCm$fpUf>$9Sd7L`Otl>82j{_G;^&b_Ri(ku zgG~XfCW&5vYA0@N&BVL)cQ*9gN<$!a);g6?3B?aw){}qG3?Rejbf`cWxQh2{WQDXktjgPvJUC?Y}Y;P#T{&cUAGVVJrY08Wm zb`(0&YkTyH{VA`;Ec`0POD>NUw&L(55L@B;6{@s0bw2^XPxQ3P5GpWn6JLb;8`v{0 zfb(OXq6d@TBVaH5K~WO_$8zedfJDUBBLb4c4$bBOGzj}Q;|L9@)MTf)GVf*2dMN$f za|#TV)I(N3aPdemSpmA{BJf_g>wYLte{-?8+!HVgi%LuTj?CM^2tmn`VD1D34m7@( zPK|(8QA(GaIl*l$*JclEkJ7N(*{b8T0wlAbsJt9E*O$HtPB75ZixH~xB`gB<_^==- z?J6jl&wz}9+X#h$5`}Aj=DNZfcZ!d#FHe2pL1+xREn%d>CW!o01J<^=8y6FDHW@Nw z9LKB840#$7iflp5xV@w+bH9{uhYLZGUA;cr^ezob*0G~8K^!*l;~9GUR?RN<1pT}U zSY2Q*_7tsw`2Yo+88OCvl|dx#F%VcSR>@eoeYQD%Xr8>|XlAsT>D3&DTr4cOc%BpV zD!bh3^%O&z==G`~E3CT_ki~4YaRKs5BEc)m3^`VG?vhm^)tVmLJ5-Qw{GR-NVL5{* z=NbJqNP+!7$6S=~3zy z1j-)ScY1|uFWXa}WIVb7M+?dY@nLef6EHBn(NbJf-K%K7+Zgh0uGf$X$M{%-9Ron! zt|S>L-h-=smA)W==oQ(c1>1(28f>8=6Lpy|SHrWa1`7n0;g$UI|GMt?;`>wmu)SY{ z@IEMy(IWFX{H_(_aa zya09vH->^dXmRN@srS4cabmCA4UqHfLLPYW?ZzgWAsYqnVrO~#jx=`9&FG6a8 z%lvGb3a^|51#2xpd>Fv0G4aY&C$xnPoKJ#WzG{Nepsj1N+AtKH-Untzub|0iphysU zdqjRVfLkmXOCaIAy}JKqH-mMZA2amW?5jV{j*1@pF zy{}GsL1$Z{1^jvgxY*Ulr=jBo@7*#)%RA5vxo4BfdQF%B!+avJfGaEM3@d*jiL|Re zm1EoVOFU-<*uvT40<_53Z0z490B;Mt&$a|RN@JtFw>JuWxlKSVi8L1O7Kh!7_r#8E z_%)j-^&1vo_;z5r-G`P#-E_o!PVA*MW@#ZFHhRvXhI_mVwiEASgnpr`n`fgL2JYB> z*xr)I!1^uF>ntybZ8|1D-g z5n{_Cw92(O{V1cHnSM-3JQyrRXQ=at5701n_5QXD=}$!{%L-jlRt8>wAL{DrN+xdi z9sjxg6+Y7^?aPc?2_AQGF;hTB19S{^*C9gr&h9k&8k;KisMq z3N@9kC)3N8@%4T=l*|*?F09}n_S(wL`rQU(Y8Qgnwb~GPo5HJFqL|_=hJhtQRaLdg zRK12FNFx2x8?tA2iTCUy5`hrNQV(0?Y!}6a1!@P2tBHO zaBS{IZz|x><>UqeS5l%&FuHneRvsy<8?U+kTyg=ZO@)I1zuPgt4c^dWWBf~*LH8Rj zYac7`OoWC~06LG2pjR`e`H)vXA=B{a&3mu)b<&?qf(c~uC`ol$RNR@~f7)%&Mbltp z%R+v-V&`Ke5nGIlYF{Pc((jew*UJ}t3#LpK+*`C6;m*HSaG*%o`1wi!Fu65$laF%y zU<7*E1r)ek^otM4$(GEckae{63OFy%4_uuL`VPkO5oo*19mP;8hMR9T^%3O8j4)Lt zs_t%+>t*SH<)60FIP7KymJ8tHRC3)IDoTs7oxR^Jzt1`rv;lz5=DbD?W8}VZArSlz zA8fXdn+KyBO>s+md;2+hh$fi-)$#iQZzu+s33+;WBwX1If?{atDWN3|2l_X^OiIkJ z%`c}qFx|96Q2-uF72528+qG?gk`WQ{kaSoxunk6|qbuo6DuL#%APEi2j8^3sa%Ul! zsht`O7%())U&i(G`(Ov_a5nsDQfZc@4`TvOAi+)D@QHRo3A8?HZv|i(c6r&)LQzwSJO8L|~4~Wsgbh;*ps=%ds7r zD@aJ?^=V~3iZzLutb&|R-0e$d^D`ma%yxr=^xQ%T{7#rbQioPqY{C0@ukB=txR1pt zC9f<7Ill$Uu5Rkg{42N$t8u>*H#MV+A!S2ZcLD$=zPy8%;da+{W3-dQ7h97`{j_m) zS0X^ne73g`oV<(+9D(~j8RWxV>~Jo#^=I^fyV$d@7!$OmpNe;^9Dk0{oW!p8gsK2Er$?XyzM#oE3y;GvUbpz? zG{Dd4-jEW|e;Z(X1snB{3?zFrmqFO5R?`gItH!dx224WQEFKE7N@TN7e5OY<)^WOQPaD>1E_qtHab9xXvf z5e2fyk7p*Imu2a@*AVfy5cWjs`+ky=d7de$L4PJ}FJM1FJeI6hq!syzw`yu@3tMI> zsjEabgOsgIBRacH$&Pr#bJ)A7VN2d=dMyg{hbp~CY)p5psIMzsJDNoKLy0{;#g%ri zCZ-gq{x$6a>#2H~OyDg(R7SN)v8HY(>xoksC-gN8f;9rDRB{+yn1XIML#kxrRr$Gd z_K1~$Y!O&8U>DRt8}OkG_&MHn-R-^JDHJ#SBw^tY%!nKi8tNvI;ccRjy%3T4?_2)u z^_8=&Xn$pb1g3u^rs2PD{w8pvM$I$3WgC%Dl=ZS9_;ZV@#o(XCoYkJSxw*NKt@!@X zGWQWJ&d_G-cM~^BHK&Hs8K@_@odOp>S8`$-@z5sAIixue+W?d9uR z2V}Co=Nreez}ZSyjQ=W@5f=(vR*UMo<)WD&dMePA?DW!xNvEmu-42*^Dyh4%_5l-f zk2HIaG&uK}fC>9p9abCIxEAPNg@6dhP9DY!s+X3UI#Cv!FEhX)fO5jNUJBmOpbODq z86RJ!Iosl1j8vZJw9)nS^)dhSOj(JjWl+RM22){ z3Lf1@uZ49wYjiQBmz;Hewez#_HGKqdSETNdlx#@=(`}kEaYID>4;Ntemb}~cn+ZiR z{m)x|Eizt>DQV|bW>WAWRA_-;V+yrTenOpThEuB{7_4Ex}5U#_lbrR ztx5c17Za)u8pt1Q7i4U7o;)IX|6pY6mr6kFn&OFI zJ^F!EzeielvycQs9oXYGd4ZMbeEVvH!~Cyi+)NL=+<4O>yS5lEV%nLteeY8S1-{M1 z??I1d1_x0iM=BRnmfHo(cq<(U!27C3T=9Ai}YsYqIllo;T1CY9MK>v^V1l2?k~zQQ{bwPaF| zH!|_m`4j%-!TV32Q%0l@mUQ1;9=PU$MA}+%enh*exl+{-;I7 zp9fh6YP|D3<0?gPm?{h0Q(LyQ-`BIE)vyrrm1hSnTbLu0|HO%tQ2dL6fb=(rob>pf zQC>(*EvE`)`(gLhNE%+v-E7L-TPC@!y!95EjRcWW49a0+NFBH6=4lT}=Yo?EyfTv( z?av)nM!=m#OAop6%pE0_o8dovx_ABpw-+s}Et;id*&_yuVH7ER|LF3*DYOpA~LAHL7Sm#^|?s zdH#`=SJchX7+LGx!lnldf`dav_<;k3TvvB_0+ZhMg%kJ*Gu$~_OnPWNh$oo)Xqb~T z9Gd?cNEbdby07#VVsGo?A)&>iywXNliQSbLL4`!mgEyZ>$XH!Q6)9?s^TYT@gU<=^ z1?MLsXvJQXFcN0&$AFoupKOhLz=-%x4$_=_E;Pz3FDu>BTncFYQbfItjy$Z~4)|&w zWNviP%n5x~Hwv<1Zj0#p-k{G$Jbfcl=zn9-`9j`d1ft4@HKVH*bAz*`VB0>~Sx5zw zimrhl4y+gQsLK3LVFQJ}M-G&D@$)cbs&bi&7bcQ_J*bO5{=(X{NU z_UXr`7xLfw=h4uJMA`j&#tMG&Fg8u9K&|Qa8Re&&SsQXm;1lNXebRob3k(p`ZFQO7 z;_mc>uLir=-VG9w(@$)qH?E|XwHl0f!8t;tdLc*pqfZiwX?*-rNGeRr>6vBovh$YQ zyyMp}Q}qg&*j?e|hi_sWe7E-p1jN=+XHWIYa&>5QwMhQHni*sVxRdMUuf6ZQVM8a-&Kj}pU?9>Y}Nm$vo_}E=*qLh zaQps;78I~VjNG6>Z4Q@$qFk)7`H5xn8+_+n8nRzoKecbMO}}d2%ksH&>4DbXsDFck z?>|AI@f{pNJ`kWoX^T19l6!vaTZmw_sE?XFqD1FTxw+`Z`5-0@ z8?f?a={ZcbztoHt!*unems7Cz!XsT}`c>YP;jXu=5}U4s&4rI|kFwJb1j(OU2P|X+ zK91&j=53K2gQ+!u7vjwD>o2L6Yx47KY|2&a9Xo>$PCIaXjXIGm)iCrf;LM`XYm$J7 zXhtU(5OWJiaKS(LUrVCABHDB$X-oC#FYBwNk4=4 z{PCjZLTQ2Uwcfn<&bsGu<}Rm0EHAwC)|Z;P|DvdL~=O9orYsqw!uN+5hldGI03g9@yy0X*Q$3`!5EZ+EQ44%JJ8!h+)cuKbM?L1T02bE=Jljw;pWTJ~|k8P?Q|&Uruexw#lrJ^nu2yo4VyicB$P= zR>qn>&T?v+{@~JC`u0Tig*`kvFJvQ=kD8gAdG2PsNgOH}L!CwYuMB-)MjsG>1?ihU zJqkN_?6HsPaoGJ<=k7(=i58RTMnM6Xye{uvd`_RPoS(e{ryCilo|@l&F}7#ex@z5bPrMuuT z$r0EBIEHj;FGndagJP|BFc9WVdZf!OZse+Wsu$Yubv<&OOk$;NvKl?rr8U0vDmXW% zZW(XWvd=%@c6v@QYw=l}Wa*eEue_QDs+&jtkY%H9{iN1;UBESIXYWlOO?jPtDD%PN zO7qgh+>Wu~E=N8*S-2Ks%ZMsFp>DMT(&s&H?gPcDoS3b+Nx_8!Nr$Y>jXr!W43wSP zP#m^6V`VK?L$-|G^YQWLPX$B%M%cO6X?uPBA8~$|^nGz~tWeETCm+c0l@&MOwJKA3 zD_SvyaX$0wvpuiy&`YNm%Xn0iYnLyzmUk0E`{#%=`TK>uf1Ef34ixz7eR^re!2`UJ z4ZF85r8um(pW0%mMnW=LI&UCY_G(!zm(^^tS;lHdck~xp6KSgU5=W#CdXlde<`;FF z1dZ1^S-fM>!7)GgQ9>gxRdkjojoGakw>0ZN!#*qgS-odD%E$%ArYUr?RsP=_Kx0)q z32cCX)G+LF+pGo2srL5y7k6^#U+M8`iN9IPR?EL5;d|Rrd^58Y zO#dd!md6G+drD7a^0rZJMbv$CPb55j?BXLiYqqbLfA2dsJIIzDC6YDqW__&B0937Y z^l}muHu~)5yS>w^Ce5k?V%15N-Mhc*-dyzl-fW~JqE0x06%9biHkI)%Ha-65Q~J$8 zU|&E%v_l!^&)z!1P=b2?~P>Jnf>M$_i~N@h1(A0GluHaESr&>e4Dz zd-fDKX00Ha87*N#I(KmP%Bn)%!GmOiNHt_9~gkxcpHGBT}?X$nc)4YuF&2X@PWj_ zy{!&E7Wsobff8_k*TU3X>YuS?wSsjh^%FNC{U)~!tI8<17RO&Yl}Y;GF@1!OVirsJ zQq$ME8_v87B)XTxe%4OdvKgq8e-MWl3*JjG8dwezpitjNk4(Ht%&kpS|8Mnz)0$y9 zgP*Oxv$>m*+q}wYH%@uZdsiGyleiK%$!mJsG~uzLuX#bqt|^cN5iB#m{(9C9LH*#rqK`Sh2C zc59>fn$6&6#BLrXD&b@QUC&E41WTpB%H3^J=gUwIdS}Y*aBLmd=H^M)G+XtbmA_i` zX>h&P&{sr9gio zWo;IXD+nvbPD+1=&A+`+BiEK zODCS!8~ONuDSAC}l-G>Tzy)pc`G&aOEHe3+JvZm-#bL68Ep4xwsr`AB?^~m6W2TZW|>$WqwHC zx{0riP*<=ykFR`dx>)ySRBK;&BVHK^w$GyWQRI`6(VUAK8> z_s13NTPgSl_wPaG%~TKU9s9qyd(W_@)@}qT1?C4&1>vS`V*!xg(<|^Zz zc}+~o`snWhxyP*Qxucm6xen$i>SK;djH@yeOzuTJ65W0FOl?N(yWZvb+l$Zx0W(_4 za{bRN>nr(=-caa(f%n`?MfXj+OG7vTkp)u|G&OYA>&*nC;9N()@q6#^08eWiW|W&- zcqrUD@&D_%`0$4UUO5nEMpZhcu)Hp|XtypnJi;gtD%v(G2PTYe;mY^k8^y*cs| z-F)&9Oa%jXvT`w{ll|DaR-#R)_7z@W-0#AOqP{SjJEM!F{U2GQ2ldgv9TB7jgw%1T(Caa8n~;mlODmRk)a5rC)}$E(X0f%RI(~&Bi`R#w z*xN44%5T`iOdgkth?ww|7<7X}MBm)oY&UR+wbXi=LHhqqB*?+f`UAnS`*szT1A^Bp zT{RW@&6jt_KL_|5s|pEp-m<=WtLyF2?|q#Z#qoe!uRURk>3+E>A`0)rh6hS;H7f^J z=e`;BcTDcbsp(xF`fFNle=k#gO4(V4TQ~CSmPoT~zS*_84E@DZ6MTN>m*44LK~i{P z=QZ8=+C^NhX^KJG8^K(ltbLgh3c|(Qs0h%&A8`D-80S}l^HYk@nQJ4ejG6@4+ZaWd zl%R+UgqE<%fj|DyT;>bFc^6J`jFHMnrC(MiQ>yQMdDJT6e&PLJ;XueblSNZ+>{aKW z?0|l}iFG#pxOWzkHMwlaI_?#0GH#`h$)?Y^Ie zT7U8~{%zjRx1r1A`Sbo|nyT4sG~I!dD}t9(>TFP_;#cf(GeXVGF`cjK+}}2qt1rI7 z62RsNg<-Z9KJ_T1Wj6U-z9)>=6Gt3IBb6F@IIB=hJmI3|i5-(%rma|xDip#qRYx2l z|JUdv!eWpmwb^<+qpjO_O2A(Dd))a4u!-(WpUbA`3PX?Ip?Zo?J!^-a3HamYyZu{% z;?ISLcd^W)i}QXkM$)ce$AZk0K<&c;e20NwUSMLfTWKl1iJ4Ld@rS9vLN<)38j#6k z26jaAj!}fT&}k;IWu9faPvvR{c}C;b#KWFV`{PpqSAId-8FgO1=Ck$+7#6J&0Vw(8 z#_a`6opvhqP|357w;xPXSc-jwr)cGl-c8>Ya4(D5IqWt#$I583ZEVs1Yn*$J&nKDg zfI8NVii#zsb#q8TZswuork&dtzwG>Y8p%Jewd)qnW}b{AQO}V&b`8POVKd zu^s{`T;sHJ?JhAGQb-)=iAb!p^{N1FqNJ+JQk|g5b*c|3^)Fr-oi4w_`jI+bb8}iP zsP_(9_<;K7{>Xa)9?zwRX4m|Crz#Jz7Q9uWx7C|eBYIy5;M&y*MAh8wmnxqV2)sMX zOc&Inkrj!yRMZ!r*?EPW@b9c`2&pgui|_6=Tb94~yBLU%ssCANA^q6bN4WVVo@nJE z1a`$zcwh_h0tb|JXsJx@AEErm^BeAl6Z`NXAy&D6;uEwfC}Vqd>~nt_y~2N|w?t3t zj(7+{PsRn| zrR`U4)tz=TZP%!dX?A{6LamhEb+?CrTM4>6gdo8qS8)fpXK!VM%ssOk{Vt7ICgR!{ z{x&-Ed3GJjUG%(H5s3i2czw5;41!la^O^OD=sQn!-}B&lqvya2!q`36P7I6y)51IQ z5tBmRRSqT!VquKkz{Y;_ciNWIOoeVVKrOoPE%yM{X5lEv=j;0Vy?u9Wj9?pX(AWoN zlkxY_b4bfc3ek==#e;r7yG(DXi;14q00y*D9XwDB@=ToFHI7?>sqWRWQN-`uq_q@w zynZ;7FH3r!^9|63SA+YQr&SC~2SW2Q0MrsKb~<0H$X~GOhqX zFDgx|jEi@*BpC+CvD#meXCyNV=`5wc()ZS$)8pzpPqN$U62r#e0)IXRabo*lQS6tT zwZ9v-{`v?6l9zSrf5oWe|1Ctmt-Uy5VfK=fG0+k`+vle{QMunDI<*ek2U?C0Ko?yG zQDt8H?#h9`7ncDxjppCOSzRuvyfvPU*X(<8BgNM+WQ9?Lel1wRtKbzSZeW#wI;e9% zrco&P({l%9~3*bs&N7OSm|X~!*nEGY04XZary_?Nqt zJ$5?twIJ^)u()e3a1{A(kv?s7RL6I@31;ZLPV=_>H}CTu6Zb-Si%$Avjq2y8<(3V5g)JSX* zH>r-(;ZBE<*Vo%401pWucrh69G)*YRy(q^0F2<4iICif#I}PPl*t9lPb4gQlSD=KL zCsuGcGbr>x*W2_Ps5mxraF}cKoCie*BfF%AKIPWkPA@Nb8)&+kLTyT+CQ`q#`v13k zp`C@xO{aYyICLtFfrhhhr@jSc;`f}+MYMFR`tfbc0hOv@ELL>^l)n>vzuJQ0*=66y zS}=VZg`q!Jn9mF;dj*+8K%`+Fg$piL>7P|_km3a9RbhT@WHUuRya zw;Q+zM&bta{>6Vsf5Zhrd3;bOK_O;r+~w*X%~62gKX1LP{|oVXu8iUO=Pv&Ipr&yC ze_>hwegV>l{(lWGv6}!pgz)#QP{Lpg%U%9!k|6EIlul3z$X+f@g*5kSgA>&9+37V3 zRjH!}V4hOm0uHpVN%O8u-*`8!_Uk(o!2TIn@#JzBX^ZE!KY8{fW2WxzQ$hSNkx}Ze z$i3TuYI1=Uuvi`2i$3yKZY|?*sm7?Ij2*Sh7t%7};BDq;e(ax{P?NYcmH?gRfcjB4 z_oVz~&p4nn&PesMafF?Q6J(IRY=mm;$NS5fJ8E&_qw~}5cT2(s%#fo}Bs!jmh=}n9 z>O(k(|CR&V>J@o((Vx5g{B&y&Tw{;pD9EFZ=`i6~Np^xd+|+|*;LMfARG>^*=Of=6 zNgH+*(a?h&*{VO$u_U?zLaK9+Ti4Z%d5NxI^8-Ty8}I!2D>P?(h5-Xj-!esJ*SaKq zSBEWj?w7Vy+1@^Z&jzX%Tpd=gn7zeQRkGk$(I0Sr)QrWO(t~H|=|2qkwcT@g<({47 zLfwzukXTmY!o%-sz?=(EhPR)2&MGuNZ@Ut7uH1^r?fVy)^YgE{fE#IQ6KB%6c)1SP z^`N?Qbnnyc^w)1N7$jW0i&I^?v~aHkzi+XvR^Kc@X=}F*QeEPi zb`RLX`Kg$NU?Sc9h{C%AqX|!9re5!2j_0RyTMw|`zt3iXGhpq{88GdivP&mB--|gr zAKtPhvaAFr@PZ*%{kI<~#{9%i(5#;sWMr$o%gxSRW_M)MJ1-V=mMLKXdR_{HAy0TR zk<)ay)VCj7=vnT*+kiI!5tLCCM028%`}v;m$z$6}sCdp}>@^-NWC8lp51lTQNQ{3j^u zeKl?+5r~e4_Kryf6iPcJeVdqA4kh;P?65u?AH6%_Ohr+oT{0A0Lhav4CzlYUyJcjl z+t2_?>YaVupA9d0-_hV^i8; zWt3_(CA8IOUx@>amCZ&-wO@Z77xZ4{zTmjXy&GHww(=A(#yGc+S-C9{w@c7Heb-l7 z(vr-jJTDyB&@QguWn6e&YkyeXp?^ESK>}%4$p;5j32oYMDs^;9MiJMmg>wC9c3w5# zt@5rM6e?nMZy9Rav*|C!b>*Xe2o3E5k76UN!_<+psV6fw*XeK{94_wwG$f8Nj7nO3m@?8Y;=g}uLB(jd6p{0eS@X(95qGTg2}7k)pQJqW%XlDmJm zZ>;-Qj||8Vt^uYdS>T_fEUT~`9IU(2t?S8-fr^b!)W@KE4oRw152HA&;)&2fcpvKC zYS{tab2{xZ^mhlZsw6%er(ZIJc-5xmf7SH2b<191Ln|!sLPU3c1KiKG$`9ZM@)4QG zis|6?->=Pg62yQCH8O3r969gfshAU27ln21N!io#xh%ZHbT;1lG6OI0!s9@ze>X|5 zIhD5`n_4vF)?%E}!{*>`h)s

    `*Ur8L7h#G!;e=e5MKYf1u!TpuRE%xM6&Y&Ten1 z?K~7N`s;jE3@HIV-RA-IoG{&p?2~P~qrcRk9o`oe<@Id!3R)q1=IixHL&nji!bdB8 zU6*5bIB}YCs%?BSXoB6>W}?GX(HQ1DqUz31DH1a#D_*6qE-nnR!a&@sLF=@l`i`x= zU`hBbdubpx1SH$w#oolxAk<2)ANv-PJDG!P>$hcQN+^u0z}g`RXrDI9rZ%eN(pCquG7=|8Vs}S?i%^x zJ$#+;}%W4oxLYn$0>Yojh^Gr69l5X_It92bZgze%R` z`yS2vegQ+w!&5ilpQ?2)^9E?V*SqB@Vz@^A`_-K@WnV7bc)x6{tlD0E{Y;lpQNPjR zz`+o7*=v$Q`0A4~;jda9gbR;OX`DO{UcLn0*U}@lQ!AH!#Np38bg0ZVxa>1?BHF-q z2%)&pa$DZDN*FP$b?T9#QqX$V4j#?(WOUu-$YOk}VH~|yuXxY)x}dR3mGpo6j+5v0G#)QAp6VNA%uT1j_~?pWw-{QC4}#V|A&XXl#osKChJAvckHq`O6xqm z2(FEY`hgEqNdkQ1FXt+3R0CJ|0_h$fQSD z?K?3{*Ya9hg04b5FqAuoTLbPSwVZ-oRlrEi33*B&rws_)nCW=waDz+2$h$Tv1*uzS zE@f6}^{tA_pfM1_ZQJIy++A7z;wB};$IX>S$OcyLy7mMlwMEona;Dh-xrF{q>8G=` zU4oo&3r>N^XkRcE&2By=Z13;SgB~b(z)WqPJOFO5O!o0mJc2J+tvRdfoQd?{5I+<% zGm|GPCB;IXm2P$&M)p|ofUr{aLiZwxlax7}0X;Mrpp|Pg;zxMroAe)+)q~UT zz>4rb{o5@x#we#*4%Ds~BeLt7P3BI`LlAWDRFwG$DB@s{N*}Wx;1mtCW7= zp-`*}q#Y#trn-&b>GQq(1rvSnmBx^*i=byO25`o_&z(AHl%$ph?e@hln@l$PQUIIu zsec5<9&x|7;R;+F|I`og*+C$8tlFlx6QB$4!FokZ)eHrB&R;3QDXnY@{)a71L&eX} zzqG!tC7FI*HgniEsdFy$iC{{N)Gi=3V`meyY6nu{zMHc*fC?aYPfyRu*pFVUgYEOW zRA2(bCI%@W&-=_U4*=(~K*E*Z0}FHg*Ca~=9=fXq@-fa&fA$6<2@Q|6G5`nuMGesJ zTlR30$xp#*3g5Z3G~%=H!mzJ#LPWRlX>~(H$1wOgp{(W}#g39wmRcqE zk&%rgAVHL>9JInox_h}NPo#YleLZ{ljP;F@zHDE73gpq<(8`7vmzzn;*qd7D|F~V_ z8^S3XSI$Z~{=BQqlFH%lR0+CETN)al7K}}3Y$F|+i<0=N+^NbfPH`Z!Y@%+bmzLA3 z1A~_j(2xpXM|K60!3?35GoE|{|54_tdR?{>H8A}d1zqpx!yfe;s37!|AwHp@ijK0o ztC%)E7#(hQ8PR5YE%u0=i)#=qt*5H}!qe;F!=c~YZYBC6k4k#`68`KxBdjERNKWd1 z95sL0iPINizLpdUCLj=8$AL~To~yVi%UxZAzMsha^9*B>_pHX6!6J^kzVS0fBpBa8 zO$Gt{f^xgpeAc;h6obDGZ=K~pGTyiljJ&r1R{hVd5QvsToB|yyt`lqATR-gd>!ORx+IM=52*-(XLBQ6J2 z<>0Pd3H~s|zcu;w`A&@e{vDA<5@$pZ#l(>@k!JdY^`F81g z_EW`Y*DnYLTypT@`fw5`fyDuON=Q3+ys5l-Q?xQDJAQ}CEc?$^{q74e5uz!#&ojr( ze8V6ZI8q^Yi`GFu_IZ?^cR8Ml|LjrA7Q!RqpCtYP6!0eK-I?|HHYuqn`G(78QdYWa zA%`sphn|?o=qTnF&kUvfkoFxAO=d=e`|?9_uaAvAuCi>Sgm5ePQL1%pkVCZNak#a$ z&kG9|`^&5N5e-kkb3-D%$#bN44pDpl;7P52h@&x>^9?#D^1Rc9=~evw{ULdyH_Xh~ zzW=K8>hGHOd;N|#YM=8d0no4o2S4~6Fvts5D8*1vEne?$Z-GWyM5tLBG6qvwEV=dA z%`=Ejf~`3<7U=$wFVjmg8lE42|aU4>)oh6ZgQjIs~LWi^+PzhYv~EQ zNOCV4O$9lZI{-ybZcR)Dtz1k7GamD;GhsjL=bS&18#R8qV|kfxLuP~_H~DtqcCTaf z__+Dhr2pE8=sw%!r0O(Nuf$MT)uDRE1*N&uETUy$q3UA9$2Q4_qp(yh+oC`xX-IgVQ*s8A*<-zR_vT1*+Gs)z(NfQ`woiQxVPVSTyMI@4uon1iK zL3Zb4F^*h%=Tyq+HDqh+)CTk`zK?J&JQ8i??$Rq59=X-?yE^>u6AS>ba(;z3Gh@-2aQ)y1t4VEK-m4OOqUZr?S@bq(;G zj0U!*1V`@m3llKMs|KEv$rR0dH?Ordo9xV+Yfhfj<}0QF>JCYvEkvMv3nVrhVEUD# zi;Ynp4XLM(OurJYjKoIdp(^f2oLSwBx6MP*eNA(JgtnR$a&!>GRG+TQWf_*h-P44# zoeKCt?Z8AMHd%vy$`@45!OcCSqSi43febv-Xbf5B4xIL9@;Y7*dg2f?9l++5qZI3` zasDV6BCjZ445WB2nXsk*xNnt{@m_lOOIyU%q-&#o1D>+5nxhhM$VQ6{?X)Kt3)ZMG#gM-_Qi0_!lprY zf0I>hC@e8EjpDv~_A5x?V*k1P3`%S48(aH>3i<=zH_UhHc&<;Gl`^?mF)U9lmQKb} z8+Hy~P_@%+VZwVd;rkWO9jo(}#plLMnso)VOCXylVKBYwgD^1xT_}Vcn=`+ao1Hy; z{ixAe>@Lqx5E-)SC0{j-q@VTPkMLCb$3CoIiDabX##`(P=@j5NZbeo{-m~O7#}iSv z$07VX?cEQ*Z)x_^1cO5+)`Y7UEK_LzI`AAqLXfMzaaU38>G*({677v(NptaCyA{Rw z3K^``y>?)Mf}QV^6)9)I*S5DGE@j)Bga3v=di-DNxkXp{use^8zSx_Me~&%Ctl(i7 zYZFOYN8UmBwYUVRWN)OJ@#83U=RFAreWdQ0Qss#~#&-%NPP| zxWd2IM;;;C^3i1<^(S_e;9rWn4tUOgim&EFbY4aCYCKg9xgXqUH*@KCvJ2}yix2rX zDJ2GLfDH#0pFK%y^T~G3w-=`qWJ_A`P7V$f5TE6fB{Cy=u{>ENWw=_`MIQ$QL5 zWFaXb+Ej1BBa$J!eznEZJO1Txqs=c{4(q=$gq3ymq$eDh-8 zb0v39MwdGKdT$vSL{3yPh0`z-T8Wj8UZ+%*6woWiWozfeURPCBDKWk&uJlC`U)t_! z<~jw~IAtwieqmcF4>s2Fn<`I)%PvrvV<9p&BH`a;X{dUO&1t3FN}1ru`Fs?OAz$+` zMt`@|ttO*+KcA=~^5D{Kq2yrtcB${CFQdT`!aFG4^70PXbc{#CEx`&^Fc=_veY0o~ z_#_a*3ebGY=`EK9M{j0m7JKMfjq|A{0<2W3YxQBZ)JN?Qu1<3iNWr^OYv%>{t(pJS?KrvHQ=z+0dW-lA(lUW4#JY) zRkCiJp$*c99qo&3z;M9yju!(%Zm!8Quh0=U5+%5GQAbC|gyZaEH1IF#{TKT$ z7cqQO?IIq&-OT%8yl8`Rmf;jyT#rRr$}V&hi+$_!UA>`u>X=XRSACnW!1J>D$0JfT ztPkkgR=DzNI%&)NiyDq%vG_jU(17CdO=IE5NF?&*sOmKz2#7g9wlOhrUsCY$@?tD` z^Gj2ZH$8*gKz!w-|3ENQ39Ywg({dKBRnyS$1Vj`c52l$ z+xzX{m$dgm^IM=3lRmGx*;395NdrcguGl+hd(C_({XI9m2qX9!C$uF|eD~{^QMv_OS$LW*CJ(nJ_8ba}Is!T*^d@CS`D@gCVP6Lq zM^0XcnPhqzd?qk+Hb^cI)UkN+OC@$KseMQ_^|qAb6Ffx$Z{J^L+dxPlY?`*4P!C*s zD|DYHAnOnHPApG_n+#IK9M}J#wx&BQ_tt=$#pl*B7+}NSWi==e8>%Q$WTq!3++5d@ z)j?NDULEP5*y@z!?_DHPL7OA5<%{jwRD7(1MENa@Be|LY^S8chb8Bl)S*7H=I1m=u{LYStRCL|_u z_9{C`rqfeVQEg*e?Wch>y>}!bPzPJ-owDNiVIg*?BR4GU3^i)d`2gY2nJ9x$3wXzC z`K*MQeG-s)%(3pMGaZ^4*=j5bkBpXlilA-1wuzOgMT5~5z9V>?e0R~lGms+NW;9UL z06RRzWO8E(v+ms|re9F~z1V!q^r%jF;x(q6CA!p8-C$YdBw?pnf^E#L$}3e ztk_$E*udFFxPQ#U`V;k~D=iru9hTEQ>KY~oKFt-?Q^HK+D$?5?OseJCV8SCb9P~q0 z3Erx%TzROYlLxr9{5NQ!ze0KvnIghL)PBg+P;!@}xP(N0?>;Rl zcy@B2HxO^TcCcDY*e7||)J(ir6wo4=Jd5+0P+$X2NYknxNJtb`HtRR&F^vs74^mywWttBOCDXH2DrZKT$%Hz)hcZMI|XybxHpj+A3 z$Z8LoX`|HJLoyk_tX#Z_f53Qra0?T7Pqec5%>$8WJL3|e@~dw+@AN5ql%2R|`{-24 zX0wFcC7%{^9`)j?+hpM>iv`hs?v5!Vqr$CNku*$cvJ8Jp^aQ*;PC-Lft)$quZN)MR z8;G}F$JxBSiz!6K7-|n82!sYsXR7lHwLGP9@UGz2{zo;`mpm#s;y+(uP?~K7TLXaE@>qAdInWJxvC?_6Ox8VVl={kib@%cQM4oy@GHulzt#Y4?$6E6Z7W&b~ zw&8=dEXLm}SxUPm3PPb3)TAf&h#e*&-^IG8Iv2tp&Gjvx)PU{7wCT>>PZWEv41kxS zAwOlSfkq*p-^SIn6la;a$9T(P@HhU2`#oP{el!zqFcaz%u-A$z4=j5@99jMSe1hgX z;}!h5llU7jsH){VqpUi!6pS1HhEX;UAaDf`b0Z*})x+_zv$q4aw}q57L4?l5<1!r7T0)3BL1r&IaPEx3aqW zsk@tYy>-_nCQALr$Jns-$fFQ><$lrL(dwKBwTipO!t?0~j(2W>*w>?pjMLK0#+4tq zAZyzkg!j7tss*V1yl8|S84Bh3k6DGMQNUhiGAb!4kwNyuY>3U-z6B$@A#oPEyf(6p z_dIEYi?#P3qt3SS^6q7$J?H(IHq^XNLHH+`FhD1U9|iu@C!39bvKRNU8>ADe zE^!&YOgQUm@$rW^fSK|W;Cm|HR3PjVCrQxNr;P(3fUendm&O+k4n6v+fxbSDaFBap zhe+#TzPYdhH?Z(q=t-GhI97X-N6!=NBb-poFy7k7$CY(EgVjJ7nb3I1q@g2@Fyn{;*u z2lXUb(+Qoct&f0&r8Xxu#aSbm12KKTR{_1&K;lBD#Ziuth+VuZCc!1j~i zZKY@x6*FsWR)qKIy3LS6Sse$jD2oN`!tcg>Z%%)B@hSGV5@rl7bttW&D1s>k$T=9} z+Q>MyjH5=ocvcs%fx!=s8LEkvq+Xv%z1< ziGJ2!0_w8gH*xGyH&p%rxfJ?QXGcd$h`546N!!`@&)e=5ZyLz(g$d=4t247WwN9cI8O_Z-^w&-PXo=wB%sP%9{^aJ=#3qe(hynFjCqh)~H0 zpx1`Mpy%kt@FBTHYzKF)QhEgSw=~R`eG*#fuzq$y1quSJ$RP3<=>^3Y^kfCDJ~SI` z-$T zv8*0Ujz*#b_3#%nh<3zPRg-``BE&Ktu7UA_n}NzoNnp8C9)lRZB5~_rZ*qXJa0qn| z;{_f=((c^ePEpIt63Sw}i^n#Z<>Ag<{7rK%e6%j;E>>HAUD@*UZQhGuV z%X|OlvD@8_tr^=sw<)OX68ExBX-wu_Mk}j-rHJ`3#t%3)SgDT7u9jh<)R9--Ouy`U zdtRJ9sgoZ0uX zil+@0iJ+!v7N~=bA^n8{8`eMW(K+Zb5aRzyK&>}Pj1CaOK`>w26m*f9W(|-WH~Rb_ z4-F0V0m&pFnR|hou>jx#c%ju2+}&c_M7IX1l3)VC*SV<@^BH{e?p`cKIukkzWrV93YS25n}} z4#v;BJj_-IQQXjf{n`hQ!H)LiGzTyMncI9WP0bAX&c+731b(RDl7lqo3CJW7gKbig z*lb3Ty&9@oYBMTfRe5fs3OkhdLt0tG*Xz%9XTQ97fJZF?2W5FGDE`Kcyz1(cuNvB% zG+^HOr6`elXxVPcAR>55A3f=|ZLI@)wi|K_tDY7?F+w;y=MTAOWko+k8d7wBTdSl> zk;G^ytZ%LT92}_yA}U5se;qh7@>|x*2?zaFd|!Lp3#}8!Q=}y}5+_<-r{|zgw%pwG zzR7cy#-1q3UsYv}$9fHbl_m$Qbq)WQ^k|w*+927jo=1@mHEGi{WRDqd;q#)}`zQT@ zy|rreA?r-y>jcz~zK46hAOXbB&Dd67J!u&lIUKlb6%m+xzHedmguRG6gZW z>TOMJz`qiSSA@<>!aYRh6}i&+e)=^wtt4&kcL%I`OvQptnNC4$H?^yqM)N|JF54h9 z%gP$Fx@NAow&mUa^xF8s%vGB$ia-KsGoEE*+nkuS|MB?q4do4-EJ$No^*dHKG*CgF zUcV5kR52Pvx&;!Tu)gj!nXLPUl!0^M)apb(G)nrq3)`KHVQD+a{&D1`TimyJ^{k5{ z2}R90pashat~$YU;{AaHKsVs78R3Z+mXsA0Ep};)K~!0l*{I(P&&9(oG1m+QgKPmc zB+*{v9KlL5?jT-W1EIhg*Z%8F@#m)+Fw9D`sY4QnZ*CyhvZXaFv(H|wqrJMNB>_bF zU6dzFXL95e#E-=H(dnLsXtW8{biax&g~r`5Kmx>>prB zS^}6~mI(s^4wY}_{DnNHZ)4^cu(Nonqy#sRYiRVHqXLXwUq?ras8cByRPs-+-S8?R zFZ26?o+N!F5N(xrc-Z_}@eFQjV$W(xF=HTxzq+Weg$f3y$!z^ zqOEPMno5{{^MViv4deZEY^lXwwz@5PyndED7xQsb;YE5{+R6DRvGuvrC^+usMXTCz zma%TuE15-PGjsbPEhqr`5s~gJrOk_aGV3(a?CdQ* zKcc^l`EOph!^Xxog%&~cI_{DzLkitt8*-yEr(Wm_n%6MLNJocV?$>@VLD6Qq8L_@r zI$q4a$F}z7G&)DBZBIuu)%Kf^lAl&$?WX+2c$Op}HR9pr^@e0&E=C@#BdH-iTS0C9 z%JEq<05rbo5(Y47G6*Rp%6E1nvlY6zf15KtK7Mb>D9=(+KTo_SJu7Pnq#m0TgB%Xc zA_{W#Tj9!Hy1M9RRE$D|#LxBtZKE<=`M$pT(BIu>vf!Pkwa>@gy2jfHAR%HW(m!~4 zM%@hO{>D0se8W#-(AwF#XnOsppNTtQUZ5NM)qK_=sZs2=U`c|>d%4F)5o(LpwwluJ!|25Un8_Y;tFkHzyVg1O zQ=s4UYmm;0*%wF2CatwPhFATmEv4R3;BX+XMfJc3xFoO@R7GG#!w~X`=*i^-WMqJK zcc+P>tz74#S~VOQZf;v35md%4z3^JYp>h`-7gnmyGi^2Fp)Gm1Ja#DLVuQFQjJjux zrS8~r<^fDj@wjg@#DRGDYbKN=fbpR~A028p$o&_tUciN8Rt#Fev}irMJ- z*;YNlL0$uStS?>d1-srQi(di5^zomXrD0`O%Hm_wUVE7*>6@};gOr}OzxYymj!N8K zDFvu{OH(rP>R}@{rur}90+P-c;l#QBNnMM&o(n#57Cs-mFq=+8_l?qzb*3dI0 zmWb_kRY*&1^-Ns5szGrX-^~Y5kdCcskZqYBjRjH-EJ!QHDp4`ceq6b9M`=+_C-;}r z9qMw+w`F&(g&xRyWso;3;hN|MaAQ%r7b#5O%BFpQj;G3@*&>uF3*s_$g zKY)9Ccz{GMMe+1l^5vX1c`tuYA&U=kH8nN)-Zl7ON!P|v8YgFGkcXgq>or9V31eCJ zVsQQJucr#xF3QfTtIDN zxtZOHRqxZCagagBauwsc31>O`=KUJbyuRgXC_a#AfzdI^4IWY#5~&VLaG*FGv*YXq z<>KOcvWxk}1zE?feSRaZ3E49&HaKA;y+Cg1AU&Q&2O$c0#$qs-GOlaD5Udz^6bV;1 z#Xg$@+^fnZ-sjl2yxT3X!bt-s?i_eQLW!Oadh0VHdUm4+gTf8{h`Z5fQ8+Sa>hU6q z@LIk0&H~oS!K)r7KLg)Ha!3S;d-IEtN0+*BT~Z~2e0;--`(V`59>c}jx^hzN;u}4*=w0r8VRld`vv*qJ_962-UkAl{i?OGD3bX+ zcsBQ1PDp5zkjT?W-0}QmFLCXtO9+xz?yKj>NlEK;qo~;Jp1^dWEAY;!sZ1EThwN8R zR~`ZUXtJh;&K40)0}+hsDEK^ZiUayrImA2TnKlt_G{C<<&9FwQsHITEK(?Ds>7Q5V z8Y_5Nvj`07biX4#S|{(6n)2y5yO!2$G%uUWqZ%Pj_=VJ-ADKL-%PWt`Y#pqLlksd< zU#EpeM%QS&a6>Amn&xl8aNh0|5NnK+1Cv2xQjdP(R8-)@hhY?LwtabJWpuwDTDUqS zrMb{*EcX8}5V&iK1@4Q>=Ws?fO-Z;cb1i!QbJOkMTXR)YFvRpouNIHgd;;i@Y(=?C z>^z(wr8}1Zq8py zdZ84Fx|k=Cik`ep*_TEaOzhazs>sc3i;aqaI#iafEILKouaXUYBRPZs)>mF_Yc0ZQ z?Oo*Dv3vr(0_e~FftzqO@ z%j`_DbAGo;siTF&VnfTyQCE-lbGd9HW+oLr z8Wq@R+k~BB+1I^TU@N603VFO@;%fO+i{IVqn79TzaFYeCpJ1TjHH)9{D}tkFy+NB( z2ROHF(Fqj@%+T#TtKV9VQ;~N_&UtWl1@mXideDhTKF}&KggpLyb^I-tqeGPo zuZI)QLs%{i{Q#N39>VdD?=PLV87Tdat>Gv#_Fi$DU(F&M{yq392z^Fn;PG0JL*;ld zQ@bJG9f!(;Jztof%eb4(O$V>71mp$(8Z$Uj?fgwpsx|dJO$kVGKlJJCC)qYn*RGMY z12gDuQ}{Ieo+>cP{ZrBl7VQ51`)42qp+}RnB=nrffpcBGtmdHqAbKnUYK>KMIPjKO zq!bpa+}zsZjzpdPF$(5&PuZyY%!PyL{Co5z#M>s*Xm8={%$z|F9{4bm&)rTQLc2ia5dO);DGZ0E!K?<0rx#cq>S}3MIsqXHZxIR_@Zbu-BnGzryzomD9ypaz*2vK{LY?bUmR>=lr^BZt_8{u1ngW~ZQA-{H>nw?!>) zSCnp|tgs9oc-C%>22=x)d$&FY>HUSDFE5A}r<2De>FSXc6u_@ISu23_{7W`AeX>Lf zYEVRblT-=?-}_Wn^~8X?I6Os(t9o8ki;?01|qIW_cMktWj^JM>Y`gG0MjLvw7T;hf(A(qNLx zK+DCF(FOKgcXsKp<=D{*Bzu9u#FMEjW@`bL^qV6yA1fPQWW|Z6ML}zBOZzg>#P8pu zg`O>5STTMJ)4!MuGS5#c01@-k$SA8=Z`PP-C-C>m1)g~u(o5817S}^BvVJFdLn?^-Oovj@%J{8OPufgyYh$s^?z0Vc!j?F*gwX93Vr52@O%;5 z*#nCVXkIC2AlHpHY&v-#)cIThFjRX9O0F>co7cC-@v&b@SFEMB8oZqzRkGNI8H%^D z;-~I%LwiQYtFGnfYD{(j;Pv-@ilr4fC>-hg#M7`5-Qs86YPD^{x`n5d-)f1H25 zui_wMYVXjK8mG*a#D-qHwAS_@tGDfO+@QNUMY}vTgg5%BOlh?CHwxyMQeWrYihl(huZ-L3A1oHJAOHkKy*bvl&2~+yDVb0T%XC-B&1TE; zl}?KjCrziA=b3;kdWN!zDcU>*0@#zJ7aI&KsW`KkR&;uuvWyP->DXuWXoe zFP{T4zUun=OuS-Fglf9O_=C1la^fuL&zU`%5Zj0_raV?X=ymB`8`*#w1ywB*kO}74 zB+DhP&r{aX#X$XcHXU_vzuj*21)o>F)K1#s9C)Or8fO_yqLM`kPU&mnu*XSTL?x(A zvkwU|SG7r$xW@tgv}vy*RvC*y^X_+W=7kX%Tz4;Ss+1v%539w>j4c>fC;)8(!TYfyggrCq4us1XLB|i?f4H z^{i!N(6-u4-o3{@4Vf{J5Gm+wZ-=}eFMoh;4&6OrialL>$tWmD4x}c0&E1-Zy@FQj zDjmxu<+LxHZaHeF$k;y~F__~8scjnWArPQ!x97Fv(7Ynipw=S;6-D5JUVows2`2x% zV<5eI@{^j)wK%iGm!7#g{1UJ5Jy!!hzEtyYe@;msAkMh=VJsOGE*WFo&N7jO$}*J+ zQIYD6t%D@I*rkQ8rZX)qepLJ&T;t9Z!Oct22fz79;ocXA6nQtPS&OIA@!awV(;KZ z4L%27C9nV+X{7J4J~6>b+JQ0veKKp^N30PtVs^i$xqrd|j6r&XDX&~&^iXA(oG8rY zAB8T@jrdbQ$-ZZ6bB9YZwzwsn(YOf5qN77No2fpC*vkYh1OWexMdy5{cBf3)7H!j( zNv`ZBP;p`+=%TNw5W_y(9wB;x2uhVQVW~hSAJ;m!IqRMgv#d^}VrZ7(ahgR28V0z*-AeOB5Q@~81cVTJ-ktkA&pYn>jn5yDap8uO zefC*7ZJXMA>R~G|TS5}Ai%eOJtSNLHxt#CPb8@XIR6vaX zwD&Ame%eOkwGou$QviBLTIbnz)BQSE(Y*2FHn$nv>go?<>*H77 zuJ9gG;#3b-Hx^z)ou?J2UMh&;8LBxPZf|BxbU20!)!zY-b$OrGwI7B}f}hfWhbO0C zX9)VquK>*y8`wNsXkHW7Zpe(zm_iN1n)4(RJbOiDao^%$6ztr&y}O=(_;4|f+;yr; zP#{rs`y>6iLbe^cSt+5Fk?~uCJi+!&zM^8=I}fpn@JPsi*kBSTsu7o>=2tE1J^-~5 zU>Bm@r~g(}pM0>j# zvotf?)YyZCJvnp_eLoQml7#T5r(>=VM-Al~Tv?Qf4U$jWrt+Xw(^nW4glXsjg-v_K zo_n3iy@GMpkw>*MM*~=}@li!&hZ=rJ?89`matTvsO9rFw! z?EGLWBV!GFq=ZDN_XO2xHA@J5fKjNR{aKZ?-yh?gc_^sx@@z8Mu4M)sZJti>X@B~4 zy;hhaH?y9E-ZyFP>x7fqJ-u^Z0p9_v`xkm7vbzVS=pfEHA$&7*-a_lTxcK+wp2 zL2Gh9Sw$HMswt|v29WB(ppcdhz*f|GVk3V1qg&b3TNx(uy0Kfggo233i~V2yt={GU zpP@Er`_g5-fSd(-5H5_V5bLU$927$G#!I8+T6WskddcH*TD# zc`CBbMZ2!SA-dg>%PAFP&C>u<5u+2J9&TJ)Fv0TNP)eWLeMs2_P4(PF$Q@0$!;Wm-+|%bh5MVY zjio$YuJ$=pzSYp2%U3l3V+bW z=7YF=c9lNwc-<~aaSN+LS*HuJX1a%5t84w4iHYbJTiUZd;{Pm+egZI##p4viojdD9 zBM?fa(s;`?#se>laiMiZy%}6pSqh3=E0afk3e#J5vjCQCQQG)*DTG~3BH-Mv=j4Q^>G^W zjjOCQAERZ*zva%c9-ScMw{>Ox5jZs;IO=J=rH>BD_p<7D7LC z&#jdzD660xTxVRfof)5JyxSgFbMX-+oP-GF2hS=he}Vzs$j>>?-lYt0Rv67ajva)| zwNmvq&dP$jN!?$7jGZY=QB(;aIHg2W(QUa`FKWiF9k4h%F3y^OjKik<>Qgb5{A_4g z@rE&<;iY;OXT&XLrEhN@+~A{8bNF-d*aAT7SIXW!Po7xul8*mjoATNy8(nH%Gv9eq zFAp>zZm>noAGbD^L;VDQ^x}Fzp)2SsW>ld~MJrc<_k;_6zIu{5Izr-L8ym;MNEfT(HreouIS1RO2)5Y}?ZiL`V}9aXEejphA-H@+r_Ux-6LLeQXUA z10t3q{go&P>DSs1Here7m*OsKb)1I)dG2$1M1lYAh)feMVQJ$$@_RSe zel3&f6!*q{)Ytn~SN|}*do?y%ZH0Y?BkYuIkuxUvicJEA+XQ`Vou0r>-0Qp?vO87t zv-&r)Ok-N7vBTL$Ve!Sa#PQLa*gD3);orFY*`y#(KeDTQ@~(JCRAIKvVE z(mXEV_(zBT-aR2YI=qPYXZV}jzIbMTJH5|WY z7^u`&2e`~=b)=pxC<=cl4l4dm?0Y$hpp4EmgyU|IdVzv=;oc}pE)1mOEd@5PPo7z` zK;$c0Tg`i&+-oD^G8SOxq6XShThmLsZ-f>NnReJXIQVO{jbrV{XV zN(NgaSjBtsuGZExRG}^cg=-;eXum0LTe6ulbw0w=*$O-jI)Vm-n$W??&+Yc`1VXMb z`mufn!c51RQ_I%fC$h%!2hX}y=O-9YM_HXXI!3wb<7)CSN!&dn;v{6tYBF> z?FhtzqK1dq(?B!bxeGw&k6 z0IsICl?Vm&^PdcX^T&93nMQhgA{*rcwKw)=vYe&%0}y$BNc@`)`R#=q#@JfFZfjq? zXZXeNxo1>eTbR%Cb;q-zxj&_TrQP4*)YNmqD_J_mp^p0OL;%zMkr>-(4E0fOYkSQp z2`Ysjf}tDqB@-J@r|ni|jh`_ybueC+f)W)pxi@qJBtt=Kg22u$T1BR+8Rg@jP4nWX zUCw)9j}BMN0$Gfj4iD$0|Fi>=-1ZV4vnSmafy*<*A^t```O5J&umUtUx35o{4~r0> zl0x@hPzt}g%ql)DsaXbBxxSyAJP_H7?LDSs&1>6l|M=yL<2Q~zIoCb?9P)f!>^YY9 zgWi(aoVXt21#{aNMFV&e{ZW$mwiJ*mTmdBBJ8c;~>z?WTUw4g99sz3;4sEGkB}Coq zXQLNKFMx8;yvF+^2M0&<8qf0w-!z;gsj}js4RF6V{@k8A;}4q9wKXcAf<=ay_}$rI zJSPuI@|7{iWustUO2*!&JC{xR{}~xyI7zGcbf5U{-I;FJkG&4U8EUJ0)m^2g5teJ= z>5aWhonVrbb%zoZBMopv<76KLLJNM6V7ip_U_tRq>9K|CC$Ud{G3_xF3LDuk!1?uS z@4gH2%h^SR6svVGj_S)&61^q^U}xBTMpF^pZ$p1|Ui*hlA+n?lCY}ce+H=}68~~s| zekrTDi7T>ZwDgPMs|TNikybT_qU#>@i1bt6tTz-(B3aOVCr40|d#9ZKls_~8+<@7a z;%hi+sC&B7A}uc%wNW>Uuu82z|EyRTEBR`b8;AlC`|ZETUJk!$%~R`3PzJF-_|mm( zfk=3Sq)kC3?hjI~rKF{aZQ<7MIlIaE4cUwOzPyTi_c$>r$qSO+hHGgt zMUUv~l~x)^KR%`SxvHVNW08gN*4u3c8jJM0*zU3w46zG;2+~0h?)Y&*WI*M!!}Rcz z+Q)mIP(su&V>P83P9KmS~Q9h_;9B&51{DxIlGKd^HuGUXSXPdZ=(;+{>cyb`fv!~D2-<~(UXaf6n!DdVY9QD$KD=cb;R$Z*r-&8{Xhh9yORF-@_=DZ6K8c0!Yvuhjd z^MF59^jHR_zK*u0;g)w%_YftU9!fclvZ=lEYokT4$>(aTEI6WS)_R-le}}5_JvUSO z2fMbMJcZ#|N7TF!4v=FbY0g^t*}6B34d6wTMc1tqN0B~jW>7dSs0JVWZ~Lv)WeBei z4-emn?k{Oy?pfi%98nU3}FI()6@{f*^3x*RfuqMXMj2g+0u=m+M zs#lzFwf9)fum$HQRew^_Xs>sTMy|f%1yJ^mA(ARfo_Sqdc=%A0y(~SDG#gUTO`3G#ivdb9QX`w3W?o0KPM+e{Nx*NGA=`r&N zG%f%`<>K+rSNgTD?));vbFkN~i#Lw!*O?2@eHQD^V4XO}3S@U0Z{|F&0@P*&iU$xZ z8^Q0qIH6N%1{|C%*e?4&7sGy-zR0yyTx>ozVC)l3|+)y2d{)y&uT(*N?Nl++5N(l(AJ95YAzVQy~4zpPjN zxqy%JdB04xob@8B!$Nns)G{`qU?hN%fx)GG+;By6hC3&D;8PLd05fIC$SLRa$#L+L zYj$j#dDs+7;9`ao!vTWkqvTS`i%uS3dSl&FLS~bpr7T9(6qcszVO`d!@|*jGS7B@C zxr%j+uu*Trd_vr{MfZpx`+c=ee$3B(X|jcvHxN&#Bkeu|(DTyrG9ZthFMsYTC^+Ba zz_uXB63Wuv1cdycW=0r@;p)d=*U**%pAtZa984J4@Z@`~&tu@-uqbX|Ad;UF+rL_F zcZotQwW!t6_PlrL2W4k5sj=hIK}GJ|N4v@RUf5qEw%ZPLsy2`1OpK+3yUoC^-g71{ zX@ngQ>eaaB1NFLC23q)5%%}(gAez-qMwgXG2h0S~0fI8|EHblx^w7qLw0Vb>n!yM23TgIc|cJxGsXj8zYIhQ z-UF%$Q)Ch$be=qs9sW3?DRYge(oVvu(VeG3($X!Cm)5j<98(e{^>myJ#EjTJHZwCb z0L)8(+yhw!C}DTb*Lb*mEN^$s&3H-2coXoKoSi!dH$c0=&P(|*2vU#O$?v5f4ix|0 z(ODo3RqIW;%Yv4i{qGL? zpp^%dBlU_ZDsOJVi{vS%Trk@s_;TszarhdX^Vx-iI{C;?BCm~C3&0*RQw-mgd@5a( z>r^DR#OC}_*r*59@KKZL8^eLD_|kE}?*rQdX)Eixa_%5W1&Q?Gh12%=XCKe^ko;1f zC!;U4J;Gi@=Ss6I+qdz9jaWW?RjPe?Tdatpb^FpJ5OV?o*|}56K>9Wo3@iWs{VkAk z0EXjnn$UORzW)C6@5aO*T~PXuEkUsINMelq@uwXbj%{7PPFyCC6pj$yI~%1I22e)A z6=0ljK~N2+0z}apzm2RCuEsTuPQK6lRB=M#TEyJr2&t;G*$kW`%a-1C!jw!v!q8}z zPqh$@?S(CEA8j|ngO^m3J*A3q5}?sNY4a>~+)aZ1GG>37*LiDe>v|GK#1?}LP%@G_ z7bsVkZQ*bH+1gN(J6c;Ask2asdvLHW!=+JnNlnOKi1No#Ovfj2LmgS{P)n+DXLGSYD8=<>a@A$HYleA7q3qqLS@A;A93P7 zj5OGul5`vU`m!aW`_t}PC2`Lq3#)pOJX%0-d}UN>AZ{XF6xKF1`2mYda7%gaH;a8I z%<@!ry{uN4#cArF_@HBtzjiNE7+rtMAp6t!PexXs!_OYFAoo$Z0&<^Nu41pR9`eQu zp|T#2D1aPw-OcaTUheZh+=S_b(O(Xp>Qr(HfvV#CGjCnmNVAN*c-5X)53U{r zQ2IO%dYTT|hf;FUMiQwf-!CtoOh^BGL&rdK?^DUERox>*Q&k_2NO28ZA&I&ZN*!er zK49vE@CILXVJhnC7JWG;#igaDjRHNepX09W4>!KM&oKEp8}tLRfdTcFvXie$b+AW5 zp6{C&{c*CZIkPtJY>~QKTb7>D!ZU^?7o7Uc?Jor@UN` z;`FVBu3c14G^I=XyI-s!Y?;R#)xlcFreFNN1BzsIxR@YLNURQ9vbxJEYb#()x!knU z4Xjk*&w9jhn6+m&H@)0(b%VK_y!w*Mwf0>JUarEEYd=!d_7ZhKXNDJU)Rn(l-FUJ< zzsve+A`wlx$G(gmy=C@Mz0HiEDCkU;nqL>OBmKi=n;5DxD&>p08=u%t+nfpCxpA}$ z!?u7C<;Q4%2SI43u#NjTFuADc6JRI(>aU?3d>SK>`^EGhlF8dQ$1oAv3Wp;fRJUSk zYlSvFC=OEF;1!K?qc<@30eq?XqZ!Ks_$~U0>!70Fas`8nEN?gN{1ka;*7p%AX3ia9 zR{70^xbW^3cePm3Mf`MM)!jA4;+M$Fnn9r15Uml)v#BO>Mp&eKc{A7oI1n^&o~R8f zL$Uai(zNpU%QU6gT&60|UOQpWD^S!Nb_IahK4C8%`2G}ef*apM^97R&u%#NFAI(ks zd+xc;cD}wcVXvsZd++&_6Y zxDYP-xDN^@4F>?#t{`V|dF}R+wHbH(MjFsi?4sO+iqQvQn;y&K&{Tqdt~sb{00&&O zC>QJGuw-6#GESDNL928{3s7rjBv**X$5WsO!RcO>o^_R5aqCE}Lw<9f4Mizuo)>o%AyW0Y;gvd;gbBc||US=FX|oyNw5zfIL7Y zUNz)8>$ezY3PtDME7Y;7!%c;Sw#-9Tn%VJk+dVI;!$W7lqnj7O|9lQ)DNAn}s9GTa zBu~aRA-G4JHZ7&DwdG}oz6V@{j)@lvl(nK4I@REwl)I5`qkr?- zV{D;8CX#x&!_Ei8(*X+~TeTije96;_+*yvsW|o$1nVbp?f_)vm4k9%6ny}|^7~`Gz zf$VJowmB?w<>liva-6)AL1+t_=S`>9Sz3K!r|WOH*-yiQ(E^8nBF1Jp(@^(&^LG!- zf*Wo;+Q5_&=M`h-b>*Ar_IIP3u#{(OhTawm>G5d0KOgKI{Jw{ecrQh0{ld}2m# zI^22@OKKK)LMP@}-cO&)xhef#Ud^e>e70$7Isa8*8)q|zPs~}i06mPQC<*8bdDEK? z0s#AAG#Xtmp$vUZz3DwQ?kV04c7$@+x3+@DMO^XZOL5RG%#29d;!ozD*p zko0K6_58;*_IyeU(b7bg#dx)j4LtTjt{?UUV%Ycm>q>j}X6~Ha#eazT(m0(pv3Ke- zIGCy@Ya`Jl{&O&YvmVg#1^4l{cg>~Y3@1h|_|`?OveM(s%2j})`PpfP>2!;B@i^M5 z&W}DXGo-?se2*?N`hl`2=30X1g)5K5~nyqcizIr42 zFUiTtP{iA0Z!@oVv#%4RKUY@jDfAu4H_OuJXbA=M_;W-JFHC(l;lAXfcwv3p59NY= zp?vCegZ0`mo>WbIUlY*yT^t33G@H?U+$;%4G~De8qYXQ&&AS_Adi;kWTY&5iG$}Sa z`II>CR3VdO_u?Hr?GNR!A>`1fUYC%y?cwajNgvV43XMtvzgE{`^?h`t8Ebj3pN=L+ z2YQ?yJ$65IC_r@Xz>METe5s3QX3GWm)DP9XMxOYSg~8M3TQK zS6J1!Bu@K~Kfke&+v#@-9$-tSn&Zh5dE=|>iqp6**A$^7RkvG40`jM509SGZrSiG4 z`yo)K(2$_y2^tdqm9pgo0R-l30V8Z^~bDqkqP?Y4aAt^`LjEMwOcZA%r}mKA*n5V0l0BTiAvWYplN zqEe7t^|8s2EOue_Rn>+9LsPR>J`iDH>CcZCtdk>&S}zk&hPnM<4N4K%KqaW!&2#I z0R-sw*VR7tYKitxV{ibX&%;QJ10@aY}#i?bii=wUj{cD*?Z`#cLK%Ywi=c?#4Hc;T;3xj+-LlU}!Jd9p_Wjdvo%_g5}c<+|RG*?qwC@ z<(ZbUJ?{UBXWt^$Yd1!5i>@GOCw|@AGp!VHP28`;_zf2S4QhY@)8408%zkumsCEfe zaZMG0;o&NfraZ%guO30J=FLul@u&{Iq{Ti}Zn?W4)D`z1A>C*8yPFQwA1*bxh!Vtk zF&Wcj$+ZS|UG+LJBK2f180#5A@W&NSAw4(ie+fTV5&3_e?VPWHE(ksk<*^X*QdH=B zYv&IoJc&bgKwNyWdz1bq_+d!~x^gCS`A)vaSGEyJ>a96_1F5uN$ zBR&1(tflM)ytlQrB7*$=RJr9qby?tH{USo5MiC z;}|doNqR`~*Mj?maK74*UdAH7%m;N#IadPNBF8dXW}O`vam}A+OY!RO`jyzfd@-VR zV0ti$)ud2cTTyDR-B4t4a5KzDIXF7VrL<3Z(~5loMx zJ?9nZSWg14(H8F136Ht33-j79zOU1aG+HxPg+G2CMw_rt9U@+Of>cu4cmjnW!rxs14C6`IunpF>o!@gQIA2H{m5!S%~k0ylpdASe1Q?TNYay`UGsa za1!USJZLwY2<5EAQ};ew_o(F!Hwu00q$NBA2YjBcy=F*~UP0kYHA@E&=TZx71{^E{ z1MhLFh$Nq&sjs%B`%h1Vbx<>-Vxsb58)U+q=Lq5BeTj__0GIb#+Q>@Fb%n%N_;_6SE9C^Nc`iSGF7)D+JL1}@V2gFRI@5(YjYP(yJp6p?{O{BYOImQH0NID8}q%+Q`kN6T*3WlexB=n>jxl86SU`I+0jG% zj|<=ig`WIoKe^em+ttw~mdB0!kAil-BlZ@}b32g&RMLgB4$?}Zk+2tbB4^GIU<&TF zPfc9|0Xj=$M3?K;g?Vlz^S}$9&%E{ngPz5L;78v6+&KCINY_KJho(EZLmey5^pTow#$-SxoV0auU%i0W@iPX`Zf zS0qj&_9ea!I!#9zyT=1d&?mQFME!qFTHkAMFVy)k>)RU2{{LuV9VLHO-Mz5X@NY5* zRkzq?b+wY8UK4ivNe4!AA3w9S?Bny`12gC8Gye@O`p?4<|Iy^v)3z@o7wi`}@85Ys z-Aq8|Z0@)5RT#C}28r$DOV+T-{^aH1?G4J1`e&>oQ{15AgdTSOL&QG@#7TfHyamKe zU@*oy=Q-}xCSl-ZV@kc!vB8pO;_MHwj>LIM7}@Y(N*SH(Hc-CsUs=hUdvysxF}aX= zzb+)n#g99(3s?pLYH!E#rZ_wreZlW`pK6*dKgpIXIg0Bj^8`;Dg}T^Q`5ynW5^#Bg zbN$b?x6-#wWmYnFaKWF%Ub_G8X1_F%<+^d=leIML zE<7l@kC=tkb|Ic~Nf(osCyZB@;Lv5=>Ek(_Q2_3p!oTdUF4gN!OF>2Pt3pM1g)O#4X5 z9y7d&_671*Uij>D+wF}Q^Wp40{wh@5MEeVQTN9M9lI*PnwGxwiCEI=t!Sy&~EXL($ zRH*Z<|2r>)hGrne^KR%0aAN|QBTpD)Q(S?ajco{tL))ve@d{o%D6-SF3OWkX)YSCz zUl{xG>(?v4trZaHqQ7Cu>co(Lxu? zVtgzzrky^uKU^GDabqT9Y$t~d*{=I2IEI8wdC^VTl#dryBjc&xT7r@N;_#mwGn=}a z|N2zVM@`VP8E4)dtoEkL7&48(oc#?ICTd3mzMQP=$0`J92}VabYv_t3kARfi@*4Xv znX;QnI<%+@L1B?SkudJ6d#d19Rv(EJa9~i~mMcc(cgtdDEYrV-n7jcp(Kz4vzl)`( z@vPkS%QKDO2k?RTp+66d$v)2MQb87iwcC0;{B&?&)QIJe$1wyWH>Ib6AeA?%+W_9n zN9+2)82Lk-jCOhH8v7)B0cxEnkfbJ>*?91`+jUG~x(sTGEy@U-emcl0)eRI=(4f0ZuI`KBe0gde)Gm} z{8@S6z65+x98EURbCi;)6rz14myp-;o;fjW##NVwgQp`jMn69L6G zTD02e2=?~zr1!dbhc^C|nZ7&~ucp3~(ytN>8|8{xGq%d?@$QJ@QNNi=gRSvdzMb&G zGFQ_Ss!pcJjvB4?USo-9CUM-&9@NdY37a z1KIfAm#dq=IvUB8BDRAcgZ{Xaw_^y?h*D$0}UEX!b<40V?If?DL0-T zu#~JXt9jV!IQ^@O^z?Q^~rzcFd3f>ESE<`C@KDhP( ziWbU56=@eQIesVebHr$B*nzCfepKxgxM}&n1ht*eX9){8(Z9M`%07P zPbs>4&0&wbV@vZY-!RH9o1J5ciiweJ0Vydb=h)Pg`6yXFBcpJS0(7v$LRDnom^3C) zO)oaN1YDaNHv41^tcsu!pk`0@FG8Ke>-Od8g0)z$B`1I*(+m{rlfZCon=oAz8+)<0 zug?Yi>x5tB;tI&k%@vcCEt*_rdTNSD*2w)^&OG&{0Z0Z7=RNL;#P_p|yYEpF07*VS|FR(Ip~ z_Pz6Q>+BvYq87FKYu-mA6+D%HKzgED$leD0pul2)l_=y(4|em_R~hqjEdq;Jb(a(E zk&-6f{c0QN_Qk9+?vw!{AEfP1YO=*T$xc^LKzJd8t3E@6$K+`0l~>P^dX7X&W+wXJ zpgtG|45ZH_KhC#U?1NRL|%)et7R?nQ4N=7=tb%HZ|cF!1}mYEJ!ut6R<>`gF$eaB=_f zS(p@`{_d}NSHNnFTpL*3N=%mrqc=lpDjMR}2*c`m+C~s!&V2+Eq_t=6?y5mq)C|fy6eyE`aDC>|@l*(JbOZ8%b&u zNN@-ett|B$0tpIVfD{45F!e?XA8H!7i=fuRw|h1%oi8kzuPr0ZiWC+=jLDlR=K?PH z;JuU1eIA2ln8|ULy;8{0&G)SNeEVN3xL#e|`#k_WX4KH-_hBJQa)c|&<8IsP!*o=5o+K99R*Wh zy-!Vp$O?!0j;_bU!STZpymr6AZ&f!Z3UJenf=WP0N8(~oTkBW9?}zXt=mI}Evo{RV z2&ApbY6LxfFmB+6ifn+u*;Ww75)&PuNz|>Z62s{S$WQi(hvM@a->X$?=S+u!L8`e* zOP6+}m&XhxQxEkYFX>ngBY|g@rk2)PPM~>NWV8&{`D-b7-a*HA{O_geUJ>=beLX!Z zzy_!gHI1}na_3Ay@v_kepMIGkC* z;ExNF|B4USX(ns+36dNt3V{@OdS+U22-M6f^QhfMM_c)(K@9x%<)QLM`9lw$lkB&h z`#auR23$LQC@bk51z+BB?tUc)PJq2E03gJdm?fy?T#jfR!D6j~+$2&B1d{Z?SBcaF zC}!^`VVc8A0)65qcT!MVGHV})BA5kJ>xVO3+ysEEZSZ$}0{GnGVDJe`dmB%C5N6%e z{{BQ|!N*@e%Dv?V)l}N8hY#Yr$S_8nit4${Dzku5-aupq!;NLD%^dWV1&9 z>OWy2aLFVw>{Ss-xi?IrN8#V8jg(hy^mNhDq)-;hm*$61423kXu5?4F6XHXV8XM&&!iHxi`0Z#Pu`svddme+K`rTXNy+Ta~9o%}U+`V>m$Wsssu6TmM$Sx4p2!2zw%}!&DT0|35YGrP8R5VX0NYK1%kT;}M_aauE4;N;w7b%1Z zwC`asnA|->UP?`5;PUVBr!35VrY7MaE$?-}^;In|&9I2>XXu|LMUM7-rS5-_IHg1U zy5he;T3(Tr%|)YY(!pT~5;Ty!#4-0*7wWJCk$BD`eWq}tHkKBi`@qOyWNsA16aZ&(lWK4XDKjbXYNgcElZR#uM+BL zV&btVA=x&GM-T!5Ty`h1LJjWW@3d-Z|0I za&7!y2Luhm8RjXN)V=yMoE|)W)V%Swv(LTTH4cnLAtir+Q*?s;oraaW(OC*5XRJP5 zNZY4afdif1=##do+`ehv_ZAr9#%i8yfMGR1a|C~i^nj;er8B1we$Vf)I8OyT-DuHi z=dBZ{9hdhI)<)LKtfp2DBUGZi%lP&FEzC zlu~Y)ncuoP{Q)HYMDlQO<4&@38g-u%ze7nAen#gL}?pwO2@P? zC0roA*D$dwA$#s`Tsf$lhSt}=H6jR8dxYm}bS>0O*^uE*t>cR{Q=2xuN^P+3`BH-V zUu{o?TPMWq8d<2{YZ8%J3qkh%iHtbz4Ha{6IP~3J)6+Jn?hQN~%Gui&li(h8bIqZU zN&M2TZurR5g@uJat}$r|nUL|-*QWojBwdT3KN_fKj!e*yu+j%Ni6WoH&s{m@T6N~f z1UJPCE>8ldVFOVG4q!Iv^Ci49FEeolVWsP5T(*tfkPYxPk8&)--3IrQ<0>_v{HcZ} z+_9Plz}}tuB&|F@{2u9z`n=`$&mf7CJV)Hs0Z;>Bx(@7VKXBxiojKRAi>A=^8@?e5p#HGnL4M`uk#u|vqsqJWt} z7Jp*tt4T1L3Yd(=l_t~m^c!*3fk97ygZP+>>N7#R_HZpdfEf%mcP9*FoSD~B>pIV% zmaMS|$xmKi2Wn@KSz<%$)^M2aIdhdlz64%K8ieSfoiRdj!JM}u0|G7BaUP3@UnKNV z%)lsEOi1YIE-RS6TCy+2bnieRqP5G`$`_7R<+e|FSkwN#^$m6fS5(#STGlY;DLaLC zOKd;tEwxCAe3V^cMp6VsednhwyO0lxZL=m@W_u2))VO(o1$o&SJMI`%#I7bZ!MgtIaitH zDv??Ob_!6S+^Jvo|NSJ7`IMy@81PoSM*-{3!ZA!eHs>J2hNQ`IV?KW<2+(-UqI%NS zl4R3;)jfqc)kDV8feaIoKyciEGEGKax_}bkQdpr+m;<4~J%%qH=McTjHB)c0Yno+U zTGys|wUSAkz<>v#>~qDU32o&>u}HE;cNy7V`kSKz_8J?Tu1tDqJsLd*zeUYdzvN{M zMY*E4_6t59_oWYe2wIM0#Kt}r)hP`JZV5cVF!})$S#A+1dIjUo?WH_H`u%80$efUjkp+{M*#t*3J=dZy0DK$LR5@y8p@U2-A$q zCUt=uHmTM1qEq`|R>w!R96NN6h~XLH=qt0RFJEo|5OEZ`@4gWL7CKw^I zJASY~IGE>0t-q9lbU`L*>t1}P(?VNR?cNG;wJ`gx0HsJd80J?Z=VK$2I{G@rJ~Ik* z4VHm2TqOQ02E;26({jKw-CY}~6J2y3b)Hc$SmA@d37c$!+I<6pLhO@A;1ZD)Ju?5# zy*S9)NC_{ZBAa$1tkYnvLASpaL20~QfI=BbZU$+xMATk9yQ+LId(}oq(xP%5Oop`r zC5nNSRVJX=Q;}hRsH1Gi;_fmCApp!No|}87I%FmrFa|H)-2>>$on}(Pa;6muY7rIu zEHmc;Ebbp*7+lq*clz=NZ4Dm4Kn2t+W$aZ!AU#BvT9vUMtlA9}u>#+(LJ}iD&ER-Y z+yLZo5X?maW}Vb$UQ{#-eEhJmV;~f*Xh@Gc9<+qfQh__j#YbxjeqA8ti&36IG`SlS z0UQ`w>6#Q;;a3E5?a4t*-M!Bs8{z#@4l?&K`=;scg%s;g`h~4j9E982oSlsTM&g39 zpn7huO9g+aBW`PF_M6CRcwrg%V|*zF!%~ewK6k$HsZtvKiq6K?O$yCA+1gJ@ZvML+3weCK0mtg7J3#*ewjF&wO{1uiWhRWjkm2thMD?ReTB z^PEi28q5!^^>H+~e)(SyN}!dQ<5a{yuvPHhYTg}HuF#z?gqen-uyk2*_~QGD!Thg_ zH0?liTMHwXQlBLVaF&nDCSws+aXd;)RLS_U@jkhF+{1i=;#4|evi{yPp{=<*nl zj75i2lFxUm53O!}9mq&_#)AW$I`_{_HK%!CFiV9)lota~kP<4Qs}g-}lfX!3Ee`?- zwit?7g!|q;{F6yBK~#PFJU2I|mMK(Lo`I=11obLF85j2{P7Y`BFKBWnv;q`IIJhAI zY!L^0Q$thpK4*+za3gHhFbhCD@(3Z@f(!Q>%HX6TD*z2!GT==X5hxFAsZDu)N#;Z; zj8RvH5PWFNm#fJ>A1q{hAA-=N*2P0~48`ikm_Kz6{!YV+&R852lPv0Jhp7hMi~h8vvb~unrj@Iq=ya1|AtIR+9pM}>jQ-bcdah6<{vAxM zDs;F50LIB0pFE%u{VI8vyYRT|8%8dFf5Mc>m20e=oTVq`>Zx`aV*yS37R$h&@#B`z z_rzWYP<^RAgRn5UN475{2pP$wZ~x-61JtFzLE!9QpR5B0ilBgtVmIg){~}n~4;&w5 zg17QTrKKl4U)Q=*7wA*+5~w?qAAhNWNV>0t>}~?VS%hB;Z2G(YUtKWVQ}>Js9Dyz^ zY%Y-f?D%WJi`v<_U4n`9ab3N;C{F}ug&oeY6Ita9S^7SfYEeGjJd}%$fZ$8S&lXFi*=wLDsW*7vCB&DN!HDTsOJ{UPd^`Y4ls^%_$YnRYRw~>&$ts z`mTm%itf84?sIZ-8Y1kT0yr)~0xWF8onN?ca$-t?UhsH;MkcQMPUXMKtmZCbKuLhY zyvUbO4iY>}drn({bb-^T; zMPrWCjIr{;!7f_?^Y7P1Thh*~s}}Zvf2eB*`osToJEgDU2h z!JBRHtmgq-l?UDoakcqh!CevpN$Td`u~j~|V2 zgZ7UuwR66^ciOGnnMxVIfd#QJSCS+Jt{9n)l4Vx=S@j+iGLCwHn$c#s9 zp5gwdWnb9y-V#eE?cl4AicnnKBRcFyYfI}Huw1zoK3DT@zW6^!q4?0z)WxFI7(_!T zln>=Wnr!I}!RAZ)SfPY|6bk;CvDi&HQ^0WUoW8@9XeRoUKCU-ptXIRcf2Vb*TOBKo`CgPrT=y)d3t-$ zbr0K*=A63s-S@^ZexYM(f3$C>C2ZFu9sPZ~VA(~cLQWZS_nlX(J+l+5u^d~X-T8UC z_Z!4y)twms^)PdppjgR~iw|z{25F&;JA2fMlA{XZLFX+l(Y$Y*FTs5O)8ye_HQB1# zbYzUj2q%g2mLD+^7B%^UkFhq6ShBc{Z270bqm}7?RmOd*-hC1^i8sf?Y-cb2j|)&; z^D;#DkOt$D!+6bejAyDQv21ZE1O9FFvn9k8p7yV+Q6xLNdQvY>ad}GX_JcUUhlC#< zR#sNZ=FmMHI>0b7g&SJAB5q!+y+g8$mB`-T+XI@L;W!a9!*$c?75|$T+2SN1L&KtS zRo^azK1!M4%c=Ugy~e$-e)yRjeK|A!lm}_+_cAkcuDdGv!296E+dX$q5}pyo^ll(2 zd%bT6v01`d=WP~V_GB;WBXMc_OCuK#m!z3)`OJ|XHi8rTt)zC;CHe~smbQTSCJ|Su zb#tR5qs%GY z+u|Y`kC9{(Nx>chTk|d`k23zgkzmU2H&8enT5JSc%RidNS`p|eIm&z ze|JJMTQhOtkN3}KFo{g<=~#Dy_U)9$XG@Lu#d)EAKj*$LO0{yX&P&`+jji>kOegN! z@AWe z-8Nc49@4`e0lD>#=rFit2Al`Z)n#ag(w?oY-*2e*=*}ezS)nKJq>tohFSDcK2t@7M zoFAJER$G)xJpv#}nUO-l(aB|6_n-A}5^U<~iG%hqYH&g6ZPiANTby~BTMss{WV zBK>$Y-^Y?OrJ(9BdG6+zrS{P~{rc;VD~6Wpt1O0=Lhe=h&3I)bCsfOQknfZ2V_n=t z=jBW>8)TMs3#!9mpBwXX%mbgzEj*Drcs5c^zRckm@Wr@3*sAtYqWoI?(j8La53g$) zw}ZhOzSy!;nl!1x-~C#hZt0n}NnbP7o{R961$3s|#+MdY^GsM%Hs<5 zTj3o9`R=7Ykaj>h;tst9dz!o;MoN8DI#`P;}cGTZjBfj#14 zcP)G0G6k;G6?*;3p||Y@ZNa#p{omI4bQ8>st!h(J5P87IevEZ5fi+Zre9NQa`wcOM;^Oa_C^1`4-TGj2#Va`cib5*MK z<-kiQ_KpNnr9jNym3A=Uq0_eD_nr;%fQ1U*6F~Y-)m%Q~u-{1UYiYFS`#rG>yOR(S z65@?l^)?L-8bVPnBffuCy!J^YYwgb#hVPXE>;0N0i^0I4D%5C&f40J}O!VNx(!xLD zG(2?DQR-<4)FG)RuE~tH*?i2{qgt)IM?9vt4!lA?cKQ6Se+(E;Kue2ybe#;*AGvk1 zdgqP>3h)+`!twjgT-Wxp(7|5E6Y4D!HK&PZcOXZP$|%=S0MZwwT@{~xaXs3VyIOaC z|9jtt9~3-M^4t!BZ;GBMGHy#qlhUW^+sT^^h-!gw)h2iOy1TN=&!F z-Nv|2wg;lFC)AyD$4_xGMfjIAR64lq=EcL!`9HVMyHy74zGsfkL z^ZsOk=#q~5Fi{PZ>zU$W&YSS?T#-@bmib9fb6f!fOH2YgB|R^WXdSdHt#ad}_nY9S zw~DD~ivCv9ILqehY~oe!Q*cnfJjwpdWc<(APGI9~o*11(w&|Lh{M(+_3Q>J3tn=Ac zQxz`VCL?v9XHAo-LuDILWv+JLzkXHN6In6?3{*gvRl77ae%sQ8X(BF!z<;Kuep6U% ztg`uFgKUfW@@!E@G4aE)IM9>|%np`M{Qd;m9CjcEKly&IPeH8)+~&WVoD?mynh^iZ z(-md>=&#&oql?R6P2)$!FadC62?gQmkZc5UM0p;cJ}FDoxrgFwkq(l+L3OZ?n3nx^ z7IYrfxwnLp&D{Wiq@5Ym#Y9B(}KJOdvd#EoU{W)3f*JsCiyqe%OTTst|lGT z=h0GDp`CF1n{!b{zRtIu^GQs`brZ_cIvMfbABS>9cd$y|y?aqOX{uW^NUg3%O zi^`nHdeGRZXB4Ho!~v8LHcEBT!vd##VeeqSrph5xckE*yF8X8Q>I~f27pntgZt|z= zZt%WNp1l!~o<@_<*PA2LIX~~zt2%@VT{ba(Vcw-Gd42G*_F{RE2QOEMW2zNnmZAB0 za;)wB!M$XU>|O-s=3hC{W;fmwdI)u>5eA2A1^Bkrw{9=SZ2C%Gzsv%%oydm%_RY%ST*MFpuQpZJ+YI$8#1MYd?2JWon?4sG{S( z+mk*_ra%n2-M7p|m+LH=VK?bA`c#`7ZliC|F|+i}v4^SBat(^83jK-eJq%O4#Rsjw zNsWtA{K7Hs{^L+*iM+E??21!t?l)AmqR-q3jQq&O+{qqOWpqd8+8hrz?{#YDaK#$x zPsdiSnL`5@rsQ{u9@paFzs zXY##O#yRsfb&Pd}b%@(Z+1j|N6MmKIS{Y(V`Z1U`U+Y+}rR8wmG>)39c0ZKz*AreG z^(rlr7#xmVxGQ+q#3|VYt}qB((S*J~+6QoZYq>6E|8m$AzFaZ2d5&nF8rBZW$`r)TF2yYPx@mC1_~2~rYz)?laT-*f%U%gDV>^%Cl9ZefgUJk+NC_`iwe*p zOMgW&mjLp5!~R6SqNRfBrWn5N&rh;-o1vyt2fB6Y@}dF*VCSsLLcxhktds9ZN*7Nr zwg>Chm6yp6D#hmH2Q>FQ+GPM{ncQC6d*tuY z`Tuh?zNAcn%hq?UDsp{{S*g{XxG$)^P%}zib|2WR_gRJ(78U`=D=RBc7F*s6AMc!B za{qsEHiyLjb89bctEFpE7-1Dh^*f?0Oid{&uh85f-k*+=EIJ{MV!SB%-M3jdl|7~4 z`kpF=dh!{}+YbOAdaOL)+l~;IwPKs=+8fzfJgs3r|s52mr3muLU-5J}nsU zQs2jnw@lhnYBrF8ZgO9nWq}^Qtj^6PmetW3B~^j2mVv>(&p$mJ?9uO4Un3q>RS}fL z*)SY5j9YLxBTALSj)%v6758B{6L4kXd0GIJHC2)>41TB_>_yZZe)YKJK}?-J0FEf;eVlE*?=f{rU+_Plcx_~D z+FWt)ifWWP$#5_?#&3@0fK>gwPX#Nc#3kU&PhSJOd!>}9in*Z9K~Qy2l~9!^rHYBA z+~r4gP60)RFB&!LuT~UQN{4(YrOd(>R2~P1DfZ0{+9hi()Sc<@eWpJiQ@$F7m*~Y- zf>StRbDCV&KGn+5b`d20o?%G6MMGQ{UxDz#jZqA%9?L;Y)=%0jE6m4E#&B<2C?e{{ zp}Bee)*G9qI9_@ewff7SO2C+Uqi@X}sa7;R^GX}%>`GH!APxRK%k+mIY6HD0*XV5M!&xTNOYTs z`Re=Le3w@e78jXQ?@%HV&Gaio$3Udv1BbC;e0{8n2eb@8{1g9eq9Lj8xa8t_>gUk? zb0!b8-tYYF7ZuT4sjq5s-(M5G*OF>vPAv) zFgI=s2}UOY&t#R4zSjof$8}-wLeslSn@pS4a208ZMU1iTZ3`)P)Y6g zHGS&Ql%HbLP(}HT(Bu1&1|P z--74xY4I0VR-R4ELdcI#BiJbrBt9pLDB<^UC862G8#a1Vv_aBC-g|J(VekH4T>Gc6 zun*Bw?RlQHC9&A$EPn8- zDI`SFy!vW$Hz5W#@4riH*;8N~DYbxf6O(6GsMUj;2HOL* z7Tg-N-l%r%C~;vo-@%*9p+DPZZpTs#k037cIjdvYz~gzd5tO)cKYlm6ty2C|Yhi=g zVYX2hIFgaR-yaxwB!^cAH&h4blmyE4QJ)>5S?g8nQ|)4WnDH(6g+Jn}8~V>!&H1*O zz8jt8tEF>Sm1#Hk(r|ATpG!V5AM6Q&VoXGQ#@krVAViHu4DQ}$`^5h!OQH^Fo(m_M zC*nl&=(VKYBxTu`R$b%|sh%L?10#l-Uy^(?53>gD>z7rj2G#c!nu8htfVPyW38z4snQSnm!Rk;jpk(cA6 z!~q4FV>BOh{1$`g+?F?YwrzvYm88v@?6)Cb8Y+LSQxdba1}fHWv!yPjr4&onV)OVK zze(3R&AD?BR6?xy#jd_pWQT1hzyFAM{~hV9%ysN3e_rC(`eT7Jrr;Sr4_cpD)K@$| zEY)Vv!X6fQ%t>`{c_sh+4pm6DvO;#YyAv_cl9sUAIm`BS3sr7o_4$2tg*RQ;9`5^` zj`U!Tufs!F55aaX9=9AuIPPq`G{^>+kCY6TJLV^`A~(#zB!kPxGSXWy^kKM zdyOg4^dH{-s59+_1vf;-w@k)+cbIf%`R&M-k=R3RRTwdIn44-pP zQ`6yz`;Oq7)?r=wNgw9C8a?xCQ0HyaokORcPVbgfW2yt$-?=AKn!PocYRZ2#wnj0l zgIk)*;4hofbQer1iVp<9GZeXUb*BC0vYFwN>T~*6;j+V?Lbd;WILLTwVto93g3EkKSr9{p;GsSLf2yzeI=H$D`C#8cLlQRw3ili5`RR$arx~oW;Ljx z;9jB@Eg6GUp9>7Q&6s8FBN=_Rtt${8@taC5iK45+DV=R4A^LUB^-DeA13B3U!OlCf zQ(K2krWjUksIEgzEv32f6;Dtdd~_*m3#EuG1)}($l`6L^#W+D;Z|2)Srca=IYk!LT zc#5vd67V~eQV=3tl#&14$uZPC4a&6t`D3W;l`Hno1CRxZAN%_$i-(6#a#5Kk12WCy z=e+&?dkF|+o$j(R^9xC+r=LmvrB!kPp~IcxhoNk$BvRPrZR-K{^-vc{*>YX}|6H}7 zVl7Z!XpHZScXLAxbv<;N-te3^<`bx}%v*&7+&iq3Wr^j^t~63@SsksSJjgQ%%ImKE zYni=_y0=~}JWgq@bZo`~zUune(@0C&gRj!onyZ%HS_xi0AU_vyFu~VD$2r3lkqy|- zCZ{entJUqp1BBI(KiJpL!OhmtJh2bF(OiFDa)^KK*=d53#41EK16?>kvwk^9I{eZ~ zpvBOIo%AeOmepOk+hxYp)mMKTmyTYM$E0q2J}I#PyJGNRe5VuPLCQ3m$6IK=I6bA( zp7uB$y}Z1=*R?jLNpbSTmeeWIFUE|Hw3mqwQZ`329=_Wzr3jX?x2(l}snX0voh!~j ztLNd{@?iK(wE6@g(s2mot&O7{9`SllS?fehAxgu}`yt^|F6{GeKB_|1SHIRw-C2@VfCiOf1J&EfHE)9GAkL_7~t|Ds%$0^K}Ib0%Y0u4N8n=QrM`x@sN)v0X} zp6RSNs=qHk^IemzTHLOIL~3Dq=W|)+4_0C7W=Y-^JLmr6T=m<;M}I$NV%iq4opns% zuv^JD=oqR&X^$2@ETf!!J8sVEpSOX8p&djX1nfIFjBzggd2sVz!%Ef?`RLfmgPiMD zFpe;U^_HDbDSCw5=O8pO0S9rP>{sfaJ;9;tmsU2e+pZW%$o7m`CxdZv3-ItmjD-I* zkX;p;U#|WY$3ooSL)78qKOr=?bWEy@v5U?%ktRPYvgn0SL(>gx1SLkn^o>f ztvnnFH5uqe@0a%;<|IHK3gL)d=>dhKv+^sL;+0AZ$BEK;*wZ-P$(vh^z|l5PQcj6I zAbSiFZL0V7L|u%$>qTWTpVy~O62(DMw_k~9_g?4WuUr<|MBC-Y4|t#Lxu0gSoFuolv|HXD{0&B! zbTs=bfe_?n_u;*HPtwA@ws%AchNYu>d%9|fnT^*tEUFj#gP)fg=Q~&5zHJmF{k=g{ zw)Cpb52%gf!T3RA*aW0u#x(HfI7_HWF5D>ALjgk6ko`YT{ z1jr7d@>hq4@)(1N)r84aA)EWNCmuVbnQ>&Ml%vUYHUmU13uogn+eFDFR$h4|;vopl zGS_`#{K#Af_N94AsRpOB(LF`dU}%G7)^S}$(mB0N;wF9GAX#&1cw%(H7Me%y=hxgg9z_kkNTc?H zvdTM_j`wH85wnfVX*P#`bQPJJ<4c_acY;QRS!r@hKlPh8k6-_{&|mrpxHb=}=ndXe z)Q>1!91s8NJ8!Kryt351KIH9sCci0&X(jqV52piv#!yNeu2w{}sGlvUdJX#ErThMC z9dpXDOiEFA_2>xnjF+=f)Ei%ZwR6IZo_<~paYkh9I&cn^5G_uhE)@0~6b_h!nK}C) z2yrq)5FdJSv*L`V=^NXlBmL&V$X_{z0{6ruW$Ma*2MY3% z^L|F`7Vc2sx7boTa@r;bhxS}}e_ho=)-A}tD0DT$(-E}Bu(Fc&@2yxkyG|aItDcGc z&*u-?uA1gkdGXfHqN^(g^hf^A1%S$xQTk7>jnWaIr>n0{)8@z$l`~_qJVbeK*B;hC zT^-n9COUc_oRma9NTPODeu+wuW04z9cU($&F}@;2kYfXz-OB$iX!hmK2yo|w)cH&>sOhLbNG@}?ZmoNbZL z_v`re_$2#er)lp`fu_=l?X&W~mS4|g;Ho)v8vg6%nk7H7mIZpM6i#Wd&_|n4!#PGS zPO>KBfU<$xMCCmjQD5sGRhmETywhP!Y|}M ztu5Ck-|*;fmp_dRRdD^A*jAU(3#G63Pf<+b!DBo56^)Px4{m>BFemoEBe|?+ zUS7ta4%XfbsbWQ z%Kvc*PsiYV83<+yNC71zg5w|mnJIzkW}=(IN&a~?HNm3Oc>M-^Bi{FE|8mln*Oqux zt9oMoD(A?d`|3b13*N`IbfEY0RPgBC*k0u~Q8I_!oO={GWqwT$n&glsVNptr z8LGwg;l3ZzR7@ZeoCe96{Mr=4nU z`@XcBQ8QqCZ#4W<0i5E9F|*{b4Nu^^w32`GR!eI776J)RnPQOzybAyhFcT(OmRQXd zkf_(B*9I5Y98x$QO6#}=OZyM4NMK>eT85sL29D(kSR!)=?9aY=-RQ&;!RO*WjCX$p zfRW`r?9iMVu~VuvX?Y)1&Dq@uko(YU>k0KoN1BYJl=SqK-fAQQl-CQgd+%hi6C{gyTd zTBEPimRW~<3J-L#bc9tq^r_rQH{I z=8~-OM9V%kEnG1rqVe01cN4Ab)qOt^V}yCBcPdd0+OY2|#35e{&3w9Q^H@WpsO3*4 zb0mLl(8Na5!pTf2!(dONs7b6z^btG8YjN(S$+dA6Ly_dfBLPCZ3oLXTT|Ytn#zVBQ zG);V9cz?*HXClw-cyp$Wg@`~3h{bwW5}JmH4Fm4TI1-H#E7&V4#rusW^d!eM`p6jb z=JXg#1gK9*hVD0^Bb7$Sz7L}qOL}gU^ce&#!@&mEPATWmUuA%xH^v(AKvG3i`2b{a>}YOk6zJJ>f1jJm88KgS zWBh{o4`=aYv~k7M>LXWLL$awc<5}X)`L4(|r9|dk;#UAy#Tmbnu7EygNs4Z zky^MGhOC|QR%ObY21xau5WU7JgHgKGGXfj?K5NFAO^_l606oem;mPPr#8mYS~>u3mg4dVxf!vsg0OJSO}xzMz2620hKR&SWHZPS6wt5)}3qb~zQy`s*)Dq)sp(IU=i=|2DcQ5C6)Y z`}-vTNuJODr)LY^I!pI&X!W1diZWgQhll*qMHFOI4(*dRW;=>w{b774TEcKmK*RVU zrR;9tRzlwkB^c(=>uD7J(=0A8U}PKR*iKIGCpF zJ!vgbk8`SmsjqG^qSr%e2vJITc(6A~2tXqw>od^BVPRp_FaF*pGrUAWli1PRGVY>` zs)|a}#`R>PN4+GOn4D#o8hnR{;P}n)4z^Z{W724B>0br7<@Hgehf|e(GT0GOV<+=c zJZLp>6J&F;M1rb*z`%^%*wQ$DuRE-~)cO2Abn??&y!B8Xo~2J_zlgio1WHRw%bV15 z2XtsbU{4pLLH*KQktw{N1%Al?DK1hQ7w!p1Uj7?x)@xm)Ji0+aW8Bi*vQ+bEX`=b0 z36=oZL!7Kpp`t1gTQVUHMEUZ_!K zz>#Cy3JK7|<>QqD&ExDLs6N)fe>;;yqO@rz5$xk67PzV2M=BamXu8)Wb49;#uQSc= zogAsR7;ShR(PkA3eFF-ka6*TAcL+wRkFPc;a{W5^nRb|9T#O%wg65(*89toRh}5zXK*O`5C?j1~}M=J-rb?%_fWxlKMtY zIoL&UbR4iVC0m;>)U$Qi6-o6egu$1Rx8~l;>x-fM3LnIK$~yVuHR{hUdfFuZY^E4U zxR8Hgkz;6;d(upGRm6l5U!2ABLlqX?4ULz)mr)KUmsHKIy&U7nQ~qJiw4M6gwUYj? z*RU<$lzc|I1QjlZ@6-jb$tvR|9w^5^ucmPL$>`m|4n`lK@xGXOX}>i5ej}-3oI%_Y zS&6>TLh>p_lg(356lV<*sBg(b&mYV$x5nnc%K5&ECaM~(4vD>&4h>U01$bUEw9W>~ zK`{H1cnAb{@J9@^bibw=<42`+Akyzp+cP#RiGKJ*Wp>O{aS@e$9~AxbwJ$tGp4O`J zCv7``dJM`8ty{U6R|?luVqR(8dgUYK5{3p<3?x}@)l=!KxiQ?o#;ctSYn&4b95@5g z7$T*z`$c18x0@=ZgH`gzKMAtsu_4LF-NHO3ak!{YpFSlo%R(N@mRqmbBJG|bHK}hd zAwKDGbl;XYjWA}GqE{3$t6PQzRG7G5=zy=U!@ zry+%Hya)^^C}a{(uelHU`v$ipgZ92mXJ|eNSjc2HlWCEfF)9iy%D;DM>P!R4N5qy{ zEs^0qs<@XmrR2Bn+_N{36<~-hfk74)7qvxF1^UfYNmsDxL*o=H17h!sg_zkNW?Y2) zW-_GZSM2yjKNaky+PvQkKC(HE2=89Z(bEdcSgi*!#!F0u(@qA?!UgA**)|( zZSZ=$$_vr8c7Bk;?;x=yf2E==r;N1JiNKwsN-Vt1}d+s=Xf&0be)d&;`%h-ZB8TxrcDL(5XPkfxj&1(*ebPxoU}AeunI$y19^q>at;a z{p`QLadIEZQ4{VLP6fVvkfD;GC3Cp_BL;feno=o{oYMra!4q6**Y~-uju|r4960Hj z6Cth1rpuFllZQu5KQ&(?5r(Z$Li-_Q_$|;y6f}yU`koitbIX-8@gf8|oo+jFW@YmD z$2Y+d%pBitWc*mReF# zUPMAdGf6Zj9({On4*Vgns~h*48WJZi@bCN6O9f7>O@j9WVMsygq*^(soY_SX$Z~HpAX|dKF)b zhZA;nlKkwknh+naL%p_mr+&)sA)^Fp&Rk@EFQER}T{+BN+Dh`Lf61--NT9py{2ei9 z?1hg7_DGAJ?(1T|r& zPmxK!%@4f4BMgc&nzAR*C1VW7*qWl~hreXc#2iPYA@Ns!Gy`&S-2h{WbB_y;2**$R zrtpu}F~_oLT=Yjzoxwzj-p3m?&0xyQFF`JzGXs?JS6WFUIz{NtG4gy`*?q8q*dIp9 zX-+rNk5U^z#h+_iYfjfIL&L9`{lHmiNwMxy^1u74ZF1E+8!hk-Qa!9TZNjljSoQYoDIxobtVKT27GozP!Vwg1L_V-0Rk7)oGuW z0sxi3F5NzMPLgr=+UOZMS<0QN@9=q3vIKXh!a&#r`qbpLRq2$guZ59^ozu76XCHqL zd`Mm^PS+8+r4LznXcf>P6|k>R{cirjlH1G+ifBG%HJ9N=ZbpQ(SIKT^G5eR{}fjwER7KRSwE8|v|~uQj7_$>?`O&!^||K3yVm19c7w(J zmg6mG^@^9>wrdcYtWAnbAy9tAd+&BAnoN%RpwuY{zi{!l=VS4@`3nbeIMadW%X{ss zysjJYeez?!?o-Dc$g$kc@vVS^2IDFh3(&LA+vA&#HSIGLI$uh_W#`$CHSHd!Ny(*+ z;NXhFj&%i+|9tHG_Oa`wPG1ruV^&Ey?#I)XBNj1uDUG%_n}@5iG1)_J9CxHgwM%z= zA%;Ww+rfYS*lK8KOoK%Mp$8-hrUwTfuU9?RGMV)G;SOn5=GY;FuuHx_W!6e&-&>Af zcyHWiFZ@=^mHo)JuTSLgI_|jJn_Ur!sr_kZVsc{#^*xHC@Sz~de{HHf#$vfEFb^iz z`9f)ay4fQ45@|IK@=@mTyhZ&!h19|9%i>WH7R;ka(26!o=k1=^-8i%+nc5#5SQ)~i zqFgCYoR+?jdP`xBnn>2S3;Psiv_UQDiF)x>J+r7&b`#eBRd_)8#r=B4(4wE&w=w|Q zAY5izIr6B{2APHR8oNvvtga zu{X!0G#Bm4wQGBQHKn`r5z-?k%Sc0sR)YmGk%Kp5y;9iDe)IWunL4iRG=+M~xh{S~ z+oKOdc1%7U@*- zo%UG#<-3tfKtSKXUphX(zvwxNsN3wCM1RZj#kchgkJSXQEqbtko*bD5oZc;`A)sL| zm|!a(AEpc~l_t?L^o8XlVaFUOXVNd-gQOBlfWZ(bU98JEe0;ZunfO2Ex&4N?!=o|= zQ(y?_R^qAH`n}u$+0oTvi|O7oT}#exZO36-%pR$x3!Mzd<%SwGXXdZr-Uf6z(wz@+ zJp}Ebj}~7fGc)OuA3r%q3OA(-I;P(ZSTE(b94Rt-&wUQxNH;jtXWxeT$THw8-N}2D zqA7zkuu`HO@t#{S=^opnm4x+m=6M0VwZYgRMxjl95Dj^T{X1cpMowWC4NbC^(+)YSH;6|APF^|WZ)<&N@1s9<5^M2eo zSFD<^0`7D9{D!sX!jyK@E8!AB^HW`(_vi}Rb0#x=)}{mrzG90~X=t+aOu~i7Ic*;h zXu0{$5J(Yjyzb)X_Rg{EOR@Lv??8+q0beI!{9>fiHC4JL$JSc+IhLb0g-i201cHM` z{nrAdNI^T<$t_(cG=bZJh-6H)>IRh)(wR9^CC|m;NVodF@6PdvTXCA~-mf zo#|tTY)C2T3WRMpw`N_zQtK7Ltd0cO9ZSkPcu8K4mi>1Oac#^9z;g*&Gr)t6t)|n2 z*L0EL<0F(ujGphT76-FguIj%nR}Mf@R6yI>+3oBbb=y-t9u)7Gsm1`BAVG0)d;2A_ zmm`yxeGXOIgl9i$)G58eTFI_=b3R$iyD#OUJ%1}PDe2PL)4D>Mx9GbBmud&bo_a$I zHEiKC3Q*xv^t{D@ZB*x$BeBWGdd($HUCFBpLKE*qrq#>HTmii;b%G;h-0nqc z-O7^CkNF5~M9|vp&-Qo|GPAQo2-2#8BpJj`k)JFrq>w}7b3s8@SyMob#Cy2Qitwt0 z=Yj42h9<@9Atfd5*)tU3O_8jJ=C`bAr&F5)$^qZfV}v};7SIwpw%@SwaCh2L6WW3F z4v1;_Sw}^qDM8a`tj1fP&asEskflgz5^fU6LKREyO7run%h!IS#`FDzj`MU2(>zBB zC$240)TMd**x>>eLh|jCLT}_twT}@C+ctiw15J7VUNG-cbh2kDvn4w^`k! z*!vtV_?lhTmyH*8h8fq+2tzMFVaC|SlE|4UATEe!l~fRpSIE3Iz_7Zo8mG)10hqV)qGe`V}ibbQ-k7uM!N0 zenv6yR#4Pf=CQQ4x&heMQx4$Z8Bnscld>GB@}_3E5?9p$z;7j*p)m*FM%zRFs@Zb6 z=#r@%eP$e8dU4lTN8W)d<1Y z@$p)y`lyasH4H`_n|mAXf)_#=nYIpYkv{YoZvXCpynlN0(QNP=rObi^%9rEp&&Mxg z%ZO!GD+5A;g1>J4094;e2jFVgN}sMN%ZSIwb7wIjBDRqkqHn)OyG;y~JXbFvckM8P zx@&4i6$;bH!D&=xxt_P*_%=b2CAhwMmdm8e(D3Ss(x-sjhmgW11&yTIzg69=0F}fL zIT%a;QieW*1jVJ*$ohr`xJ;k7hstp6RHL1bi}RPxSusE|q|W(poRv6vlf3y5hF+|1 z={%n&-MrdT%OslmClnj{Z~rD<$BKSe_V#TfgyMDDjJ}bFX}@xsWwo8btliVnKOnNx z%>HKI@7B;iO+j#-#<2ptMcm$&7Ol~%`M%yvN_`Mp0J}*^QT& z)0p+Q$Bk)=>CNfU<++3fEpsHIZA|Dgvf)~$@-;);6sSN2-f=5QRA}c#vY2(>&xbg@ zG`RZoaT<}o<1;npv}J0!a<`)Hx3LejHy4v4rPqc~%-Q#LAkCf97U`b*3dxsKO@<`i zPT9Hqc&_8MB%1hArzUD@ydBM*qpjUA6??z%z?~PRO(f%RgZ%-Tb{V180 zRxuZg42iW&+Wj(MxEx)Y-oPs>@X=lRgM-&-sjmg{Jd6wv@GhbJbk{rxKpZ9)*qZRn zhIm0ifqTVo7WsNnV@vHt5_{7}IpRCNAu&Z)?1)eA@{%1pjWr?or>Hl}UxRF5<=^1n z^nzGe+H3eeo5YrT@%(8{i3vBT$ThRK0qw{#G{abYVF(!JxQmf>6QR|OZaCz9RyecR zbru7|StF3tX1Vh04&&h$md`q#B``{X2pkj&-OR`}hIBtolk`QhquqYEw}!QS;CNTq z0fG1hQfoE{tjoqWw^&n7l+R!a3%`SoyuX3xMNznUrl8y4WNLtSIMfS}ROfR#FP8z^ zSJCB^x6<*~nMYX>hPWcIB}MXbx9nFl#O*~&@7>?26UoNd@1@k*%i#3LyTs}Z_T zRscdL>YAerj@(QBAk77Ls2Zh$MpiFWYO;0aVJ8Bz8i>Xfwah@-jSWRB;(z6=*sbh+ ziRKwrm>5{=pj7_2cN+Qn>Bi0I&gX!NFGcC@l@Eml1w$LJuDsE(dq%a~ApSyO|IKXe zq)GO&+Y&$pO>~=B!m@gOb8GP*_WOi;d*{xaa*lAlR0M;M#eZ)%ZI^tbq${{!mTw(9 zMq!nt>xigj5S`*(h?I_DoGhQ=(Bdf%4Gq1(9tUd+$fi6Br>4@86cZJFa6c&&tOl*= zlkr)Ol!lzxQzYO4q^2^C93_~2n-EF?>mJ|0_)?Pmm;>+B{<*kA?Nhn3FhN`o=e)A< z8m(@#Qs?uB_HDi$-3go*PYbO0s<22r=Pl!>j7oK$cA_1Uip zveWH1j_VitJj2VCSIAjY*;5W^O6*Nv^+KiCL-7m4_u~dx9+>M@tsk_?4`-s4Ap<=z*n#mHy^)gKvpDo!o~}qTdSi*pKYP5b*UgZ~GPYWRl zAO3C*klR9JqbO(1$HqQ{k48vq*kodE&h5ijabUm~$&cwT{?NR8>gVWJ;)yUq8s6 zna`S!q7rJtUJ0M2+WqC^_$6%Xp)YlS2m3-J;F#hD9yJJpI6DdDzQfswtxX;-70P6$ z*D#)%jHR&~PhvN}zgs3aiY;r;eH~Y|>M5Sd(|RxVRMhMrpSH2qdl6#HKE9{XInEc4 z%gMWzybnc1s;VkLDUmP&qmp}m!4-suOpD4p&gHO=vmYKk z+!6*k2Mi0QrH4n88+X>DR)1pfvck0aAB9jv{;xBkANPXW+m(hJQ4XjWWQLUta7Xc;tlT@;UG>g>U|zzHEf!hMc|!r z+CN^;-22gd9`OCh_PH41sAm1U+hHgq?$!+@PvV!|$p=n~$gi_qza^lLZpeIF2OgRT z-c5*J7-CuPNiD4@Pm!B(`fLWp*$ZdRb+iwHQ2mBT(PXACca~dgaqZU#Jr`;kox?Z4 zb?iT_f3gVLgaWjdZ_4=j`Mt2V-s_XBmP`;>NERmpYKm|vs>4mWf#aNm>7;EmJH5D8 zg!E5hE%V9Fz+=;u_N8980=k1fWkdoYUSL#b8rga2nMrL3lGFydO+Mi^qH>a85$WW=#%#1%r@_1mrP%M zNZUB_yLKh!X~to6>H0i2eMuzc$#pgw@LOox^teG;Pw11+1Pb-M|LB`R%}2=$q14;$ zWd|CMu&)x@Q~C{Z!_lib1yF@jH=(a^YXhu=?*V^<8|}A5pRb{#L6)(K<*(Uk*nW3h z2s|yo3g=}OUG1R~08K&@1xF))|B#5n)s>Yroy3{T$~(@MvLKlF%tysQpp{z8Y2wy8 zExlOz*;?84QnL-&0t)K0eoq=^a1t6f<-|qp(ta^L4h)b!@tD&ojv}Wd!69DqAOLY^ zBiP%Plcr!|MfjO~MI^b}d++){c@)KQQ#xM9F$p*V5@Z2idd7JomgE3p_euEW6)C%J z{NWF*sa$!eBB`3X)&!^YhaJgrIpJ-2E`TF(8a#mK&yOi`)g?HhW1G{uPnYU$2oMMj z)ALUT_f~#ZZmjaPo5<`R`oBP^QxFJsCSCQBB_;e8%FB#ChmsEym6Z!C-n{ad8X%pS zn)K6ycbCLIe0Tpk=y%*hu63mk7{!E74t<3z0wFc$26sUir~fl+=GHX**NvoYsIY$k zBHVrQPRFjnl{dzqNH z_6PX+$dA5?BlG~R`ZlhLx(wZD+-lT|5LfY+i_81G9-gsHV=RWar@4dM zk4;uXT7Ri-nb*MPe~39?i<#>tO7J>PCfuy+qtNR4m*w_3-NH^$tRnn6CMHh6TTcfO z%m*%)T}DxtJ|{ePz8e{+3jgU5A??uvb8yg3lSS+}hp9OVSf$uLUrA`BHN4A&NLB)> z_Fzq4mfeTXJ4v&=cSeHI*Lzt{*(@zb0qrC>Y;b(w5#gHs)&9~4ZCqAyQf|0`i1~Tw zrEH0aKj_P?--5oY-*n0X!p>r2m z&Kx%N>INOVoI6XWMB@KAKz_1I+!P!~;8P&*X2H(0*E5$cA##A|HwS3viuU8I;nRLO z3qmxHC9lV+i-1VY%58u+-X;;uBI$xca{IM zc)c;Glz$P;Oi+;SorbZOB;ad^Mm-~K8ip`}FfWu*y{E@KzSvtQco|>2IZu%zEfHt_Xmfby}2HTJ4-C9`U@9%!5bZreATH>J9)+|Cxnus+a&jF(%n z=#;nqD->@{Ot->CoSviJDGRmb^=vaila@aTCiCcBI786{bjx`=3&AgI>FFx@K32_XYTuT^Sjc{UYRI@@%BiY_l!LJc;`Cf^ovMVo8O7& z&AY!nGJ0xV9)B>=G)@$Mgqyn;@jIRs^AtZ0r@no8cX-kIfsZ3vFxbs58>jBRRhd7s$e7alq~#?iTfo z2|x2%j`C@I{`2AAaC7F>N6aEU=35F%J!)O?4VF7ApEVH9-90Su3kk%$rilVK0imZ` zsU{kTry_p_5qGNlo^*`0vUsy+_oIGPOUIV8LZXx}j#Gtnz?xH_`hdxNov9S?$9`Zq zHhCK`>7sV^#in0>+O4@y(ta!Eb7{1H1=^&Al8ayh4k)IG?Qm-&>nQt(^wE^hAd@co z2Ni907Ml?wImbnzxHo&1lp+h#P>em6{L zwR?*InwGLq;&(GKyzc1O7#;mx1xLF3nKYaH8SkE`#04z4{$dS1HAS1u@5U|uPkc;N zR`VO2uBLk?Klz8pCFms|OP`K3n5ku;3EgOR`qkK;>S}28h7;Wf&5;H^_~JK3J3{;t zPb9V&DmS4piN0H;)IO1z$npbmzW!!bnm+5l$K{@eb}e6eXZ%x*PbxAvqsA%oSeI@B zU96=r-wm+bieSX}t@GL%0iJM+>Qe&MMmJz>Hn05MhZe~$6`s;Ezd*XIPkEej@gn^* zq|-AbZy7o_^vCvNaW`Im$$LUOV+LICu7S9T6`J)=Q7V+R+NaScyf=hu&iQD?;xC3{=c|-3$UoS?vHm61r-F77E}a8q`OU! z?rxASVI+rPP%K&nq`MnLVrWFVrE?HuXaJuVb9cMyhOUVYCdPT6eKjQNf3@9K8$1y=@?IJK|G%c?ZW1s+i3Fz4(BM*Wv|ct(?1716BsFsQ0Q{f zvHqV50gFOYi@c_(2v)~XG?kcx$;Jp*)8)%aJlgU%UR27m$%Z3Pv!?J}a zObvkrEnMV*x=$NGlS>J*lmGJw3>{YS=ZIk`tJlf3-7YHl@q$Be^VTaBUP~BvY zzzKkHrn$GD-s337%vvt%_UeWX-V-+;^^xqCRVUfT`T+HDUyemRcv7RC&r}0VO=D&J z_R+##mq55{t&-B z@OJQ;@XcCOExDY={|A@(f3xkrH+qHs`KJIQ1==)^%A_ghq-%sZ9|V9w#aBb#@&XmQ zL^vqyfJr@a?(ZDmPJ>ptHTg>^)~4LwJtGal6e-&k%?D3Jn4ST`2j*{E>D^`jly~2l zyVw4ln>hNb4ytb-l;|0Ke!SQ4X;}$LpqX`_B}?OaZx#RR_W=e4iK23QJ$UVZo+v4} z$h$`|X^^o=EX6O^D>$tDXwED(Sze;nDX-ydiErtVrdH?RE7ta3C7#_e6cE5IP(U7- zRI3u^!fkuMk_GYR%A$5}{-ve4PjJiS{M-n`^~}x9fq1F=n9*8#Eh5riyWl$Hm~-fP zi~?Ha^Z2+vq&=k#04IJUxoVTut~1{^p4vTt_a-r7dmvgl`(6wu7*)v~Fz8WMbj9=j1dF zEDs1X)Oi7?6uu|kR5F3W|6Pq(1&)r_uZwTHV!nur3~IEmRBZJTB!Z(;MYpbu>O(xI zRR&ezreDE$J=-@|AOHh&n%ux(6#psbA_jJQzw$o0^BDpGH{AtCmiowh%lF6b>VcI1 z?8wMcul=8EGa*CFEW!!Yp!f?4cm9jdl;MH`b*pECA5~G~_Y~i&K>P+X97eOMxt|$z zPgeemtI_STeuB;Sm5-zwU!1k;t9p#GJ{1+t)5{bza0%0Pm{kW!IPoxIBIxG}k>C>O z>X==$v~fE)Ws=1#^S^KtJBZOnsUDR>t<*Rc$9I`6ZK6zGzNyH&+UagB1*Hk9q3ifd zK-ORe8UK6qa%UM5CUdV+dKbM`6UpAPIM~QU)hzGVKw4tG=n^alPmX>ZQay`3T_{Wu zf@s3Xkgoa{+2WQvWZ!TOsi($vO8>EdF7xY&|ti-25~jU`j|O>YzIf+G>A7 z(6IpubV561MwLs+lF-Yb1`2+iKf65_=2W z#SY5BB_UYseomYjcHiTKGrS40(&kKMb3~jy#;yE!^HA%!<=R;9z4^~Ob3Sq62SILM z6v`8CB0+9j+Fs&CcV$I0RPe7BjBHBG#IKIE6LHF1+<-+r5(!f8?6eK>!2B|qv1QkJ z2GX{mseA-(9!3iW{QNJK*1W|i;$XcS66^?R`T6syQm^ohCsd4j_deZcYE@5>$`L$@ zX{+T*^aHG6sbD&pX1~Hwk7cZ5RFAQq-Z{wO6gsHnT9`<;UoUS>{t8vlv|Cyrz5pay zIT_YwE_ImlVEa2v&+$Ycy*I!)nhr-kEFJz3fpqChaWk5VH!=Tr1F{_QTP&dX;FT3z z(t-59zo~=7ka}WBs??A@ z7*^c=To$hAarD>r>7CEX7i5MVu3dchK=k#n?1)%7AJEvPDbmc zuCWD?KC?I^o;6EdKIPzg@AFL;gKs}4MJw|8X>Cic3}($lz=A58y5p%Jpiz9J5L$a- zfyB%`?CyW*(pNPe&m5sZ1{o}Ec5+?_ia>@6){tmGUHHsRl6|5RL#tmB19L;5WLxmC zYvHmv+|mv+y~CY zL`uuZgo9Kc080RqXoR>!%4UTSw*ID2oqXCjlb%Knn_dRlDJv2dSa>Amw0j}&pt0R| z^PyW1M3d8MEid-Y6?Z-WYuaOQcK{p+sdQ?JRAfUcHU)sUIVb)8XokMfOJ+hV>e`Ah z2-U3}rl~%(NxJ6C=f>A5JXT(4;mhw|T~ts|6ngIW`-fdFW+YF;=H<(mzv7EVlfseS zPY8EX^!IPld{8^q6*SRebTkn`hvw=v3f2H{lp+ckUT}>{36?ddn_Lk||I5q>?f$6n zv169>3}V9QGe$OlUxg!eIkRx@+N`ktpFVL4`>R$o<)A??@^ha=(d#q){j2@3n>TOD z4ae78w_n`HVoBgA11qb-t;?VQTUIhr1%Qp``AiWJJzfBOkK3$Nnvs>2mD}|pcwE;c z0jKY%=ofIu9$V9*5mPB=F!0k7=;z(k4$MmlmqPdYPRu63&$08_xDOo< zHl#|YQN456n7;5XR~F1M3v%H{=GfAbhDvc#ZxBRbx)Pt!vFdT zc6Q2r_WGvcwOyiK_6&=M-?Ugd%f=*LR+y~TC0J~o8+TDHOXLNSQVeYs43Rvr&eM z*&C6aqcNW~jbLNZ?f7abkgtAL2N|vk3lcgSpPc*%AUD8?V;cdybS=T?lQ#SM3yuUj zvX*~oGV5)3xkq!&bvh|Oj{y)kbn{o@qfNu^QhBx*#z%iTlD?9E02(*1({=R)MC!wh zgR(YIPlwKelqxxYRrj#N^^64>-J>%01l2;5)A)pgAk(ba;p#^K87#Q=)0-Iv@a(5; zSAa!(YmPb!M;?WHE(hVC-3FPLTvMsY2&4|!aviSRtOof_uTrXcUTSuC%#w^gFebh$ zv6q8#AipN}*=_qOnSq)3nihc^0mgVh2(A7MrSp#bblh$Ocym1MljQM9u&=x(c3>r~ zY@#I9$Hjk(*l2J>px#DfU6&6p?GPkCoe~4;By3OY{^MeERRBk>iL_!f1GBUb1$P*Z z&Yt&o?Ok&x3o25Dwfq@R3r5;KYnd%~*l(Dj4x=X5RbZJ67iH$??08+0J0zn6E~zJ# z^b3p6S)hbH!Bi#%Q0ncs?;Gv3P4I}~{C(|LEob`iP89j7!_7w<2k#^(ADU0R{fDJ; zKG1m3!{c*&Cwj)Oq1I^X8y83fGes0K?t=pIXftVS0n3Prp56@rVuKhC$AyPJLjCXTdz5P+@x z!zRDaJ04pacZt~<;87-Y0lDh0GtH=|4FmZ{u@>FsTy{1|0PY|cQxKO0%ZdWC0hdEU zE_`If1Gu~HS=8K&?@;?md%v8^v}~bY2~1Ho@TF$;Sd0F}zI_57h2LXG#IkT0-}+8WI$(8N1Z~Zb~f-8)9JR2m41O!@EAUP(nHuHOP<3f{{v7NU=c#K4GQN{IeeQ7hmlU)ot}!Urzo z%3hJ`gpkmK?G1@wP&682A<>g6aeQM8n@#VTM#l$Q$97}TM*y%_cdIBY$G6@ETZeik zsTx6cJ*%a1qfF|@_qfS2)yp5+tWMenW}r`D|A7gg3MKpm70CqkZ&E1%_-zNmV^Oby zj@f9cv576}n7I z7ZVq^v9>-lC|?{uob1qd?i*Tm7?;esn+Q(m(>dAiGJS z!xZv7M_WJ`-LsK68p!`Ic8oUO!H)>4xJ}!ICJ5qQ=hcZM!U2|?8wji=2|4zu1ViMT z*}mLOV1mA$ZFwQUpxfygAvj?dL5_sK>)FcAxhAa^Z!-T!>XsU#U z(hC5-FYim&e(-Le_iG6Qv~;RUnebR_YGsX8f%?Rv8GpgsRe<&+%y7=G{Y6~>@pn4Y zVRIn%n&yH-78dXGLRu=J3cuk71MOIT`%WM7*9u+w`%>Z{g z)Wdx$e`6)_ybzDJETW43aL*OpslyD}7I`2PKC#rI@KHKXN|eTw#)0hnl#I^3>p!p? z6CQ_ods;VLbXO9TMVns~024*;m>HQ|@UZmC`!|h{QKf>4itlzD0g_j^7~9jpA~LE| z0L;nxn@0CW;>$fV0x0G{V!HW-j-G$XCeBYx#Mw-fUtco+7jS_<>?tT*(=gXjtU}uoj6nv*g#U!c3}3*N{)*cOV8M=^G?nYw@kwRxtU~mjWxZladMXlc-V( zSyoW%10*X@-xLal9j>;?0V&Spci45{8|BJj#K=*)*h>#>-g_uRGCm24r*YE^35UMzuB9N zced<{)$Z|%e1p>wT$U1L7h8Y>&QW$rmKk<^a#AN=nWZ_U)V*bTH>nAFCV%x93RyRO zYtZTbp9s@~2`_mulzYg>wuR`cR3KTaJSF9G`pqJ%S)Q5e+&3)eNa{6e7`{DJKZVLE zZY7cShF60Q{;6P?0@=cD>!q)$Bc3UF)>oEV_~irH0plxDHX;6WX9!Af#zr~LZa$LC zLRtOB@Byce>f5Wa*AwmU&>DDY?pDM1tOXB~@6G_}C!)#jarzjQg zO;y?t&ldl@+>W`Wo?laIs1^e`L?v~{8e%N}<^A2B6AEoPOQ@#;%5vKlnlgP1; z9+nn5(Nd?6Jv?^ilF z=>X~wZ@NqaDXCO=Nv0KUuKdSzs5^l-@nBWBV?i!-Ox$b%!jWZ%`7O}VQQhNhI~rrK zeejIB57shTD*Hl)BP9%YhLDAxSRTl_-nG1uHxxlvyCm2dps_+LOwd8EQ5!A$H2+|} zJ512LHzTUBOu@J}bt-h?MPxc}!jXgWEKfIzT|O=UBzjM&iMxXA#^KdBeo^1ey5ddr z^xlDNAb3wRUL%}N$5Ysck9*FOsc%&P@U(MbaNeR&5dABzPWQg3-`-c*G6iwxx4wi4 z=Gv4u4t=7JhrQ+Xi@TU~gEO3dE-AxTsnB5g$o?=vVYECQrn1sA!f&cmu3gt{iXZz8 zTp!?QrDX`>NJ@k6CX(Z7iQuf6wEZr3%HNbhUhbxhhByVmmEN{diDD{sW**AH$u(H| z2t>`UWEG$h(~Lm6A}opmZo|}0-)&xmSdPgprBa{%68v{yNx25v6l>`1CQ<0b_jm?On<%HBma9Dy;_Aa&Y2`7 zn9qJp@WU9uUW+o17*<%H!{hNHA+pIqm_r&-sG$sN+UHh>KrHPt)e`^pfK#-O&yjHRS3Ba;aerPodfwmlWdWl? zKXxu9c0XmG-!y##uAudh4IqvHpEy-FCSle;G?XgAfpVc8z(S%ksY$+sZo8@z>lC*p zm98)k(H^Uk6x-d+Td{uOAFu^Z&%}f{(SozSy6oEoZ-okOh4*HT~15XVV8ZM7rVdf zh*~8IW8l8o-ba637bDA}FjrMleN;e#(-qKz1tf5KETAy2T+m>RUA-^&f+`b~l449w z#daK8n#Brc-n=hcc1{bB06Cs}7Crl|2qAPRZQ~WxD%>sIY74A#b@$0tYKkk=6rwY; zDqr3f7T(8FC8R8ikJQvcK3?ue?vt*22_QV^$oKTP8=1b%q@}uGf#OPj8)*8A^gTdE zD{`XB8+0C|rgK&0L7{DEa zS)T&66UHN{V-BFKb-O0nUoeA>Vu4|#(dN@|+-QML=`ZB@3D|lqa=vJ0x^`aY?Z%ee z{i^v`f3qcjjhm%4$G5Vc1Fr`QW0bA)87&IS-{f0S1$iRTgw_xcA9Bo}?up335ZquU zO4Gu(Sef)+Fanw)s$`6EU!GclD7%El2~tev-C;N(;#!JQw`v zX_gi?Pw(St@E1=PNdoW5vGA3JAui>qPjl#aR$aEr!5cG~B_*ysxs3q;w>pf(l&i@D zeKS=PI?Qn$w}Zlqw?^oD>;SHhXN%mVv5#yy}REcAi*cG#JyK+GvH1P4AVA8hFBF{5J8*Tb>CMM%e zWOBsNXO0Hdki(Qj?kqbwo9#VXO0%1XT(eGn=aff2bot(QO3eS$BA@O6uj?=!uMr09 z*3_g9gV@2nRr+?#@zwzRxVvNzm2;0qL8tpKDO4Iy;z7@02^bRT+GM@b`?Ce3Ls{L` z8^`aXDw}(8qF%tf(8pbacA_3)>Rwvo#ZmcHxv|uvk*W>r?bFzPl!<@;k%>M_5&q=o zj$uuvI7U=VtWcVMIN(eIZu5PU@QBZn_7Hoxl|Oshl^4F!(*f#pVmOfg=@*PyD^1?@ z6y(W1A4@8)y!?J-`lyXHU39&ws;V30$2f+CQp6K+_vitJ830JyV--Ot)uJHy%oJHk z4heX9Hy8xuUN|6e$r8LXqMjJ^?NePvg;t96cWD|Ky)3?j1Co?o>C4WTfyHuP@U-mU ziz9uc&-dfq)+;%~;i_`}yE!9k-HMgY^zxE z>>lMm3cDYBVN#02$9=AmbD4@7q?AI`+eh`dgqiZy?kG{RE5Kt=-#$9iI5=x}NaC>% zeNl}J%*QO`E5eC-dv`{+UqI6LtbOhe(9Sm~%^6>TkPugp86=5w>E-2fBo9D(qG&}w zfRw8K(^KLZHijbwz!sg1ZCi24?;UOlUtFaR1F_gjx{JZHdnPmCPSnT{+K5Uc$#W%s zhQrlO>Wki!Bd@3H87f~O9i5${<-wWzT0rQ|0CzX&Bf)_tQeV{$s9SFyR`A!SmWnv#7hC`m2w{y(dw;< z`81wren%3!-bKfJG35im)6(Lv-h4PuRLIq-lfNBJn*)oR5LJU&MVeghblat>{l(dy z;7OL_4$_-5m`-eY(_DeO-?EzpIfM~H__<3oP9@gGdM)tQe8;iyF<`WVV#x%zH*=KRH& zMm=ZU*qrtw!BMmA_%<+;yviMgEU5lpCrdq6hXe2*Exzq_D^QvUJm)xSZw0y41aoULoK`sG;x4BoonL;&syerfW zJGYDx%J3(5?NbYY=HP9%OPWe%Lq?0b#9JLr3XJ@i}MtDyRw6)i&@!gvT z6*b*9bC7wsb-5+ZBCvojvRazP1)L(t&d*j6B0lXgB;6abn^${vntM(6LS6cBDylvH zAV5v+uy`U0v~vKFOyUQUkX95r2GozM;6MTK$LQ<%?p)b7J+&a8v(9{n^t;8=23h01 z_XINCp9o}U_nWtoM;iJEQrPyhje%ow~~^JcS+c}wGplC zSmyl4k>GHo9SEJ-M(1PngaIX}K9w68j@*aD1iHpt!jjG;+~S`zsXHzd7Ye>96K|5M z{6=occ6Yq=$Yx}+V2y8nV+u%c0EYN{*^AMArw-Hf!(ya$hpERimmK@P8#CFO9j09N zz2^*3=D&Ol4C11~W!l4kgvecmB7k{mHn_ z8g9iq5~c6vp?xBXH9ths6Tj-6JlClN#4%8R-YH|h560KgW_0~W`N6Q ztZcpQQDIzF37PDq!s3t_H}Xp&K_9F;Ak`!}!woWb4uQs!n8$lg_|t;H!fG506u~Dqd=c?bUCiT+>efC;LzpzYEeR6ez7NZ;{1k)tYnas`F>b;%BS#E&x5K6CcI* z8`SB^JoWlK{~yuKen56_t^((n+D)Z>)&ccu8X&mwC_;t38vq(2ZAl&!*)voO)3hU_ z=(Wf4kC}b~Et7!QSA~0nr&njv26`_rSE+qOPe)Hwb^vsv z=`oar5$gQE@~p~@k8D7=1j5D#J@F>t?>FCuBj4TYh#G ziGs6G<0@(<2W4Q#Z)i_I7QFPV zHVwjVJ%iIbpP2w#z2Fs`K1pz*d&-k+DIE98eSi@&SAfwDM+G3vS@gqEz_Gx|dRd04 z8tGj0SRds+iXAz$>R6bdXv#>mT|L)KRUB@Z*JfL5m zD#F4EGeZvo_u6Vb?~%t^yY+SwEDAyeKiAlNOD=T7l^~)mO?Q7-*~;-ocjtFYZc5}C zu}A&l;692nGP=k?aX+`2wm~NI(C95O5curVP8?q+8=pwa+kQBGViBeCCM{UgdV<_( zs$lM?)EVQ-QsSv|o&!inDIX1nr3&=FjpL=w58K z)Rf>0Pw7l5?^JMC8P6}0puNZu-;Kk=Z`ymFINR;1k_1jm1y(8ntbjC`W;?q0`z0jk z&UbJ;0Q>`Xzi2E9WCSyBjjV|@HF5;&t^;n_$mlV&YiJJ;_=Z(w<*@IQgrfFq&*{bM zE|b(`*X)T9kYvf?y4LRiL;`WX&h-yyFFES7JV>Nw*x$cyk=ON=z3G~iPV5!%gc!HR zi!JU&t%@Qq-F%G`SSYSaa)0TLVT|g8hDW$@q^K9sI|*ln#cSy#+#0Y4=$8M;e7#B8 z;_HcTQsSa3#3?z8Hsj#Iq-4tp90E0*(f#0y7i8gr4PQF7p|x!L27ROAsiX~rVt`(3 z`F6LdRY?L<&B)~z@l8O;JNKNg3XNT6eGhXG|nb!1gLdEf(p-dAR z+Ca)AKSN0YHNSR64f*guM#45T7Q1x`9#&qV2#}yu?KUds*)mK*B7{{Q|51>263WIM+D(pAdj!57U0PFj&>6NaZ&k3@A`fKi?!>*}mD9LRE@pv5C`a>l@0laFrAL+R^f-x^#rw z84zg#45O;wfs6!{_MtUjy{Hs&8$s(W$B?)_(Bscn6SL%3{yiAn4;H8;orNXMPlR}o3%XCR?EEZh*k-hnndKb;2SI?A) z|2d4aFY?O9XX0S0B`w7eA^o)G3X&v?)CfN8X7^m0}rS5}1ll%1Q2+ zeJPQ|H@mHx_*QPmqAMPzSdS8Zjo@d1a!Y#)Fg%cQE)5h-mr!bbjo88#+4Bkjl`~&Q z3^O&wXXPB1{x>Bbuv>0$a+giPHqz#6{b%z58yF=% z0~CeFOH8;XCMK3nBT9baCIW-NpBBMmIj5I)B}f}EL)^Rf7eP9J*`ltPaRMGa@s|f- z5oWZ+-GZR{`XDvxbh#h3&}}i;RwA!MJ(VMe$&h!9&Orj>zaxuU>llD*4Ftz9X;pf! z9m7DSxAt#!_8MmK%#%ENVwZ z>cB^k&@W9`)%JXo;`z!Z(LFy-o|X6qqT6IgYD_OyLBAKr!Ehpxm>lv$(6S@C@n0zu z5-m%4t}*nPyYJnRc~yO19p-Q{$tn7o>FE~%dGiZq%Q^qi1e3~k{V>#gX0Z!us&pb((EQPbk4PJEL?@FKMJJoLB&RWnqubO zP8kDpUj#CVRn?Dk2jgwy*0ec!)Q7|m3idMezec>PkUS1(f6?ouOy~0EKbw#Htx1Gz z&KvsiS_4!LQ#08!$^e9$X^m$DDo;J-%W3~$-B>fX<`WbxmS?8zx4@6z0)c)As)1&i zkIjCoG$)iS^mr#asT#J6l{<2+0laqIDe>_wt|n2xQEmirU(0gZ4|3l-0yT0Q*G8Fx zoHx{7Hr^lwMM3}E$0TzYRJq}L?z9$FRxsio=q)`!O^ptql@%8Fm@9w5A(8;HU<}M7 ziSe^nieq}SN@IBGe^$QOEx{p^>mw&PpxU*xYEma zfO8PJsPsj^XF$N%*qAfzX7>!LpN>K5(tS4GfQEo0Az-TnBqTm2VVHC;Yidlla0P8_$N8evbo4Kmef~HKHGO4Z1RNpErr!$^C z9X>X~V!++JFcd)(YMqN`_4WH%eY9sCUZ=om_Cpop&n}goV*kxEvfFcs^^>UFW&CJ9 z=zcTcH`j41M9Z&4ApGM^P3J`*%#qB;7~ z52@wEeA*KPIN%K(vxg(wv?s7u;1Aw3VLPGc?nv%^jo7QZA+*dHt)%#(74&2B&TAqQ zJGdTZ0*JKt|L!N&X0j&vK}E?9%yMts@lNk@4_ifi0|@p5|2jP<1Ts)lcpPjR{ao_6 z-EuA&;ddDXC`<0<`o!ENlpn`i;15r;X}ysz6EAByii>^N4Pry(=0M&E@YDScut;#B zcbzJhIF0d$+Aw3pa@Nk1+&z*3`zHxizwUZt(TC;;Wp|mda&(w7FuB+N{^)Qijq`iw znfxNE7FW<`p;gH-H3O-5@=spl^@V=eUP4XrQxOa!)(6fh_&D5S{TTH6Dzbi%#BBT; zgc-l1YD24=%k-MklJ;?W^@_ud?9N0_YXrT|D~86H7El%a;q&yLdPFBcPp+Jwm2oU5 zCy@v5^({A*uL6rG@z;6yN4wIL2-yTU?Qjpm4DM-_?n;9=8+1?m z{HbGi)Bo0OTTZT{*IYDW0NlH5KbZOqT6uN<@b)jD`92&Ziu^eLJ$Jrp6xmxle@}3xSmGWYwj0Q=|iW_%r~_ z19>@U<1YPU<2IAO=P^udFZ=ne%bLyhYsb>*`?xT6571HT@t1FVckKu%0=+SqyMJSW z-v#mw2Q~l$T!*%5ioXA_RCweD8YPlkZy$3<&?4^Y?axLn!^aNj5{)_N)EUG@JYMw!+(2L_+Q@ zij1Vj=CZP1%yD{kZShaWSgve~ADR^sFAJ-ldv=fKJ)>yN_0zhWs+}(-ZZz0+jp?`r zmtG6EJj)E-TZ)0|x#;&7{OFinyWKRw{qIr>f~B4V4UCwfWXto9qll)eorZ7j+5R63 z@XyNs>HS*o^ea6nr(^uMF@O=uCjDuQ&upZ*u^j-Ejp^>fphg@?vK9)ahC1O*epV3# z!ffbn5@wJ}CvvwQT&P^+=@+0LUl7)J-l6R{7-S?Q@+krwq_csuss3eS<9=ckXj3sX zF<~#|5xCrQV-t@p0qi!Z`cAXD@zpF|4fSZ>b#nZxneJU;>4$I^^#WW-np+EF^3P#3 z^y^qsU#NPa4{|`f6?+gUzv3^QH{Xm9igbmb6|-*WVU%T2rkI{W96zG&yvk50APQoE zLlhJ)8|3Zt;a>*>-#&fkE=9+cs0|-4hpTeE@K+6mC!3~eqI@Cp%^tAv(Ps%In?xcn zlm9+JHYr6;C4=bpG=r#av@!ce8(o;Za%0at&1qAV1PF>^v`m<)_CQrC<56EEFb3sz zS=m#I2AlN?oJ-Tw##n~JrNoG~!)5+noq26Qb%p&AUYGN>v^MsqU-|s3IMwFcY;B%+ z_8M2*esm#3gz>1DFYStcl7Dzt!drrRW6_)QAnEc=NP_$3Ok{{vJ!cl^$F%HIg9jR| zsX(`{Iqc5Xy>=A7KuBtk;(Uc2PT!O7Skn{&$Xv&oIjOINFPfp>{JK9Cb>0tlQ$5cF zO17_~f1JL2-U3>!42Yx8EcX{Gl?&ELBs(d0C zb*T2ma3S=1b66K%4TrXBdnrRIdr&Y2FRK%P(fZc=hRrkaNpD!!|cx3Qr{SM z-xbnP_EZ0-#-~|*CM#{1Yer<^^2PU>c4sQnJq1d_@5%$BQ~x|^)SH-u}fFwtyFKeAu1=vxJFH5mT0L)@1! z$^|%|)B7P7#QnRhY_kx^Wc{CrWSioAoT^c!)(>zIc${X0bM74vEjvA|(c1Sy&=9N8?w8nlW4;i7ZTjTNll(G+zOSH6;#+pA z(nobvk^ZRrsxMKSiCvol+z1^YYdeagy>!WHzQM0L2A*4Mgt}v=U`Kg9s^(+8?VUz!^>gqFP3L*+a0k#%XRu?uWuq`jO>~2 zW-L5XQ@bQ(-270oKSSR#d!{qWF-nOuI&wt(6LZ&0P&q|esjIP=ymeDxVERE}7cWQ6C72L5x_2hqSK3bfb+k{bj< z{wtqZqR$r=2&h+QPJMI4MzirGux_t++GFg6eNh2%cXld2G*LkgleSuLxO-_+)6<2l z6LWJZd-A~b1&!>6L6vSp__dFh*AWm-aPXflTO5U6qL?wlobI4b&mBfZV`Za7Jqaj1 z%-8Sp3U*@rsqQC26ZwW0u;{=6thaWfyUceMnD{-KI209bQ{ml#b|Viq0NTh?G%tUI zX{kKbD!^0=VyvNHqdzhD8V0#6z}kP-$ckfkwNJF9+P3#+HvXvQxE7aH~)MIp-= zkj?`TWO{BcMS*V5m5Sj4&5LmPitK=8-nR)_K2rWQJQOYo9`1$j`SKFRd#u(4?|fVS z=&lDio@*tor)iD#w2@0q7@5XrW*X*PUa62ho!&rR>@bLerUu-Dx$n2t!{HA=E^V>f#-EGMlu;H2mLj5#gxg-gQ5 z$FCeJx%ae8v^w-1ds}HR*--n02Z1SpLIi%r z`%|V^GnspuvtN}9F^gE9`LvvZna3r%DF)N_Gup-84<}F*fhc-ZVv#ofqoteIIcQE* zf?l-c_77dBg(i{snV})giPl+9?E>BQb5MADnk>%|QaG!cL#av|rE`o?rnEP3hCR?j z;?1eoVT73RTUgl|Y(56NUGxhNR9*gj?VyqU#NhNqO`*4miq0|KY5u@BXJdv9lDhTP z7Rcs@liZsMhKGk4>AMMp-y8hyLr_}xc(HqEVIQA0StV&Xso0Kw+FKE;*v!`QPF87= zCF4PITAB1L#VDsebbn~OHR;#WJN|q9;=s1>rAT=x*L!biKcM63%k%)kp+9XVd(>wP zl=Q6)aB6gK-;Y&YwW28LqHm6ybA(W)zk$t3uE3z4&UmUcbcTO8f-ac8d;)b{(ijh?y)~nnCP|Fi|^984L|C& z7!Tub%16!3r5i?bDKVw&?C;eG#ufrUl zQ0cRL`%)Zl)2({_*4Cpwy5wkmc^QL{->l92U!|lKcQ;OK_3DfZ+)>62KB8wmRZ46h z*8H00yVA!?KlNwbU64ct^UL*-aa_KlnS{FkhBwIBW{!*r(b!SR?UPzvbG%rm&b`E^*}s5q8a z3suQ$lG#LWExHbNE^(|Z(Dvk!t|NX6UgI`rd~oMz!eaiG5`H&r`@Zx&P9-jylo40T z>b1tAQ!yVO$4*7mC@oPhtgrp#uN0eq>-xrqFjy@n28MfmtV1YN84$>JcXvCID}wWo z0L|@KoN_44nM1rlz@~Z8;N3@}WbP1NIwe$1Zja5*w?C>TZBSuqedGEKFZr?wZ?>U* z6Z?)Qw`CclHipIX9-jk$(HJ$~F`LU4xO;Q%6k$=8rFfd@Hf>fm1FQBvRfMfe9B2$@ z=sDv&52NX?qv-yYZF}uk(OW!7V&7pqE`sHi?b+0%)H8i8p!q<{R?X`7=gJ+ zvQ6&&5M;dycrQs|FwmILE~wcL}5SH#|B=G_bcFv)b}naeuRNaG*Al%RMI@-aHCs=55Yx<2*h*xb&N;(rJ_p6#zc&q36Z!~(BbOx2MD@GRY z3+efPx-VwH{uN(mENXyw?u_D!t(MzxttJ{e$UnegH{RjR>pVva@m61zFIE)WKdjM? z*$8g`-so#$uqc+=?@|+=$p77tMR#AX$2EC;u`I+_My^tnK1xC9L+r}9c;DO)Y{P}Ni3*ztQ6JVD%sRj*+kV1LL{^4%v4>8~0?o9jJ zxIDXy1bi>^MPZRc`aX^|e%A1OVY;t(8xen9tkS^#QqrE9nclpYcrJ6_+v!UwO_#&K z>)2mS_rw`g>m7Y~fz9(Oo1Zp2Vc5!@`wrWhZX|@DzSyeGaaObb^ZBoY&Qq9~o4e!I z!Cvg2G(~>2u_w~GEA~M41>bTBH5inxL%(NL`ZeUBkJz6b<$WG@+9I=fBB2u z`*|~#-obR!S4%XC_6S{sS*!-yv;-$mjq5G&L7-(Fw@L*|l)+RQP4gT|OCC63{9@~D z!g=&SgrytyR=kOHt7*Z>!l|#S!xl&<(gAmU zS{6!B=FOQ4bZ|Ys)|`{%)-!5b&#{)9B;+-`?b&O#;mtpx-5jRB;iKuejmg+6_=Cw9 zafA7dIbkqVX4_71Ha-H;V4Kief^spJ#dNK&|1wBZ<8?;HzB2gGKJF_zQ7wXi4<1lv zYTHiu6vXD^enFO;ENuRn;97p>zU-m#+D45&cu%@pt+Q2$M$l4JnU6*B7+w!gdi>m*4aE;+HQ8r2#o<_aj^tGIc(7*vMOBMrx~KfJIY@goqprUDRDuEm=^<%y zS`5_0iBr6VMpCzJg>Y@3DA-u`a&g`x+n&Ho1qSg~J2p$=qnmXbzt9D2Xv@(45E)JI+FRc1_1e0gh35}jawTRQOk5tNsW|qmMZO8U_0p z^QJ1IsYQ=x+>8O#H4N(#cgj-WX+OKidpEv*azZ!M7&JBNEy4ZrF7cMX{C|UWAiD2X z4rJZjhFt5mCi8eagDjEio3Q!h(F?M^n<0rV7P9_ss3kj&niXaKvM-vbe1Lg?8Ae}w z%?r+9!LECEl01oP@B@DbntO!|5^I$sU*>$YcZ!5ZC0#pCEt@*jcC9vMv4@|=?0yAGl zu$rjkw5;iufiw_9p59as_i7kZ9KNR;c2^0z(|#7>)UAAy<1A|yU-zg+NxT2Vwj3dt z!&+@23+|styh2q5=|ibo@7x3!kd@c8x6%CRKnF#IDN?SAaW(8udp(L= z*Nd==kT#{1Pub_(rPu562fLoG=3U;!2j0i|;E3>zHKpl*r_v9~ZFUyWgMr2DZFC1Ej$>F24IC5&1Y{=sQYwza#JBY4apMr^%0~c;cqd zB$7-w#{b0n4ljYqtI^E&Q*F6nzlAF4o5+C+)Xeo*3d}m1cmh|UrXII}$0a(mmDb=( z5B&K$QSWJ4VL$w{m!i>;b8I@h9&_^QY>4ALy!xVT(c#esa$ZFbLw=e=C#AW1+T83e zQ-kq<0>`cJ6~c(W{dkS!myzE7QPk18$F1`Db(6$EQ{%3K2lE<*$hl=r)JR;#{Fb33 zc#Qs|qfuy42^{+SSbSxrvZ|3a7+Ix@!uk@DE%|^!@qB{}quKWI@o|3jN*83xv$C?j z{HuV*yDsTd(e%Ln}QSTlG&X3YsnplUzz!!G{w)CDz`ZY2es8!Km_dF=7h z1f28KI0q#z)P8F3iGL@GSn%rf!(FAwrF*f;YdgQ&_QY}}@)aFuAByI8@^i}Z$vmK? zr{iHGO`f`eH9I1$P(eOsy{%>8Rn;sJ*iNnPeE0N&u|+mrNLN-<-21(~^)}qU5AjT( z#(!)H3w?v6dLrQC#e2V&Yq<@!>l-j#46877nTE1-4i61|0#%REtJ9gMJNs$<(}s^> z`CRQaN#@V~$Mb0YH2=Clbpao% z^XSsZXJBOD8d=Iz!^xJ$x-cTZxSu(^gWtrq4fggxa}7N`LC>td_oS@*g*F%?P@wCi z)LS4D$aduVccwOmn6TwDHm_I}%Fp?5E3@hK^fNelRT%!CA&}tgM{YQ)fS-AZl zSl_jvweWX&vg6~!1%q&?sf~KG@naK_M9H$Y540vF(H26OK!o80yvdA>`2Vo?=HXEG zedDlFR6?6%uTY_=?0ZqlF8fZ|ml^vymLw#h2-zw7zK?w@A?wI8gTYur42BrP*nVGK z*LC05^*s0UdynTh-ap7#8o>I7zGg~B!QhWCMeYX-BKhmq%US}Hm#IJv9g>H8o z8zJv+0E2fD0*y2I-xqG$aX*w`jhhu2WZh^r^gER=;;2Q^6<|!>8dJNadER$z&+6Ci z5>O+wCGNT}D_#sb#1c0Zc)cJ;x)xp%rM*pz2xRXzwsbPVV-eWxZj(?8^1shM#pj(ZezdBPik|mrlnSEk=3%=Ixesx##7JH0CtX;Toq(WW zOu21Lq9`w8_~qmFRPj#5n}TiJHL4(Wp$EQN{~1$EO~(o&)PL!S^q`aRJScEJI1BL` z!H0_T_IXaA{RV1R%U5=qYh!3u==flQu?W_;t#0a4rtqkT;{$8Pg+V^Y{x(Q8e{K7A zNiJ#JB#w{euCO7z^4wVB87?F0NuN#SmC^DiAHJzj)6j5V_;B1-y&zq=NN#9i!pJ?g zYV;$;Jc|E>mQTI`m$b`dDWCGs;f+3t;*Wb%n8s|u6~e)No_Op+v6M^kx~wPMglXVn zZ4MZ6jBl@fdP84`aS4rd1qF{}r0QV%iGQ4umy+_}X89fZ#6+zH#AZ%CM@K|WQf;EDcd-7ZFIyR;oOssLJ z!k~^xHdZx`3tW3JXJ>UV%P0Xmwe0PC(pTsrJ1kiIhdzm?7{;wl_VW`HFvY#d``Z9> z4!fzYu}G9Ecc%8R3Uw9l3MnfY4w+2ga<&NosUAGA36H7MT6ew_vIVSXTAn`l%8v%k zfMBJdpwM>RSLoI8m}3@o{t7x0`d{0G+o6l-sPToHLVt%4GSpxm1<}%Mbv246;%OHp zFp7M%hjC9Wc%^_08Ssyhk?{;1X=F`iZ7q=B=XM6alLf8xc6wGU?)f6o^+@RtgBfwI zS+Tq`PPXJ@4ClUdruS3L3Lw%b_DG5Q5X(AEZmoO#R4Nmbq7EjVE1yiZ6DcNkLm1>Y zkP14CV_-Y??tIxFrK4{#X$Sq?UYV3LAMD=d^jv^DbTn&(ffuGDOb%MNWUwR!ct=Ej zD$Bp10-QXk)E}Oj-0-j054tA8IGAL7+pK-@T-IM$9 z^ijN$9O%Rnuavc1*1axknp|2EELXmy+gx>9b3v9*cb7y``p#lHClc}bd(H)bGjqlo ztEd8Cl^B?AmCk!}74yOe*T)mYK%SZVatusR-Fnxfaf5{?UP*<@yusVg!a=!iV9$UA zJh_!sa<0pYah!9qz8ip$%EA=yiHYUu-p+c;QMOc$1iiaJFucXdlN(?+@x4}u2m9@K zra{IJALCKje@wA3-ir-mu>`Cef&vM{f*6PI;Qxn@wCl@zKNEveiL7?r$XcBru*j-K zHk!#a0D75&HeM+@r^+qv$F~%~TpB#YlC{N>`;gW2RK>1?vF7IHk3dAiKr=G0L?yX& zt>RF6TW=AhoiH-wuEu};1wT!r47+Xo(eyUW&CAlf@<;d$AhWN=7u_=58d5kjy0#@b zAz)?{#LvnU6A83G1;-B`NQLh7gzp1=bT6R_h*eej6w>~CSs=0YG}US{$}#n zdSof9o$E}04MXwneuv8C1FV}-O_BJDcHYKly;nI$F27JIlz){)R(TFc> zSn1ooS<2!x5kSGzHh7X9EXM~x*}&5eoM&8`%`-#Wm-!kbvkd z=8IS2W<^rgH6B(1>{V@aZF-u{kS@~U^pVs#1MRJ4q+ye?-+^}!9CmTQaIn_D5O7Rhs?DXKX=D3&f#osR)Y!ru!M_kXuPSfBDI(ReCe^}k~ zfLt}=*6)s>T~!dkufXuyX4hLHGs?;n=VZ;+-^M%P4LpoHL$=;lxVbLvd}xSJ5A2Jv>}2&V0&o-DU|9iN%3sMm>Fzvo^>;gHMu!EoGiz?sx|HG9_SeTAT^;z2 zNIaA6*4|P+DL3jbaXD-;U05o!IH~?gx?0Y-hR&l~mj-lHCclJCZfiboZ>T{PR`&sh zYc-~n0Ji$)&s40YwaGdX$h69KcIJI<>$?-QD;LK8PN^Rh>c%h-eONqL%7WjvNCG>K z#(JTq141Z6M>S;_u-ZIN30|<@D%n*03jkGZy1_mx+=$+2bg;Tz4?t|^ExFQ!sxX}l zEc2SA%~P;Cz;FqTuM4we%rNfP%tcb2)4zi~ zUxC#cJUQew7SKqon2q!=WIO2OmFKt0;-PL&t`|$5w(Y51Kvpe?s7(95#b}7}q_NF2 zG4?JUNY{DuOwn(YpGl~zs{r(|PdB*Ov%S-K?|p`U_c9?R;QZh5PuC`&aXdP!1%|EN z=&I;X!Mpg2XRWTHS|FmrfXlL%9N{kgaYbJXs1<1_P#bJP+2HHK0Gt%o_>`6W036Y8 zd}<}xhuBiFFi#GVJ(}{MvCG5)CUe%Vvb}rOAq0u2C@)z772Nic46J$vjzDIwPgi%{ z(-4qpf2Uu;dv+>6OrjO23%Vet^etisIqSsa7Ae<`=-7`~KG3ZvuF^-k0zNzSbh;Ff zz`=;X>`h!Y{^LhPIB4GzQZUe;!odPmuBZ&PpRyZ$WYwAga@M2J@C*aL* zs-P2j3x~z;^$plbUl-)8UT-OoD**md1)+yVGKD@808aL&9G?+>InFYYZ4a~94&-6i zDu}~Y8iOgs6+Xj$YBXfH|7Va*@y?vIy>7XiQIW%h*JChy3LutUwp83C*TK4;IqmsZ zEWm+`CWOTx`y_EpOpLJIKo7ua1G%`m8p{Fh2L|)HyHr?xZu+xFTb{2Y8`{SIkOblB zz&2tJWL(>OV1Cy4O&-{p$dy~C;S-J%+R3*sjzx1!99}z8emCD8IN5|7rir`zD|I-q z#;;eiO#*U7IEXi)W936<5xZ`CSPO`o9r9(nw)Xc#k z!=8$(gM22AXVO8ra){g?iOf*@ z_Vf(b1)BlHe!(gH-vzKV+d@6ZBlHql!5*#FErESh4N#q^rW>Ae+=s;SW2dIlB#?v6 z$a#n61X@Ea6>HTl_)1qy#S7`W+w!Ef1|z_G^iI9pfuE!al6l)POIj-LY=LNU+H9KG z=j8RLAh9XfgO;JfFsq&@cLJhq@2=(ILCNK}vM>{`8~Lsz=V|xe+@Zbl))+Bw0k)Aa zuy*?%uCBH>I%oPPefIPi52vT7N!w^+Ei0?+M(1BCTD16yb-BcY#o%ky)YOZJeL{ox zex*szCrL-%HppgR-a)}9zr)+w+%f9wXA@1lvaExZTmH$a?r-Tgj)G*tGtvNCI?bKi zU4BhB=w90d#5Q|>`(dMVK#9U>yw4$4Jg7gVqNGH7-33gy0Drh!V`;%<~(M zmR47_Z(ZWvE2sp6ZACJGP4Y^~26U1$TK@5uXQNv^7fK-p4Ma|h)m84jZGMiiDx+$G zLoO(SsZz({Tsl8LZxbLVT|o?It5|fwGV3TRh5->6_|A?jBRqr0EVjErWVo%3&3CJV z?TW_rz$%94-Ra*8K(DlJUbBwo^D7f|@MSz;*A|#6_m#2CWHw(HeYUO1xTH!1P;H|+ zGk`e$!z%^klCk>rUE1QpZGYj1wgD@_zYonkLF!eykP2`!5GxFYtQSIvdj>g|H>`O1 zJtS=0#@)VgAK;gY_FI_6T)%k}cUuQpF+^95=T!|y3^1K`@4Y5qB0!tXYM7tE)8hKm zW$C_W?YK&9zH*!C7nSrY)(|QnHbt|0FF)ZvQOMDI%KGv3^ZVI|SQTcmY@n~{M!VBv zS%oizUV4>r@rsxIww6cv&34cg9z0qXJTV~hpe9~(I^4BA4bgLl(dTnkJO+l1@&0cWZoi2U64cH*lJppSKLFa4uoeHjT@tpX zglqMbFs=@-K;n0So-o22^-<{tUFf4t2frar_sdWIy+mYWX;Foph0Y-9@_a2r6235f#_(qfE7Q3~Tz01;pHN6*Og0I%5DQNg#Rl4!127q1G}{u0O(Nqg1-bCpc{)-GNpuKL8@j=e$yC#o$X_ zp3eGLfu^5VDOva$|`*^0f;g=W7!Bx94swE@ixJ^EJn~Kez042H@yG>4}Jx=94ZdD=?wgmP|ej;0IWxK+{r0Z$4l$C6*mwX&B20}2A!SQ zqof2jLW%xQJ7N%Sd53#P_WZZ48Zo>;8DdwaUD;1$6Xc3#zSUEu!`!2gJs8xVD4qC% z85On52gOmV5c3cb1STS|mg4MrtSJFR6W^ zkwx6f;iL|9zENQs@K;hW8$IhrV94CZgQD>stC${IAR;^D+G5;CM~8qbwZb5)NJpd> zNOE3Bu6&3?7`b_vUiO{oCp~@naD=4uk8khLE5O+HRNVs<90PU&BO9NwBit(uwj;2m z9F#wXPhdNs;#-S!i*Vq?5LTR6I6(95hps!!VZ?SgH>R=D8ru_wzD@wDmXLl{&3GN= zq-DS&fc|?weu&5liLROL%*z2im;QY`&~KhHUbHvQRFGB6L>{7&bvWcrcI9ye-D|1r zxi4g4IBYp-Fd0C#fQ7=^O-+9kEC3m_quQ<}z z6+Cjd{(fjHSdpvF%eBXD;F0rYPpJ9QbVM6p{sqaHrzfQLq?e)8-tnut0$1$6DW8Q4 z5;$&d4ssH7IOR8Q99Jgkwto9M>Um>iNGhRg&e^@SiSH1H(XqAI9cEvGP3Pdp-v3lS zF^Mj0PL5Ldz5^eD#DU*G*9v;-4+tuH?(2VU%r-Rg7cb&Bt^t0S!BlA-6Ro^C`&Qe% zvl)%qJ#Zu|&>ElJVH;;Yz36XiQ&JUdaVT-FKmXxPSXQP@>(4h7$(GdO!)1t@-WLO$ zDnrI9LARZu?wg0!_Jd5j$mGP^ME#|@U%1_GRgmz}Z~X-K zyK5ih;x!F4rVPvP(~l*1N8NPg-n~YhxKm~3RM#COecQh z>_(01o=qk%tu9yS=ZNyGE*Xtu5yt zDXV#Ib~VlDxuQ|}gS56jIVIBt8jp&F4ETFDRj>!f$UtVeIKYa+&!fjxJktN_Phmq>T2!u-cqS!j+Ry|oLLs!P&sBX(+( zRoJKMCi8vC_$F^ugGom*vEnsy>$R*EOo&qM)y4E+lrmGG$~LKDd?JOedU$>FbO%4$ z%K63zm)_C}D+IwEZD0mN3NkI#iQ#q;)p`9x9? zo;1H#Pr@bQf%g%qjqM&4=AQ7`g%%FMHFwa+)2qjtj-OjTW{d7!kXp}1uE54cFhxFJ zaO10-=($i|WMUlL7tfUMgmW^jSz2jnEj{q#X%xMDY9y=hn)Sq$s2b68T_(D&E7W~Y zk@MpyR`gQpT#M{t(BqDEsVM#%Ge7E&34aNr$BKwQ%Z2b&y{Dq>Ang`Ltj?#|^FT2u zX!p;{@|eO0CE64;Qj68KT(j|pHx`mN@Ar*vAjDFOGO1|)fEcJR8q;)@kc`F-GQ8s+ zzfpreamoF2t^55g{e;VgC=hozZphy)UfEzB^p=C+c=eu!I1Kl@d0EL z0cs%XGE7vbIIyc}ly<6UZAjDA?(NID*EMerpOYB0$S{g>(@;TO?sTrtqOjtKU+Rj` z6K^f@g^bu)_bRpXPZIXyD~r~T5QG`SimVMsXAW+;Ep}&NlAprAVi*%&#ny=8^oZ5% zV{uNstD#Au<`THiv)&!ds)zQ}kAv}t;W0dtpgm-Mb|W#xPN;bDN@x2(bExSzyZb4X z-LZa{Z}u*?FP0ebn4Uadn)WI>6Lar7hE>I;esE+9FH*GQ+cDf5Eh<_B@td2IK^&y9 zJ1){j20P@sl#}rB#8#arZu9cIx)E3x_-e4W(~Z!(W}+ zBC8BDrB%Z~rHG-@zFrt&z=oc+ z%SgAU+S#zXezhhYegUo9DZQ8G&U@Q$CXj|$Q2D*|OJDW7b>}kSd5Pivrhw}VNN?%5 z4P&QpLW1zP_o82Z6$K4&wF1bWAQjaGJX|t}`a#$<&=X92*`lHyZKnLTI&*hzg6*|4 zK^L2u>iaxskSn~#&*ZV2kinfmPFP~1^16_#d8MTxk^wnp7I7Rc9Ng3K`8kB4QE;e=;j<>hx~qj2#wdfI>+n)jn9uL;r!{~UUaV7b^3+GGw$Dt|hy zl>}}!I-{Uk+fD>5VSRDla4#YWOnQ(yUnv*Jb)i2`MmkD*c^vksinHf2yCNFxZ;4+9qZj4 z2*CtVYgb*XfH8ow8TT!iawg*WYb*HjN+&w`t?G;JOmN*~uK(y(n0ULpR_ZE5HGb+D z#=Ij?IiNk%6}L@bb0TprI*V0sj+hH#qDMPYn*rS4~cz+P!M+EX;*E_d%NAOy?be_w1hEc_{XQAf)Yjp z4q^iMZD=c$CUYF@-YB~*n}UZS$?L0~54Nh3XJPR&rV=AtHGH9TXzoY-X|rXPluQGN zS;8HR_f5u9lQ&DKdp4%Zlr%s}`dN`tWf(6&9BDVi>!GSG3eZVOfMn$JBx{7tdZjFQ z?MGyrc%`UhHgq1cs@T{6pk?N$oQUAj{YfPsUvPuUmk#Zvnm4{*cjfn9R~lexJzT4w z@ItEXix~Xbah}vFO$TqBi{jjmJBpJ`#2=1o!5V5OOrVk^rg7KP# zOx|Z0WVCsY6PYigKO0`x4vG4%!am5M)sEI=pY7B&D{}o#HMYRgQS-wSCBFFXwC*+B zTSKd>@Ow!C?E$88(~51zdfHS67PiY_=734V~P{h$I3Y` zl`ucq3VNAuHof&Nw{w~{K@vUIKW>h>n2ze!gU=;-BRSBum-kGIm`bYjA}XKzv}`Ol zQN{^ZK52I;s_Pa+NzK~k&nBp~YxM~-IvU{@+IFEbR+=E@j2ey95v+y}HBZ>mRQI6f zgHDKmpq;iW+r=vZ{%p;xbgv{ghJ~9`mL`y4!y3Nm*>%i9F;QmBq%hTtO3w7d`7T5i$D&@|6>ZX2CbtJb@1MQw7Rk4G- z_qKHiPv(Fs;l_R86bK?C<+3<8SAp`R_&SFAjAE#gm9~(jQ08iwQjqbZ;WVJ zh2lANGt91X6RGrrzLD3g<1xlOQyD?Npoq@rNl0ty5-X*+va>;%^RBRI=xs)KD?>R?Niko>hVr%?n*AWb0s{adp@}o;^wcTCmT45xUux z;WtgO;_*f9gKhoV6f95peDyO7)2q0$^{01Byfj>7&Ay4uQm6miN%Hd@JsgM!dIa+d zH2IrlZAX%+qmT0oks}0Bw7O5Lqt|aH1T>nf(oDngdaXQQ$Bu&?qs`53o4n0c5I)JY z6A(zP9XMK>{@oTzYoK$yNR-||4~w|M+?Rmrjr8U(=bqiVh%Dw%Qi^K&DwF;)B(b9&D4MuRe~v#C%|7a?kuJ54 z^4t*8mXRcz-J5P`Z2b-SF9Y$KPE3FYKhT6z*p=>ggE)9LAi3}!g`njTe@pB|)v1@x zxG_B`{6NtiJ~Hntc8-y)et9+Odm~D2@cX27Dil&-{D#N-zO(Dq@>pE_>I(EJw_9tB zybFFU1HRFf5%WINEK&G`%45T9(G@+WU(JR_AEIgJQLRD+KX40n7sh$C7~ON{OsSev zf}T$yyw5K;`v6t^nQDi_ZPl9DW^XP@n!<%z&9~lQ-xYxl*;-p_6F466{(fRc{{!`! z*Z$MZ{wfV7x=GaJlrfP2-{anrilhiacc1$5u@J%)+CjgtUE6h9Zn7WGu!^lA-4{3ld3TD+DorVykdvyu>!G2;@`@Jo`MWKK2}t$JgFo)Lyw+e{IN zZ_kt2iYtYVOMzvgusunj9ufi#j>*Vgb~W$p44msJl!|fQPntS18ojJ-38GAMe}+8@ zO8dj$p=Nh#^&h4WvXbCsg7H7UB3nA${Esj%GBVV;|NonRo2LF>TMaeGO!{qLae9M= zPpBMBFyN;nXy5~}lw@Rxhz%1!^wQ_1%|Qa4TUf!u8rNKoBYu0jhNHV z>V?`q_0q;{D~}eyFGKWr`;em2U|Ie+ayWPx#}n;L*A^t%K0QU2RK9O6vt_%Y1V(j) zCtB5a@-6vCUG51_@a)WB#9PRQeR17XX$0d~?8*Xb(;JWIZAP&2+DG->xdK zgCZFRCAd69tj5~K{NY$`)>H5PVL)J+j+i^U+9&K;s}0dT`>MtZuv}!5baP66Gb=2R zf1q3xUfEGevdYEli~0c-=^2*bzBh>(xA$|>Fyj?E-*Y0+_)+_qg(3oCUgdS{OA`Nw zGppkt?w}7IIlx3R*Hz3gh}r6SB8!f&m7!>ng)wow-yqbk;0K%ExvoMT%;mt14U)*; zcK^m7yWd}`)Z||HlJ3;kS7%gWX~>2Ln$pmN4i>}q$IpoCDMtu$&BW69?ay0T)&F;E z3n%+cR%hA5ng@xy#%im%iSQH1t?KD=$?5ltohMK(P5o?SJ`LHNM`kTCOu6XY3rVL0 zE1+XnTwBoDbE{hgO@$HJs$xaZF3%fronE6Y3pf9Y1-RMp&Sh(_xG%d7Iu50$O$eq_ z$rhL=`O*!K+E< zv|HQ;=EWz#ShQ{s1r>`U^yLYDc@rJ=E-t#^J3%SL+~MrWS5> z+C=9%8uY!EN?I?7R27>~kVk@2?szLv9mHmELNI>6*TSj+Q>6x?_d9k(|ANy8f_mSl zQUp4h(k$A@k110?e9x)RItHpJ4=pvBZq)2e`Kgz>YFd@+HQ?!JFUh$H?S|5djhCb3 zIwHho@9+3^c`e-^;O(sCx@i|?E^4e1$RDNTX3hwhI)+7<%+7+Pd zr%{ST1MMQ${-NPqr3YUkusSSH#4Q`N3^GMgSO+@VRRxr?94hM`QYE{5H8?A)sq$L! zb6JnLWXuT5+YILq$qbm)&Ut4@x?`HSsh)>eic}Ke$7R|SZNQ;TdC3neh1OI{vVU$v z3=)sW4qvHiD9I1z`C`jL#MPl9utOfcLmmw*2;cu=1u6en0pYn&rL3sdUS@B^IGpv- z1iLSp+}!S%HX#@=5iKgHR6Sp5-?wYimAqFec!_CJS|Z5^FLZ}uVS(TTQaS!S)ReU) zs&B@yT{)|3dlqx%#5-QqvH8F>UbA<|rwT>>s@g3CfEP(xtbx##D>$#Tl7h z*Hb-@)IBrCnCkc=vkax2QXrmqd>A|8`$bfcfFW>s~rHK%JZKKp$H&M2^$>QRvuP#+mg40V|@0hIbrWmS1 zVJO{bXy2|wTVOVBqNwIvkHr+inBw5{)}@oM+k&s{XGhx^dqz>FVJg{ngg>DhC}-$s zmAb>V^z=|=WeD4?xw90R&DOHpFK$^ku*C|Gr_(gR zite)Nm=&5#L;1J3cMH}Y1D|^MBrp1~FPI0rFtv7i5d7w+;q`e8r&1I4_R^>RX2GGz}K_vjhjOqMdpy_^vQ|gkw0qB+F&Vm!Wb`4l*#Pwllh9h8g!u;YIp5 zJIW{Jt(2P1=;{0rBQJ-vj*>nzu7FXoKHF8RogF|jxlFsLKebU@eAzi?|Am)pO8&qz zdv3H{`Q$rvYV3YdGIdfkvobgAUebtXuKsZl{1M?9j$e3%Qt8%G{Zgo$vQDAVY@b&8 zb4MNm|MKi&B{S^H?5FOFDLZbw3&|?5=);DDF{1)kHkHj3HdWi*M}`ZM{!@sGRC|Lu z=M-qEQJti@!JYGpMk;-YciShY^=gNOvPR1aJwBh`4a$MCL{p$P%lYyQ0#y`kyMY`Y z3F#rEScDt2d-ryF;cKdD2Sh7HfH@`wjrSzQEG%j+3N4F_O~>NGYzv4X;$q|MaYBYd z=y!+@ZuJy5P5mEs*LHK&t`PLdDNi*39>i%pPXi7j&Q6Gj8m_k>9h1}2o0s+ybmcc3Y? zZI-l|Z!&%4Uj9Sy;bgQKmij}0quI?UMA=M}7Kz@8{zW6B+l5r*C=t$ywYN7a z>-Ze&>fQs(w;J)PR;fytuHOCM8w|#d^MYI+vnhXtJJfp@mpj=IA#StQ51>yTjD6I| zDy?qBO#=)AGyJ_kMg_ChA&JW|?4rjEP!tA}=IR&?Ki^&C2a55;jYEC7n-OhN>c4{V zOe^)CL@?`>3m=Jx0JLVsX0-u_HxdMw3v>>TXgY8~{?-hY zsL6^tYBkG%mtd_CO1=7VGmL$|h+|~}!RZKGpWb(L6n77YYoTvUsOJ?JWBM}QVm|%h z8PyG2G0Bl(Ay$keat2j?hp|hqA)0OP8VC#M_pUt0DKrT#%-pexvYU8vP$)3*vJxU< zr_ZOF;1pfTs~fO9mk75P(laWf%(Njtw5##ME#?A8NJK)Z~Z5*^{p%FAy3uhlKNv9i=G! zc@)sT`bT6I8Ck(KScA@Amw*3kA~CFn$4^gw(!&#SG&gCrWgY){ho+Qt#ekpdkUrim z_t7S8UOWN|mDo^bmyfGD#4mRwEYXG@GD zLDLibq%^_{W+NG0I-RGQ8nM*fgawiWkwC_HAGYz@*sR^+<1#)8hnNw4kM+g>thHK zO-5txQp7xs2DEU;O3v7kdXBW#WQFZgSR2aS;K>4a zk+OxpQeu8X`~FMg#dTQK0~0~Lr)!S)7H;RCH|MDSt-0lRRr)Cl)$u{``^Fx=H4-7kUF5!2zyS4F1UXb;~dojV?z22au|!L zxm8ZHrM~sI&28t=`wL56R;m@#Grq+bb<)$uy(ppzuSB6TKdl_cJbm#LfUAZgf9x}C zB^;@Nb@|e0XHtj~4j7-yZDTBcQmKs%E5vZBxm4Cix{ zk)!L0!nzf#lL}%pgYkKD^*2CpkxQ$a0X5Xwrnt7YR`w1eYqjhkw^fQ%47P~lwTdT!wKCIei{yPLC=wWdXY0C~KDp;G)3d>p`g?YfCJVzN2C7Fdb#{{wNGOblAjZcEHph(50DEA$vlb7cv3q}Lpo&lD zOJ)bbxnsvRcV))c{hBmEAJgc)SnQpHSC9gk8-V&3{*jJXvO3QskRMBBw-FClGJ@3l#V3l`&mX6MeLj%9_6I)w^#xfIOp}H1v z4A1|C#ngH-rJYP@#na)`UC&FrlxJBr9%ZFXS`Ym^eUrOXRpoT-`-d9(5v4_zL+WzQ zkxynWG?TYc`jbZ0xPF;Kb-#>D%39O#~&zG(VzHXQNA1-AC_g6pp zj}N@|dgvS@@qf7Vo>69&^*;>*e5WpJJ*sbpJoiLL}@iVYzO>|2yLO zaa_oDKv;zPEwZ(?*X~a+PQCA7$KgrU2ByB}q#w-MJlB=}FKculBUJR}6W_V<>f%xw z>*Z^H51?o=!ktsLlIQ%dj&0;#+y@;W%{q=b78#l7=1aSN|4uVE6zZ3B0l_{JENCX1 zBfjopu{q)tP)Iuid3`NhPE)ex*jZelCq1JoRVxXs@r>MvG+i)3w*D-+Nzn8Cb9}8^ z23JtD>-Pn=ex{d(Y@hxPeay`K?c`zL+nkWF{&Y3;*X}F(%wQ1c$Nl?KUw6N)?0`2u zAsF$`rku}K9jE?A9pD*Vdq}GJyw_SBGR~m21WS4aI=czXUy#1W3dIxB?DT5^4^JX$({ZY*}Yfs zr6D;=G>(*)24sOhV(p7GT1b8X87(P`rT?6Jrk*$Eb`rD z=@CNyK|pm37?aoIVy#RBQa;B6b!?rMo@GVtku7LzN?h1SxlEE_F>%7I zDr@Pr4ef&|Ou5g&@B8*ejCj=L_i)L!)qgp4qv zsMp2pTTvy@H|Xa~Rl#nu^=HB*x7N&j3e?6sXz!(8Wk<$cgnipsREY~Z$1`5ElE+9C zG3BC_o){5vTo)elwAq%&_=PYCp1$@lV82?hfaxzvG5m_5W{-B(>>y~gTA?E{%)HlC z2?AqU^0waQr0F}r_fN%J5?ij12yCI#TnX=Y9n7e99Kw!)Ebo-67-t7TlG3k+>?!E6=E3jFil zA7sR=K&Z3Z3g2Fl!^?J7{#P%SPmB2hv2!tV`bqe%?~8li)UcTk!GIq6#!(QI>yP(J zX3jp*pgm`37RgqMvDz)9j(e5tLj2OVADk@Gm`rTAk2YNLlz6iO|LC$6*1kXHPh}Jf zQ<-srqKKiy*jsbA(-mD}FIesz*B$>)9` zu|@ahna2wAUtx+LyKe{{D}jfP|16zddt6C1=PVb=qEk_%lKivdu^O9F(((|#I!?O5I#RiQjc ze&l&_85P%GLyxmtuC!YsVGTZC5u8jVb-66OXj8kmUTuV#d*B=AF1^VugVn|l*Gdex zD1DLZO(YB&f3F(1T$!qXA+g_z_-z4e1EaK_aQgC4;{$-2~tJkwxKeR`w=A=8p=%=r+dclf1wmFA= z3A0NQVzL@rjH@4E(>hZZaCx@tdGT;OmT;$p(Tsi&PTxLH*0C_xv@Qx{yxq8~KX+ft z_nS;*Px-&!gm_HX(PQi~Z?&D`6j&W5-5;z@t)SjE!9K7-el&*U$8bC)SiB2>?HDe< z*s`CYyOVhSwI`JGx$pVn=fb!zgOC^?JG_C^JDa&s`4tzZDc#n8esc{^_iFR1(dk!e zCJ#@Yy?lRuBwn||8>#&9;+0L?#KIGES77zJCPQ%PhM63?l2R-PRE)P)Svna`z^YjKUoV3u^n@L`1((skn&{Q9^;E9rX1uip|% zhW)2!gVJjcYX$aJU9)g~i4A-g1QwAAH#M+-or^()KtXiDFNB zvOwTr4j*vh(r`b_Ely*Eku8aTD`|X#zGbQX++Y|y8?f2shkpn%WZ==7e?I!O%Ii3} zqj7H0wvFYZF}8xH$>;f|iR+e`U|sl{xAYkc_+~gqj1>b3kAF)@uW0^~YqpueA5-AM zJVRwxVj#oJD2Cq>%wHeE5B@K5(^4`o*ub(K3s!YNy!}H=MRXN8KFBpi-6HWxnSjC~OK!!+ps6 zSf`EdT*bz9PwV*d8B{5WI!?V@glR8m|4hnOidV1PdVZ2%bftK)t_b8^GWw_f{nc-% zuZWb;0x$iY5QC)-q#AZBy^+U&hTpl4*fu~gv@gF5IMkQ*B?qM32Y;f!I!m}XjkC1c?OV=zKe7omLz&)Vat=?gt~dHk<1{3!?2IqgyO%>LMWp$I6!WQw#$&z+4%Y_%Lq7pw;f0CAV?W12 zFZv1-l3P_tjgC3~|A2Gu&Z9yUaQo5wkInCm)_L%K<;Z53ku0V>X!9bkd1+eOl*V+N zGNwi3p7E_UzCJA)<~OzXshD54PS-a*6ue8ttduI{`!s+&?N@+51A(zIcZmBpNC2^R z_NFg6sfwmadkUNDZp`(n$bsx9NCOuzzSYmd;oI$|W&tk|7byZ9hUUzMt4zchhb4sN<*wKZQIUO;a5_%IBKkJWN^>c3 z<-7nGo1eUOeN7DmB`xbC7Z?7Q<2zIkaY5sB0QR;273?F9z<#4C;MCbOd(0vwOxyI^ zl8$7We4bP0rtgn}=N#yymzYeaq~DMzHW}mmg~U;K(pGtC$G3FZ5V9X#l~zdBn_(Js z_2$dxS3Wb=ay_0^q?gPXLZj{UMnQHbRN^L+MSe^;l^Vb6TP2-eSb?fRd!aDUVBsC3 z;F+UaB@SnbmAcg-vPIR<8L1TkzhPpPPO4T>4Z(P#687W6lcfuxukTy+G5f4FQ+^V( zy9|0(^bZZa4i2UOt?TV4YKKejj2~OVyh+{cEp$HpHzHXir_`>JBEbOiamOANe0%K- zYFWI6T%0{&89;v3V{+8~^3e)uXj~+-4j|7)>X|R=5$9FNnx>{q+qyKmGIj1q-fsthf$P2Pcs21HneUXT=FbbdCuv?ToumZ=R5vl9C9B4T=!lik#Ti}( zoTW-Emc(0}1RaDwIB_tC`{`=Hc4i1J>OQu0^jLN#Iv@8kbTp~aQ;FG11s!i&pAg_L zylC+8Nrl@p6HvyOZpA0((g6JK*4G!M5@wNu3k@s7RxzCyZ<<=5Daq96T9rUnZq@e8 z-0s2@VI|sWV_Ei!|KO}!=p&iXvvrri3z9^QLQ?mx2GjcyJ3eFeR>b%*7ck$D2kYE> z^F&|$QH=$uhgMcr6WIHZI2?%D-bw%|z=?{yF} zNgyID(nIG^7q>x*N`Hjz<`Q$i#M@v6YpT zDK=R>=-l-r(>te&XB`;irZ$Z`9 z-~G3=a|1@A2+I*|7sGMlo3p+Va?rlD3g!QskBxf z{j4v#_2)GvidRi|#FH<&sV2`qd|l7DdA=%-2%>&xI=m)^Nh)XLE!YH*FHS|5TdD0W zaAa#!dYHvwVBF*d9{!I9(K14MbqB^EeKZ$D`5KD=Y-ociTi>Tq}c z{4|lt5ZcQ#Gn)ZIIJ}LG_X$7Er)*vQ2rL%`BuUe61 z20b_>Ol=Vy&8d-Fiq~uPa1*-TqrakK+@9Uze0=>Ld0&y2vTW)zHh7ZoQXzOG6SF5Y z8!K@4)8kOgx(%YgvNBul^epVBHTK?}6j@qZWSQCSG#C``#ECzMiF$>{GeyjfDb-jR zy9(Sj@}Y%XrU@x`=LL-K;w25S^TUIKtBhe+qdHc4gO7EJ2a!4IP>xRKsrQwFzZ_r5 zW`TE~btd&+|L$L3M}2O&0oB0F9^Pv93b&)}71;P#N=yEsTCSFu@U2@ncKn?-{sHe+ zPgfrFCLm>M6KquXb98fqfknr5O9-rybQTt(G zR;&uDOh*&}Dakd4ncJ^*mq_;q3Ki0=Pnp42`=n1sf{#QKo0@{1>?WnvaTDCk@RmLV z0^xPkya4Q_reEYCIAhc2Wm`7I3naSX?lw}P)*GT!U@ebp z@T3rpE3FKZj294NBe{=kSQW@oK6ruY{^>%_v@MH|<@$QNTWeglcVP|=%D1jGnOIy| zduTkL0^fSk5?7vpPO;%x*VA~8`Mq45T%ym>5NUk$?ukndM3iaQA<`Mxg{rjtM>+Q zm_P3@Gn1U}!6x!mbNWz^dTfA8vx7vPT{_39FVBr<^OiTD^xxt|op+2$@#m@MpzjiOTaBQE)C;S~&qIYmWn#n3hgWV;YA0l>>-+QJkTk?+5Z)AhTrV!q2oblpMRO8%lbe2uaR42&jI%V}`{u_d*Wb?08mVT0 zt8j3fgnOHHT;foRzWCDv$BwT!5wH1oZ;$0&7j8vx9n~LtONb(L=rhp9<<=Gy)0w-` zhFn(m0*O6q`wlJRhYQ$Tn5}Qv7=o&+dn>&pbv=`scW>@xG$bl?O993Lju2ff)K%7N9OQ=Z=pIy=EFlbwT`g}06u(hz-29-xAS z3V<{=vTQz-zp#H*_!gS;5B|<&+C^UT@QtK zOq_M}0dUd9gsYalXA|`6PV3>u@tjC^75;>Tg#P~iw0N&;pP!_>$kqcV>h~&JjFbH!uYH$B5f zJ-^9HMn5wJ!;RLbibjoU3J)ZJAFYX5F3#8vqM)_GdO<2np%kFBTy_1Vkjp6E!=BQ5 z%1wV!&37x60W$8b*8`@vU1Zk zW1v}YZVuZ`Gd=N{^d||-V}V$4!cJ#u7M+_GSZmmaRdE<5BX9oYIM9&h#6Ns|?7g}C z89~{b#1dHK#E4R;WiNh3%~dE$dx|X3AURjX&QwiuwcC$DS&tM@+I?;X*LKc7%I{!u z=87zbp&)KyXCE$!i6B3SUQO4l>(jWs zw(h1~5;0fIFA0Pu=D6ZyqGNV1@Vs==)?zY-MgAIf!_2WxmsKygeapk;-a0O@t*oz) zh_AW%V(y(>uEs5td7m~Ab|M`$7oGBu=UMT$!Z$-HM>IuO*V(3Mn8Xhu{S|Sptgo@o zHFRjsj0!3iIH}I^P0OAGeqchv%k_U7OO1AbZd_rkaHSdEr8C2);1P?0XSuHTNo@P0 z?Ohz2C+pv*?1oFQrfr{@LQJVp8HN?S2(EfL9YW+*GkmbAiye~U)J(by1Hb5mg?*z# zR>w+zbhRc=8v#PBo>vaa{RaZaHl~wN>t?<+Kb&}if`V??PD!BaK%$}l=i_^{h-`wc z|6gydg$5w=JMs_{(6B0+=_qx76K1W@mAb1phZ=4OtewZGHl9BtBM(d`!_Rbs=R#aW zP7Z2)f#gQ!H{@{{@z+WrUfGvYKrF$tJpMS$oF__!kdlyKIIYz^Fl--(x^Gi`D{fOg zCjSB5_^g@@`VGCh=OIyOYu{S)rRCAmbRm#O%<1GSY^9SrGiWinqU#@We8NOODaUK`;N4Z# zGTRC$0~m0}m9|?ZoX_>|nm)N9LUl^A=5A2(`LW6LdljD$reZef3-h7=LO2dv zn?fDa0KZAmH<1ml6jPOEzVS4BC{Xk;j!p?0IkkUDYj(W!n*cI-?d^$f5~}`3)no4C zYT#CeCO=RFhvenlk?CtD^8K>G) z312I}Z5J#uYl&d>_vt`*+V$u&gTrG~I=M70&`$LroW&V&p?Mbg0mF!q9GJELX;H9m`t+wT(hRiTkm z2lkJu(40JMl1jyn={8$*7cPB}OuH4zk8EW8&>iaLW?LPrr|tI-55Iv9U_vT|EXvI(&-)MLe3Y2^Cm9Lr=W*(cSj4=-_?5@V z=}LOWyv;z%nL3L)uYvT^gOCTB?>ur&icHi}Ebk=-%V?!E!shZ(D!pFYs(a)i zRB)HRL?qV!Ro|n>vR8yCPA`5&@DF>^ykPPZKKwLiX7GyV!jE3W!5oEQA{jnW@Pvew ztq0T|#GVn!om}aoz^hzj&-apxz1Y^nkC&B|T?auc7+Y6vqMfd&oz8H6pZ0VL#9nJM ze>JnF4uQ$;zXgMYefgs}8eRw@T zrS!P~LT+RMgs^>VWm?{c_otSOrnAXZv27+tAB49yJgL^FT#8`hb81mGA{MH35V?~G z;(p69alBBwMd{?>xC24T1g(Aa{I4;7_*yFb{kZEjW`E*Fj-bv!|A>w{ zDg=&C8LHkdw%mD~B{Ei{f#E|3Ux!G`$F4Qeo*`e)p4h22Yp*##CL;nFX4`8kw!&fk|w4EHsvcsY|d781Zq zaxNrSMe1={;>-enqZz4x05-G2zTs_XAFKu+`b0XG+!+K>Pcl7hQM6oi=yaaPa_RPg z{YOATDjSou`>@t4_D@P6#(fhV$#_aTh0(taRWJWM)i5bg;AyrRDeN^*DvlWA;w`j? z!HUvnHs0&5PM=zSAF{qvX$a@NkU0oiD0!$OmY7BNr`|>cS4M8Yi0Rc>qB`=flOv3UNM^ zsvqFKB}rE#H!F_;-)}RC;!1C zy_lB^#R7lwQzYW4jQrU7R>(=R$d2(HVQJeR3dHA-owbVQCpV)ih$$S5c7=w<#$uVc z??k6j;5VR9vR7^l3&@ zuQi4G>kfZ?)CRBI>e08Giv{9;LmYNnqivBMc7FP>Rs%5_{WBBGr`6|Kk@^V}-#Xt} zzgwDC!9_fCKP3LJvzfM_3{-B%rG+GSZ6n?J`gP7Y1+1P*`Y$Dl@*Uc^b)RyO-?*d${z3S@ki(9YL;V=hw?$LcQ->%v~s6`hZZ36 zq17zGOWn@C{+oTEyTKHt+kgg84Q@u=zrz?MzfJuOG1GsK1je<|-nAe9{AO|enavEd z%BZ_Yx47Ujax}ZP0G1)YX(Nl{@J7HUrD@lvMwXfW+y$!R^{A)Q{rU3kjDuAf=sIxI zP0)PvoVmdLb^^^^6`kIv5|L1{uil3VpJuE&c6QAn55hPA^vkq)`L!7i53A z4&=0;kr(jrk#Ve>Z|slFm{mh&zX`0{%nUBB{(NOmfYK!8b5|ZA)@SN$A34*)`xc#y z!igXPLtL8GxI4o21;3OL6eHt2J3s2F;^FUYHo$NzD+h;Ou|uC)7pcOk@+RJw&~Plh z=|-`wg@Z5O3(L0gD79?+cyF6WKpY6+)iDLFvnFl99vdi2d~*GY=?1yh!@{W&m6#?W zBbm2W`&65_=QlG9Q$er_lqrZkfAwXA^5^F_KX<$-!*2Onqn23BH@N|FZA}fEd z_{W^(GjKSbVI8dU7R}5j`O7)jBpibKr8FwH*d?~k7I#DpBy)4$?4=xSjN6WR{t$V^ z0#D+jWnp!{BuCAD#R2Pg;rh`;9NQbKNj6r$e#zTCaqEvLSEnPFZJF}$iPeWpAla`7 zjb!nYIJ_+PpTxg80$i^|@WA^GHNa`%$G6%#fW)$e3`wX0Qjt!6VaBa(j_)YYMgv&pH@w}#s%;JEf}iip7tg>v$S+* zpEYx^rdaMzM2z+J@Ar9hEQ$Wl*IAc~qCxI#sqSWl1Gz?tbzc!{(Yp$=2iO3;v49RY zX4~x=u*Qfwchwo=S^aNc&1OkzttZ#jeS@7o!{S&Ejx~)Z>Wm6A{~^C2#GIs-1S=wz zoqFc`V*i3a)MLFMEW&&2E7j3doc?XYYD0{u_!1+p6?*z5W{=pt&@>mLo4fskjQTh> zgv(W6r?mc}gb|!NH!25^%5BDM9xTpDX@iI1fMu1zGUpiMUx2Hup(( zYZ7%%yR_~q#(`~y<@0Ajk>djmb`*e{pmU$Jh@AA_Xyq&iCevP1j$@gD2k#4%8LIUU zU-C4>jELioMD!y~a$du0bDZKqeY_q>4_l!*iw>uVi`J*8CtkgL3XPnbYYbxG%PnnR z*3yPXQW3;ov+hX?_uk(Uu~q3+GupW9m$zJn7?*8*>XJ6xqTj%`Wg)Wzbrv!y>`iBF z|1PJqtZ>a(VmX)CPzG=Z6=AcbLAt7P&>}<4vGdt~hUO}n`r5+N$rWlZ-=o_s|K3OH z$|l%Ipe|NDh1MFk(bH+%Y%ZIm$1Kcc$i=#`(nVst?q}|A>V*4BnZTTS2mp@JX5{-$!Us$YEQxFX-cXB+V9v%ERS}*p}YV z@xPBfFjRGkG%h{3z!&{l<#fXWk!ZfaN2Xx0@Xu>adXUqS^{d;GL$1^?E^%g5?bf)= zl$N{5{SrM5fSU=?&4IW?uyA7A)(49(5GV2J3AkFbN&b;IetG&~N&Sf8 z5LOSa=zcIn*YFwUQotGA##p>(UznRD=ur5r?dZl1ZCue&Y*1P2tVhB#iquoieI_mE zE>0dba?&t@+dGWwcPykQ*-ZNeyqh!PFFoo+Vnk_BMFfa`F`H`H9Aipn;hM`v zR3^G%+{3#40HWI8WH^g8?>?{sm`WzVR1A!VJ${8(`wbyur))Ao+jd|@yLC+ZX_^0K zrkI#7Z-D%r_vwTB+IVrFb52aPle;^v)EtW>98YYr=DpM4H zSQ~Elo&ILE4KCMcuySaUycd=(xNq2U>&d?vq9;VPjQ!U~$2FM6LMa(nHk~)SNyI=bPGjxMm9o&uer*7>!B}z z=CyOSe>*1DlQ}C3${yX|iKXL*M!MW6$zrtc=$h~*E$^MgGXCBAt>f5(a08>P(IrkX zo}ab18ZTKW2Tr`bcwZpABs0$YNANEDBd#0bHaZl}jIZ;ycmMIixrV_DX0SFLhqFLf z+UoaHPm)q58L7Ex)L$7j8B-2&c7feAo7;??O?qIyiD7~0|Ce)=`1LLlku?%<@TgWP z{jjsbCW33No4Mtv`SW?p(Joe%_jPONb`-DryuaEhuQbOgGvDtjlF?;ToOE`M1$XDh zblsJGrr~Qx+wTL?=m_cDlbQLGT$s!BcNkQMo*Rkyej!P3RiEARlzmQsCxC0;Fi+CF zdz7T|q&l%2c3-0Ou<{YMwL42^*?4Pt`oq|P;VmAk^1`60B9!K0m)Jp4+ojhoLCP{v z38@Ip0#Wa=!8D8anr`!Ns`9CW+zZM6H>sqnachTmoQm38VrM(HAuw%{=s^*94CNQ_ zH4@weQYF(z;lS_|R;h|XD`qCUo4U)FQ%dVnDy-JTEOC|=c+Gfj+9sE`6|mCs`Hdl` z_Ln@~o2^}qeq<14Cz%JY8~5z73umPaW=Fjb?zXYhFE`B@3-}*0`~&|_%G0T2yBLy} zMwH5b1RS|@+ynag@B7~uczfN&fn#p*Y(w}TXvl|rCFaf{0f)zy@{ z5Hw+Y=o@=}7JbYX9dJw|2qfL9uI0zCmbaRVj&A}?S^kH`bm`jHyFlCM^ey_bm`C0f zBcKU}OPU;~j8rk)UB0cEHTU^3XYQ&OTi1NBH|@1rweRfX4z)x@^#6w%_>aCl@Bbsg z3HDzc3XGfGEO)(o3F`eS4`)eq-y)#<&s)E%!`ZhI^C>R&2p_+FhTqRPA01hnC)fBL8LKBgtHe`ocQ zXYv!7pEI5$M!XL$Z};PO32 zLpxWVLLDvJX!P4;XN0B@6ooJpYc>s#ZruQGukbf(5M2w?JwBO!w}J{Wc8?V5gUt!` z-F8@M%d6Ke6t*I20Hlt+uf=4UHDpd^D5YT|DO)vBXa6+$-Zla60l8gH2=&DE68BBL z#l=`-We*RJ#_dn*9agU5U(~XRq@^^NNL=}ca!tTHg=`o$$HXu$9!|m9=3B$M+7@rxWwj7^z^g!npcULBD$?=h7A0X^gv+I1>+Nf#FxBDSY4jVfIBtd z*qyuxhk;z;F$x^(V98HG6*zY7Nj2c7_9*nc4Wp#1!AKP$KP)~zTjB7si zjhg(m(3HSEKY}L+cl?!&!`ELbZtOyxI$(QJln@(P(N$#$qQyt_Wf#|32%(Gk` zuz4jON)&sIH0Tsw?Xk})a%QmsK)0W&fmDOh=4LxVX4UUy2+gV09=P zzQb`2eiumF9?t<5@XTwA@kNmpwmXXoua&m3PMflGr_B0!F26DoMXvZ1H>3oD!UJ$VsTBZJ6fNe*$SL#D)5 z8Cc^?pc78Bi!Tkv>96k`FCCY z|E}wIcKSpv>VFrNVrPFwlQQLe$V2_MjMaw4g8YP+|EzCJ`)U~-tyna>^9)4tw8xA&h&|JX7*GCy5M!S+^>_ev`vthrOl@4 zKg`9ki|>^HKj>+ssTyFkE5jIhx`#}mPw?XUIL8yyFjR-o|H zf-=0SxZPQqjU?1iABH^@luajHe()A?VNKBgJS>UD)~WY{+ngfvt3g*EMM7k8R7kxWBRT52xJM)QSJW9QLV4#hCtFznSd-C2IU6+fJr)V&` zr=ijFca7->{3B7TyVWujQ&%$RR3w$`?TudWa%~&r@&_g72O0I;c}3Md83r{MDbwWb zGK)=M#RW_&Wiy))^^+?ZNghDfNI3#(KXN$rg3&&00PM-H!>_zo2RtNS!mmPhrK(4B zkX!8cZdI(!Y`B1|)ug3Sy+4f+MxI5gPyTyNu7KhGr{Cs>()FjmRl?b%1YyMLl9Pa{ z{87OKYJ~hXZzlG9L!r1blo3ri{Wm=Et;W{ofA$e=SDYe{Mcw8S!fZ*gnyJn#WJn{i zi;8|Hc?|c3mxz~+8PNt1Ksv?cg;!m3{8^$RV4T_GD88gK7RMIZMg+kL9i?Oh0&}bl zb@&U)9lPHZegZAzWOY#qLQnfZ1=F~Yz>sKK`-<%pW$Oj{^8(RYz3{w3bXIo8e`q|T z&Gy)R@~@#$PB9i+MkN+qT>i%56z`^ZJJmcsQmngeXj#hY>QuT&^SWNMl%Pc1L#4n{M;_B(22nH=j=b(rWWksO^W~TV7SKT)pA8Mc*A^92rd2 zX0=@Dxn=Wxux8*`t7*8538B2V*6$gf?2`O1%Bi=+Ld)^O(obTEc$7ej3ISZeeKrox z5RfD?X023nd6SP7p;vKRR{ur3wZ7z1XO=d|xz*PjQE`Gv9{@GArQbt`%-fJ&Qu@=w z*%C~r%B}E02y7rT^KLR{^n!DE)wkyssZl2#4IU%@6 zQHZKii=GGS>a-R;3Be$zMX=OhlFMIM>O-qHQ4YAiua*I**^u|#?w%UyFjz6?(<3J! zj#5)ouiQi`&CQIXwCTOVZ;SnfR>c>-i!edJ>IO{v9?!ExpB~P)kI@9U_k_ERVla_! zL_aR4zs#+mT8Of|q-a;X;d(ZCsF6U&`Cv&D!6rab?q51fI z!*I!Ou`agK^1PzS$;ocl5?kx~HinF1FAXY(Z_B|kTI%LMj=}NyYFz8wvM^XS<``(x0E~E}Vb{6U-J%uCjR^f1LGLFl6FHDRN4LFw%>Q`;}Qekzn*9q+oEH#`0wzS^4a>=*tc11C+-q{0 zN2ix+Z&(63n@4tu6OVtiGFu9P{B&2zvzWDwpABBz_W!lw6~@pA_(H<}APR7BtGg8& zZ>`Q9ZV9NJ6FYI%R+GaA-v@ciJ37Hh`HN=(a1PRNsxOJf`>#JbN;C%7w2817CI3`W z8@ROHFx&41_*xF4t?leu&N#Ny>VK(#t-^iwhwRm#u*$7dN&BP_fc6mO5Pf{&Nxk;a ze~4TdNRR;P87|}fG!=5ssUPa7XG0Cr$!fnxwXf^YqUs1Dc5qyMMYzVI! z=^Di<`<}=^1?S{^#dzHPSZdQ?RrvtvF{64r=zqSSt)NX9eDr!v7I-)cc&viYls^f3 zDivRWz0?8b{)0FiWG+yf!p?VTwI&-9ko_D^ELM6g%>pAKb|;~3OQQMORbquce!X9Z zUafi>R?}aeT>sksQ)L(21^{Jk4DwKG-l02&r$k}xOFid6hBZYGrOWTKHqD#BQa6cZ zkb0rUC~6_-!i3%}dQz#?dp0ip*x}Tu$PiXq{h1{+cVOM^;e}j5iLOc{08=;7GvnhQ z80@KBx1}T{*CHgu?t2oMrrdR1$SEw<1H5Eqt*I2F;B(?v1@U?@sPo{UOzjuE--bI{ z3I2Vt1PsuU+`!>t*#{s|IR*ikirR=gV4M=g5&!arlS(DRwU7pIVm?6IB8ZmhTLo(1 z^74}hygrso7!rtDs{Cf<>qm|~1-Q|Vjn!5~T${)Ae!qj5IbWAQl-(*^RDFf}d0Z;I zBOxWlbA{3r?8bwuBMZEiP&U9YbR#U5+CA?@q~iCpJLl%O7pQ#+{5PYVnmXU4$Wlz{ zwMNxft0%^=_y7X+xI68YAmRbCsz+n`YIh5rUd)2GVY4LX)f(22KVvS+(qbl(d|TIN zv@?#MK#ej28k075ELCdhN0C2xxljPfWS+>XSxt}A6ogly{`hi1xKDeEcFm3JEGDD8 zGA%ibtY2rxvA8^%8|W;fSSaD{Eb5>yEdiGNG)Y94y9D0O@&bXL=4Et1XRw*Xn^)*q zZGL-#HmE@xSab`>K?OC&<7~5irIQDEz&=(unj>MCb*BbEA>}L2+mN||OaI||i}PUj zMR;xlk4X|*IOF1~hapz5>^>mWxP36B8TK&sjSZU;HKQm$=VWKUld}yF+_p|CEz~)= zv^#WN!2T?NTv6Nl%MVU z5FPgxJktnSeVq#9BJ-K%e^Kbnue+gRA_<>1?sdiNu}BFI+gUsGR9Kil=f_nk;-3Rl zd*P&7`=+@RJxxf6-KdzKjvwbgZre8mK+X8W5d^%%lvd-?g%S~!9RR|vQY*~67_m-& z2uzC0(RUVe&9hVJ-Dn`mgUmtX4KnL*R%8JZ(nH)W-)k?v;~Aq2<-9A78I`r7a{2?SS=vHW>V?@v<5Sa}5j3sijA%$v~YAPm2%EXgN* z5{;JyOns5QlN$)#LCM6r4tLksgHz71)-r9pTH@hblWu|U+h%A3UJ8@e@T%a7JqfWz z;zL9gaAmT5Eda@Jm7=WKf(L)$aHJ>abZX zx-=^Vf0rwQtDi7@h4)ovqm*3vp9HFlETSEoC z7f!!n{PdQG4|8jMd^2PLmgmzJvJCK55&TV<1CijTo=|m+92vnAKZCV`n{&6!^z$d~ zZhls}Wdl#6f%B|O#c61}Y3H%u*qn2|w~esVOQ{DOZLP&B;(IAsytq+DJmN1weP&MBI<&pN2vso$2(S)_TLe=D-p3^F{@2u^0_K(x#6imKn|gw*~F z-qrVHr276U;S#ML9pkQuq{~8qZ3J|Lv+1FsC`)&eVH!uk&r>I9Q^=?8r#QAk3@r$O zSS-4YSVMQbtYBr(ZT{_FLbgKb8r{s{^MJd#r+~d)9{H8bA^UtC-qBO~yAToeo^#?S z^8b*$s)(wn`ZEFW1DZh6U~=7PP*S71KG48|J{!64rCfl`CD`kgWGJK9VrK%Lizh?c z#R6iC%|GZa~BfLjAmKx5Z?j4$ZN5XGs1;3Fx>9 zh;J){P(_UyAkHRt17|C~bq#@nZhI>HX2r*q*$hF+%k(Rde$hHAl;`3H?6Tn#OzR}a zCn`LZOChtrauf7-c$L|ShvLW|aBJn%FjYDo$eM5*p-@BAYnpp z_+pwo3b?_WGCkd2sTMGgXYye$lv!T*Wl#Ol_&MkSoGiedx4*;?sP_T9K6t~2?W_VI zwVoOlU(CC5EI2X_wPPzOejGkx4rr1v+qa|sHHH{Pw-eZI_eJi0tP5n);GOZwHupSE zprPlo{<8efHBgHO3<YRK3p_nuOWr>m%1SH(057;wXoCR_>Gyp zbw~5By6Ppuc7D4_)}Vr$O@}PUAEd@A@L-p!pI-l`6YQ@~bu=K$xAD||Xek&_>ZAFu zHIZ*R{<)E?X6v#!#51j09V5tdU!&!G&Gn;jTK#CFk*5&2jfBZ>zfJaT_HZ4)%k zmNy9|fZ>EFidkHIAE`m%s6U&K1Ftjpj^*ckuF}{!O|me3F#k(GMZ*S2bM#a~t?w_r zc+92I-3?<_bahV%;XHtKarnAe(`&$DV~ByFbMMN=!ohFpmB!q*C|bk{0q@ zdF4*qGBeSe$43?CG@@X>qFpy9->1Gm1Ub#dh8SX)=-%wrwdCQ2&zoG5gH!_blq|B` zmOYozVnP;dsOw{$WxVeCPCqVn?1jb}|EU^Hr6T#7X1VOJSr_TyrwN}?!7^pkgB<3y zwu{{*wjE(s$q_7ZFCvJve3V-#pK%~RR0bwO$#r&#Ww8uS+jlI(w6mu|obvP)Igqpc z(+>P-UbBw?yy^Ef^2r`rwxodG(~83ZW1Qk7#7>i#a5(K~9HrVCoe#$nhXd5Ud7Xuq zaNPh^?!if&-oYZnC19%6fvM&ol)MSF$KzVomaC*V2g1EY3EM^g($=G)6h%p+cKtUO zTGD(R9W~%RHiMO;2KTTbZe}&H(-lI7p%-3~w1SDu|AMaMrHT%+PyXCJiT;DMLr;RS zZmX`WV9UdgjurtVdQ1aNPBdn-tn@m(>bl**Fn<)d4gIa8J*A30Xrrv_%97jVFls5R zZzZ{%W-)Al@sp4T8fk0pNkXlCp`8Y?d(6IElP906Ak=)4BmmSXLjo-3U8hK-Kc(W0 zzD~3Q%3K0kNH-CuPw61G*+Cnl;(%ulV0}(Uq~E4Ol{cpUG4IIf5AI4-$z)YBwC0-zVDcRQ>D?%bqjTlY9m1XCY&-doy!<1@*e;xGKv zhKtc~71Q7IQdqOY#-94Po@fz<-#~ptAt6Z7Z8@NMPnVxY{-@;BmFm$PqUSpJwjjS&wwlg<4w0%`v$9)+h(R<*OJ4Y`Nu?beQQRJ?>{? zV`J^3oq!)V==iBZnj<0&-*ksp2Y2$a9WID?0?xHgLz zN#W3DMrmoO+E+%${EeBi^R#+OO(ER_A>>`&~0~pF2xH@5uim37)kk+pr`He z=H}JF4}A;Fr^TTEf$r@kr2j(qp-hGo=nk%os^#4qQiP~5{Vc+3#nZZU@tL>ORnD8? zQ6DWXG^dz6O0=0Za6G5H0}3GtJ~EhXC`e6W$Untryu-KmU;O{xZ_;1D8@DEL|5N)u z@`5dSy{umq`Zs(GXYzT**9o{te_(&PjwmSETo9>yg9|cq_E15S0uUVe_%ewu zQ$ii2+0meQv@g+z`Dh!Ie~?{Qx~VFgH4UOC_4OLx0c4qzLI1wMtV@_zBs!(3e;mpP z@uyI9@`cMlw#Gj-3N`&kllo40Igw6vDz^}D!&Dwe2-SIub~%?LxUfR z@=r3RVOw$RV+R`X_nhA5dTkdj`nQ0Rt)E-J@&bZmi6NXbkYpnCZ6)%7XCkL1@U;a` z^{XxkamIAy@`@5oa=-~NI^GiQPP%BaBy4h1*!&qIfGR&fAq8TKt7Z7Jt0f;lqR1d8 zhnGm)!5^X;cOnlTPqnF~aZh=jcDEO+adF<4Y;9+wUMy3O%y_@aNNK24iDaTXHUh?M zOAr4T($6^Gj`g0%xmtp@5M^mwW+2OCbtBvY;U7szNRGGppwshYoh(HcK#E12CtEvp ziIJr6b=8997cFloyyJqxF0dK@eDt7XmCYEq)te$0b}qA<%I!a^(s$FZ(JpU3-K3lS z&aF(^sBNB+jha?WiEIoQR9R>X1`VURdwO~pB(}AW^)5fCRo6zqg)j<_#oiD#(5v`= zw=cDL?_`^@FX>y{sBS^K@1h!TSN!qD&G)lR}ELhm3y0V0g9lGHi*X%(7% zBrZ1rM{1_QU(v8jj4q*k`0cdDZtFH#@eEa(6t2?xEgw)hU+xQ7Ry(UGtMV(cddT+2 z$+{A5>;Rww73#~WK@0uEt3XCB^QAS|H*WSxjeHpvSD}StVm6euHr-^D>r;XyBDz+3 zmlqlo(roGspn?aRG_^lqtnko>(8y3HQ$&K>&z&Y#ETfUZD@{1xj6X@0iB5mp^1P+O zK1P|)Z^F`}{<-9u-2OIIwDDON`PfX`Cb!T%D^Sd_6u&UG0IieO`7Dxv1JWueSB{n( zBmG+{42n*L0_>TbXnP&-F0J*Nq)nh9$9lN3yjY8`LC=+amIvvVw~lt$4|~|NICw;7 zN1XB6y_C0IK(q$Q(LbG>A=WMode$2oCjW9j1FT`Wd~`pH&l0ADMK0Lm-spj)k>vjV z#))2632%6^#ZtJVbT|kAUfs!BonG~7eTk@UvID|zfXni*JM6h4-FK(33C~9E1?PfojPN4q_-qug5RSwgGph;yG$e86)`$-)- znj%0=3|iwD_D9dfhh~b(c6!!7@hV$legwgF|EwEhGH-uzanKe;WICyGwts&SHRTY( zB)Z-4UTy#lZYFd-|AEvDC^;UeU(o~A;#gb}t+%A+Pm!D4TV%K%&cOdjX|HM?B^%EI znQSX@2I$SQHD}0Mu*_w-1xbhOIzk2lv`L60^nPHIq5&$froXQm+_*P@w`5a0qjv#b zc`B8yhFFQ{vM62I-fqizk@3@Y;9=*U5WchI&WPwHQPrOx(}mRK_v7?a40EKB2UA0+i@fApjbAMHGRn$J^N^?N`CB18D&G$NgxU;NhVHfvV8b23qWWf14PCG zfr?#ht=VmCG|&YVg(W5ZBEy70nKls1` zwrE|w?{BZ5m}hDI41^2++hwY6({xlM01@$oXPbF*eK^_(ye1}@m!b{_e=WR-l z0kMApVq-F;0=j)#2dxZ1Ny3q5cDWaAJIhhaGa9Kk z7^)v2sbe(b&fM|l9~Flb^ITXUo0v`L(_Rq$k4r8S-?Hi^3%JDgEekzu?$L+K7x9>w z+1qXBbAc8zG{xz+PeUy_lQ~eF0eew>guJgUIoSJ7r6Nd;ISe(56n_S6=tiQ;VgM?s zwMCtN96%>QF`&b@TLw=7KEBSHB4$ZCw6X|yuV z`54A?pDT6B@RcS4Uz4CeI4L4VNTw1)=wbRnJVkdJrX!|Hha&mFavou+NP)v@mb%*a+-t8~x5Ei4F0!RB`5*1=j`)gewuPrH#y zbKe?;Y&4;gbNE-3mrIxq+JM_%&1wI;NXkIv3yg{bIVi`-U^(m#zxKQ0lS91zoz@)w zlFg4U;Ghud_T+6P{ffmLRwt^aqMb;b5Q~SlmbGTnjo7zTf{K!ftpLs?7+n3=xFpfJ z$zQ{{n$m7-R|utnGoBpn(NaWn1IzwY5M~8GpFo(4)E_KkgO$mZUCxXwo?k3r0@O#m z3UlYI{P>FrxE7Dc*XZ>7NT!T@ zbzbjzs~cI|bL!)(s6-#h!~<3lN$ajyPvem2&;3sN;fUB)M_x6k^BB472=+Ijjm_+= zQS&oL57~hpjnXUOpi<-E&8S9wS@^)zR2a}%<2*KmQvInwX8`22@zpyNP5n>{$!9mC zyr%ZXpBfe#+wZDEswzZe3u&mQYvm#t(DrbPwjxjucHEd~H_GqoFgE>z>(n0fMwqI2 z%z5wQ@OeNfz1DrHrBK_SpesNbMnqlgS7%aB64_jRc*1c=xQ89fA*gZs$Qy&dkjflh z^}BiAzI5xs^?M|Vl1;;LR1HxegATU$lUH(ug>tj-;Dnu&mYH01kT$Iq(0 z%=vBL7O2Lcgn3*i+Gv>KP!#uuC<;b>)*KtQTDV;ymsIS_Ry;Io{2!FTb~`nBqZKd; zpsMmFjNhDh{vvws6PAS7O|VRzza~fO4?B??HEqK%sfLYjXKI*oMg*JR0{l;YZepP6 zxo(Px$7r-zfXjK2(9#ui&_k+@3{eOIb>QiOJt6C$Zo?L!gm{*yo~u0bVEg>{ALQ>c z8wm%m)s7oS`P-H2SaRoD#bl;3DWlI!biQW?V@Jp9MQ-{zjLjEG3K>*l?hKfmAu^!uz2O8?$@>iv3rg!-4pa#Dt|7u4Xz|a82ZXR~Z6=u;J%w zQ^LG{sfP)1j$-n+2$)%EmQfmfvza~*sOL_h>YN>oHdnshWk zC<;i65PAYp5D^ej5b2;u5s)S|KoX^Q1jGOdL}`(hNJ|JI;jZ|;?>XOh&YySOG0qtG z@K2H*cJ|t9&-KhXpIO#i^_~Ub6k;6~`zb?_CW?1rK!$mZty`;>DqnZ;p&fKC?^82} zSQJuz{*C>H{l#kDEb2-{qUg5g_H+RqVw++zIE?dh z^=bpvKM(QH6hs?&H85i&SbFKCqsJDg{~XNS#t2swz9S_vwep4rn^1BlCyv^Y-pKO( z&ajKnaViOj#W)Knfz))Us8b14fp=3_X(kl3ju3u={sL*WnUqM&@aa6JsuiIC+%rXb1WsQV} zwHk#NqO=2`144`_2=+L2#Gk!=C8K0^*h~rKscy4sJxPyR-u~2a(YD*_B`^eDYl5s3 zQ`3y5OO=cmr=;4?*tDKgTy_@1{Hg~!I9)~`OmbWc&**H7aH>SuXarO}Kj{5c7zX+mbgo!XCN5V&0Q1lrL2hDz3w0UEp+Ze7Gk!8PX zCA-6lKd)agl1zBJwy=9g$>B-=^2cu9=0`Bxuv*~1Ke?tot`<~75J6bQNvot4#6c>ZJ{fqOt`>>9Q3fX~Y->{RD`b1-EFR&B z=tV=o2M{5;lQQN1X--|0gJRi7`oomG_}IT!@D>5PhMjDMK0GAItwcRN6mZ94GP9Nm zUkthFGCoh*q-e<6QDz`cKfV`?(f|frD;B>YtK;I5U%-?ZDuarCsxJP0@x)JVLQh@m z(GSlO-?!C{ZUR-FdMf|8nI2%G0Eqx@hv(+$$Ik{cuY74sm87(Ca#T%Y`=n zp{S6yxrH}6x%;}pKA*#<&3DBLe-sd54OU-&z{ZXC-zJ)z`MmJL>BQXkAE7a3XeDf| zM@H{PRZG@AXry;l#?hqHZhr4g7gu$qt`)4Q^bqyJ@u#GDcd+s<5x0+d#Q3nEHrlXw5M$jz&6>|| zI#A!43eEf=5Y$U`F;)YYj!1Eo1ZV8D&Rpi-x+dMN%r3~wlbp9e@LRzjG0>8n$v9Y# zD)|Feek{xX0q-DHSy_3GN~O2l#_VQRtCNpJXci3L8#a?}C~xJUgeNxTT6%xkWJ%$d zYHTPpO}zT7LA#WgYWLInlvhbPRzhs?4VJr#Yah+%O30AF&B~gZA`C{<s+aspl-u zzcws}|86Wd%OI~c%j?eesvG_86%TnAolte`^5h#y`of)6!b6DMLY z{ltQ`)~;&R#)jG2W>9WtvmjUCDJvsY0aeYK7sqxRZ`tdwrpHWJ@hP_;y=IarV#aSA zTc+`wRKc^h55Bpp_qbg)^+5+9;P@b=uvuEXIaJBWb}Ta8qMk&^k=Ia#)sS&l3h?#3 zKiEIW{NlL}d1m+Y1{!0fBIg6qNnUvDDTf7vd*$?f#mS5tl_13SkYCTcMJw+FzqmuH zwe@sWbUbTmId?|uWlar4Jnc+!!e-@ZMshX_<($xlXPd7Ms1>Yu+NndP)lDu$)Q!xH zxr<#|s%xRUzcnYw!Yj8_=8wBnOw@>5l9YB^Ehbrdx<87hAF{AEg&aw zF4FK?nMipuv{<&SkI;RrVE%(zT;_(D928?2BP>m=t@a<=&HVuC@vj&s=?(c%JD{Vg z5AV+D{M7FZ8CQTycRV9ta^JkK<#XjCu$M;k|Gsu1a1 zg$0h{!w`#s&_K@w0d>icEn)dNT1lvlyoN9<{jORccHm>Z+{IYU+Bh~~pKwQAw*8dX zL7SHdh>9r6UKv~YBWYo2={C|?rKjr8&}h&z{p8wLN_*L3S$8`2tUgvs`?D>!RO4z zU~G+W1si>jVNQ~`TC%GyCEBOHFoFCKjDY_^kj;q*jKA7QLXB?(CNy|| zHK7@QG~Li5x!z-X^ozkJ(Jnd7%WuKA1rr648j9{W*laVX`}O3OO40Pj13`~)6fpxH z)tG7EA-8Z&VBFdXj^p*?ymeIjxj|xWG?-Ipv7)Ls`=A?@E9EJ#R2h*`vWHXfS({xq z7w?Ye!Oo}W&adG$ScO6NXVl{npDyk~#!pywoDdQDMn<`$l&lk1D&Kh)ht_h^ZTy>r z#h5cMYC|>{XuAc>mA+9w(M!1wC=y}RvXb(4^&{=+1a^-Qtdx~>K=r8Og14EAlV6396BBw=qNY}=N*DBa7U<|TH%TI0i2t#g>K?`M$HqSN)_ zU3qs1MYjmI5*dQ-S+`Qiw{1w{IsV&3%mFNT#r2Z?Kqi15j& z7~ypPXnMnP$gj$ks=#ZT*zPc6$cNaX+tnS~j&^aeLwJ9?rnxz{{BJ$(E!d5X6NM!u zKeE=m7LdW?rha}^AkUO{LuA-yfqY0ksXoqRrs2+WmJ|X4c*NXcY$pTlon*%v;yZgl zh!&)2H!eU0f_+8DE5h{d-Pui)YQR!v{U6RKo}I~|&b3X_b%Jg1n_in$dKXA-x@Mb6 zRONpT8J#^xQo0#?EEh<*pRaGT;6knZdh3g$PHPdEv~wthBfN=@L*q+X@-DB#33Q$F{nRMtOXCk3Y@Wz3&=)n(h9 zv;3$Uvf)da1icwFs{MaUcgL0&C=hNf6j{C8x<{HUJJ%g+)!k?_*|`Kma2AuC94DH$ z+~df})d~z2z6?D9*&BheD{_)D;?zGdOYdq%&ml7mbTB7QoWNP{Qa{YBR^n=pkHsxyIKr1qu1JH;@Z${rQcm*_^LU4dRx|hE}U422{|kmXlcRH(5!(1aXw}tJQT%$#_t|B*sm?_lJ~?7 z_RK*_saXTO5ttkypCvFB*8XSE2OTlh;ezBf72z? z4|Ca9{7+Zk8!=AJd)U2e(w7o9ZWKI*9UZ~mi&x_doqyZ+rs|MAgF1Z1YRoAHN*6{jzDVn)^n>&oN(p^5Ms4<0{R85xP`R0dCm!jH4B4W14*t%M(j?AITu0n5psAxM zlC+Q@8&lM;%ph$K$tYQ`3->Ce-A4P_sQ{nY@rZ4?R^J=3Tm|}F!^RYZ)(M9t~EucM)5sh2`!E*w#%6d6F^eC0CtUy<@@I`MRE-o}<;CY2ewO*QQ|hT_e~?HCUzvyxXW7OWC)`Z`-o-4mAtV^h$Kg>yn+4j+*(FZr&#{7wAOwPu(?8m54g# zl;%?E*^k}I`o_k_c4{gye(Sm02wlZ|Es(;{#k@hIemg_M*orJ$TU+m4hD$nk`r3L5 zHpck8va*q4RG*n{cQ?06SI*h^H>=J&Y5)jP0>P~ni<7i;@EpIT8bXh4C1on8=U{%| z_v7K8&xvKKt6Dz7csz(n*CokRHx{1rMc_yN&`MsiS#RO&51chtK+YxxH1RI{^lA0{ zCs~1&3bW!FmuPwXMmX$B+qsow8@=GgCF`Z}sg8t%%tF`E>Dl}&OBpI%nNea~9BP~> zu9?~pY+IiY5Y2e}N2Vhh2|ziuu1?jpG&Es|0J|3wL0N88QQG6EiWgiItoYcbpO;(Z zIU%NT-oHO{3O^xs&N5k4(oWXAPD)KF1b2M-+~sbaZ#+KyiFH>Ad@Y%~BQUef>8j2L z7Ckn1lGDT)jEx7%h8@TWNLr&!2Q>;!;e=GV2+fF@P$xqb=1i>eG>y`78I1_ZynC*f z98QdHi0=6E<(^@t#$6!IZtm^~9^dXcHBC)Tqy9{&EHN^ zRNNY$?sI#1x9EXv0;9*^VjA*Qvr4)uJaZ-QGy@;gAwa*iRJ4n0cte%HPnuvl;)guD5l*Vy$yFf3T*{aj%KvBk?-MdjHl`bUahnh*T19Q}RJDt`UJ=+2MuYbkX zSSu*tp-Sx+4KPqM9avHW(aZN?+( z;^dEkfzuDmo~v30lBbW)SE%)gIw!WmIDd-jrlI=E4vjlCmwS%ZF(^>Pc!|g6s=M%P zW~A!umnS=dXWpOXdJ-41lw`fCntdHvLQu~>fsd(^nGcg}zniCw(gVM{g9;OX@ zo|>8PFi1O2<~?dj-)V}CAq!w$99O$o@-w%-9tuCd;c31sHoRQa9CoR+ZHH8722uxS z3NJO^%odZ63NNz)ogCV}-Jjq`L%}W&4c*;c6XBJw;F89A0)tu6>=k4@Pa@JkJ1PY_jaud<0{=9{obpjwo4ZhpvJg8;W6Yk?4?l7})v&`5WFf2l(Zr1cCdEF~U zv$Pk;pccpo3OZw}FWT3}gql_%kVs@SAy31=djOOcD?4|K=#@`21XR<8l1GoliYZ@@ z_uaga_0r$3sIc%h=mp-(ppDgAO}56$c2)Bw_AveREk4Q?8;_w3Vsc|67E(9r%1srWH6rRrV=`K(c9e(Jj(`uy$OVI57oBYPZrc(wtL z{YOnpYK)Lvv?SJFM@)q7?j3j6q{3+mt~7%Lt(Klxn+(dn7LZn^2g)N5v)i3qmJ>vXrPjh@}ficgZ)lNxy8 zWb0L^6geJsH(6FtK3rhtU~I=tOy8JYW2Ixs{Qz9hYCtJjLEcEPo3ev8I?Q_Fb4Ds$)M1ph_7V`V@EmWr%k{=3OLlU;n;Gk-a9i`5 zbF;JF(dURnq909Lc6AJom7H~_g}6pYsL3iV5^IdfTWexH25f;JpO;cMjjfu`1Th%+ z`VDWcIqjV=9>pHpohLn?68ZM`C_XkLj$g^catsMTu6K*E=0A_zItFPy-y+OTZo6}A z`uzSS$6jvg*fBMq9I(Yh36LMIN(7%ByVzPLnAeAZ@9D$8V(rIov7$uV1XrQT^vZf)hmWXYk!>j}cv`zVNLYH)43N za$laIMXI892^#$oOj+?L{auOs@lQLU%+`o|)eHZ~e)eo7!f|uk`y8=n^|MTXSt3JN zc*Ik3gtuz9cmfpmS0MM*lo6)M$iAKz*q!lkP?Z+=sLaTIV|7-KA?gz6ekZ^R zM%v;&%m+*3pA+4I=et0r>dI!R723^d=-P@?&wa6TQK?%#9$OeQHym{kc#7-lJ<-{A zoJGEX4z|Pzy*cWYf{Hff-@{Ssqlo~a+Nv@LiludR_qaBaG1j`$)ui&n2W=ode_gX7 zBX;2NZFe+uWJyX9{?xE~1K|;BUp>ArFB@yaTeoRhX&DXRKY$%*a=$-Y$As~vmSy|S znHarPUm=K(zaOjOU;Mgm_u>5}m;RFrVD;?$44qj}3%Hcjkr{RR6(T0vxeiq?wTr}> z$Vb)J$b0YFhe($LWmEnhUApDGzCG?BllHT@baz#ef|X29VJcS{lB)p_0TT08v>@#$cOk8%0W)|D%Q>NEdg<5@15}^olxITWSPM{CoC=H# zVDeZ%p+$g^;I1aXpl~gEkW2v%&Kvv&sn1HM^;*u4*0ZSf9{^0%`D_v-TI?bzs-e0t zW~bHaTv6$5Q&WdNE8Mc6=2m0CD%yx8JEYQVhlhx5VyHM4^|w=;rn3$jR<(FdFB%$= z|Ni|o;7;HByn0m5_F`>Ve|&DAL`d=7*9EqGbC#MG6UBY8voz{yF~lZo5=StlGvvoA z@0orI>{Hm~MdgGJ^)S}y%J{h%PVP>h$i*vGE z{HAq{2QIZ0`RYJI&0w%nApKI4E+IZ~Z{?tQeIZnY_ybg#H4Tx)O1BIAwQJ0G(D2GK zT|m#LB)}t8_>xnkc3(ifA6%>b4MQpmb@6nByTMY2RMrcUKhe`94Urz5!qD5?GK9s& zLiP&NG+4U9;c&+J3kXQ#kcf!L zBTh)RQubgXHa@4%_K$IVj{F$z-hfUo(`$LE;}~Gsa`q)aWZsCLf1#vuESimy92r8;a_E zJ)rAXPpvNa`0al#aYu-gTe2hLA

      QVlV@cXn+nWq!Gpppe(hEhDxM4X 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

      7)#NL1>|xcg)XJ{UOIeKJws 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 XvAYx{)vlz2du>@MCCOs(*YExh%WMKP literal 664161 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

      |FHIT$ z%^P^Y^ZlkJvnh&=6Qdanc(wI2Kn3u^L0lr=&6^+8^R2}>Hb9#nZe|AQ!QppOSo^ZX zXo{t!l|z*a!={~%|FtZq<$kZ99enfqw4H=kgSX_^>L~}hKky3xd=XyuEe44Hm=i0* zG;$%&-;Vd(_io<-C%fj&5U;s;37S86k4waD2bxf+xNk(dCAc0y_BHt~rnw&-^V{yv z4~Cmc6An+LaiYWfo#L^XI}6@i_Fx6W1H=v`1RwrE$G?t#Xhr8hl+SrD<49eXrHU+K z<=fo`cWJV?=;2s$AB***Hh zJQ*|_{joLx&ikhPDK&xz#PW#kOQzDTx6clQ7b*JECiXjR3O^w5kH$t#!?XF`um=Jc zqc@w_U)ni*7hX5sIm$n)TymQ0o}!!>omX#wxP+vwv~T3XJQ3Z#D2IDLo~2QkKp#&H zG^g2Mx&R%2cKZ0;jHJ&udjX4JtXNGtC1nHT6uz}{-=&y-_;Rm^8X?pv00wnA-n-@J zvv>hJ(3kb?HG7@1;Wvn%-bZDLBWYftQytd@6ceM!#+U8SpS#X%@Hq=wIc9L)=7XXL zJ`38@WGq;3+nUIkM>dYlz}G8dbP02p4d&W!qZ)@riU+c z_Gg)?PqYZe$R;s7zxS680Wc0<(I5C97#DBUfiR)Hv%;I3gQs*n5e*i?$AbnXvY)Bf z9ry}8VK^Tf#cojNV&sx*zt~{H5lU`f7N2+|m)hNv8Zo}DwE-~yJ2h|Il8nnXrW55H?0SaybTk;LsJJJc<;lzzpn(2K9DDnG$+^n1?geny zH15nqI=Q;4;l+EHzd{Rslb<>Ti^hemo9#45gT35s+AS6<(#^b%)&c%6lS z+vE6DeFlF4jyCN`22-cs>;1Q?>gt|mENsZ7vC4j)!8n~7`gQe@7N6mU18!`U7AdWJjjAR?DSvF0*-+#dwzdrBGrKY0@zi;mW{7Ku_cgT5FqM+MEKbS z^ONqHH3T@pg+N^`QTDtOvA(WeS6Py(e;5c2=H92GvHq*TEqSMY-!|dvf-v(8$Ysh(t;Z+ln8aks0XT8_;+xlf$DvT^5%N>x*M)jZpY_lAH%_mvDGVI7gCZ37{x>CZOqF`$3fvS6XULi9B zynRlISJ7)yK{@EkdIPLKz3VqhDvrun!jO%w z-{F=;t^w1($OZJnChYV{T70R?6nE=G&Tll2+rN_-tu3QFiI%rHtR54hmT<#G>p%}Y zn^oi=o6>ucRUq^y$msBJ=6?A&N#Wz$#5AioeLcd)Xd}HLMp;XyC(BCo=b)-G4WLgj ztkN@PaPLqFe0jeMl!3+`Aa?8>F~R;7(6d5EOZ^#d5&U$Lf|mf|EI|!91nH!z?s+5) zz6Lb3(JJSQ04<-PqHKI+|3cYD9V&h_`CUlB|9OZRMF_vvFF_=;$Hfa#n`!tgI$9Ah(L&f^_>KP6gHON!!P%a4AZS7 z2OQwmm22$r+zl(+l$FpgH+dxjHfvxGTCF{StEVqT7NhJ~rCu7K>>ddWeX8kmUBr9| zdV&a%j57lDu%?F+$lMvJhLIvTm+8k}#NWT0K${A+=P=YAl8K}N4UyZa-5s+Vqm=oL zjc0T65u%Ej!Z&jP55zRa^2+-g;mqDdBCg&#b0VGrQ~P>rvPHJ0eEv!O1&fX$iCanC z{7IeP&&XkFY6Mcdmy>Y&`HK59%)}{Q0&1~Qa6VgZ{Z4wihgHuP(mDfWiFxmgqp|+Q zGu2ha73IvSt}clMe0ld*L);Y$*1Ov;ouWtYM^9FinG@aXy=rpe#CCd7zsG<5$_omA zX9le5<;BHYXDT4t`SEL$C^WOH(F54C9t7S+vg8%M#Gq$L2f>~18NBM`T(J(BIx5yl zNv__pUoFv2Q?#2z>`u)~s%^N+iOa|ok0i4CKN9X_Kjp>2#bpT6r5A{%`mQ-N;TIR3 z#t7zvDN|ULIDLJntE=JEqWwW+|J`&8Wn&Y!M8CY{MI5>HX zbBg^a?5X%*0A`TZg<_!YjJTHL?EbR zkH63#bPrReU2LGf;b$>X?W*tSSeVmaG=E0tEw{ACJsquR;>N~#1w}qO zB|cKqM#R)X@0fG{=8(P)`%Rq;aiBdq1EhvjN!IPx`q5s$vy2vIp3p&P7#~A!ZEbxz z92x5_Huz*UqJPA#H&yHlOi0erQ5DASTU8^FAXehwWUWz` zI`ZgRbV_EX@wE@SD$=EoZ{&c#2oDng>b?1DD|^A&VgzPb=}8iToGt>MTxV}@gOf~G z$|G+fN66L3kg?ltAvnHk(a_3>WB6g(;q{OsO54gxDPY=(OGxA!T+MBD=aQ?3yr+y6In3eUui;X2&?Pr=~<=_ zj<7c20UC5jS1F#62YFA{cXl=EFX&E{CtGHFQr722Y9@9GdcjS;5nAA&*Y}N)p0vZz z)5Wr|hQh*j3uLthQ7%FKc7hlfw7%H(1vf&72t4SplKfszM!(o#8A-N8wxLqL4;##y zH(`BG%Bym5CYlrSLyVo7r~D(Gr?LXKe}-Ze<>Q%kn3!2sGeM#{6Uh?%1!K44a%klQ z#e4H3HO0lMYp3huRgr9G27nldF1Zu%Sv85OWGeyhp1W| z+5O4kdgly<4p3#{5sI{HR8+_zS0PcL57jL6h9N2e+V-L)YhbC0udPj7TDk}zpjvOE zzb|avK6lC~IM@=ffhIy0jI4OL2bgmz&-k4^s7cN-<}5sYyRe03NOSN=Nt z3{>1W5adoG+}RFWEJa*IyhA^?NQZLu4Robp+CNe z*E06wr2p-(RraM2NJ#{jtJCv){?U5^X$D<8CaPZ1C4PT`)~=TzH}v zan0+ALb-3II zOJaOOPmI^h7ayENCeIu3>fh$&Oc6itJTyCd9UL>hTQPA1BBOm|pi&fDStXdidkjT% z21AT?PAO<>YkQhf0Cda*_54d`!o?*e3&1=NTyMf3b^(&drA5V}4RXYrvfU`uBRSud zJ|UjHSHLR_CkoYklk!$0S;j2$-Ap8nk4VC*0GZ%((@(HAL)-giJXFS9Q%Ir9O5Use zzRT`oeWXS(+xN8(gvgO)3OgzlbMpWV37NW~xA<{kD?q}`*h)M`qc}B9w+Vlp(8oI! z&?y8YAf9?bpS977#ch-WmWF1n>MGZ$;K+$P3$)8EsbHf!3~pMK-m_d&e!Vqc8&A0U zu+g&kPJM5{TTGMDP3_FP+=r8pd2Gy7!SmhexUtL-**uZEg(}&vIGPmO@7ODLJBaP5 zLH%4FJWnK6?b_88AFYS{8jp+LF)=9i&4DgYqCB8_9qNVJ>HKoyk3p3rz4bKXKzlxn zAnXbmG(-OBRYJZJ5EvL8xz^a)C^-Bp&Y%)A21K zN;HBp7xQ%}vj;7prPenW%d$zjG|_;ivF2ucaywr7|9O8p2kJ*I}R?&YqdkT8EZf09Lco-jWX5+uR~& zFsG_36q!4Wn>dE-T+QMax&k=CUdz+>rQSm;6Xc52jqx=sx(OY=y6MF~$v*T3HE{3I z)}AD$6K_~1OQPNX)$YjrBey9e74A})6d&Q(<|pJK+(ovEnK$Aw8uWeHSbX=n)pN12e(rL9?+* z_1J0?u$P=PKnZ^b`BvuxeAIlVpYr=Q{+yIbhETk>x}}J(0~OszBqaG2SNmowD+5HICEk<@0S?8EJ3AcKN~q?vaefU`NMkA zON&mjs3RZ>fq(-}mLfI&GgSa`EOK=-a_7}2lMi84s5_JE4lhSj3U0!!G)f%kPm+FQ zr?QqNqpCA@fh_UGt9pwnI^qf?7r+qs`Q3s5Mn_81;1HnW1ZufY^J8`*_h-a8I7ze;RQZ3#dR*d>9fF_`?e z{zY~Ug`O?$bhksLeT*q`#%#$`Mo!&w5~KgRGl>*A;p-G=BO@=XU}`|Ha_v$Ix_ja5 zB0*c*IoLhPdxndGDPu5jo2WK;l>^GkQBw$YkBylE2_Am`DsS8#AJgFAAXMk(oNE^z z1=pOavx^Mw#}}3<1YXKa@2}e{;#S%Ud$S%h()oJO@vX?z#%=xBYPk0z8v-FaI)xhD z&TBf`Xo(K8yUwwDa`ozLSWA$JzmJcRVy63dB2U6(j5&k_MP56i@ThgH=f-`{+YiQ# zk53GbehfL~1CF~Mezm-Hru?bHD$d`N9~X0bRTP3M4Sc>DI}P+zh3lryZbm>@g1Q9* zK)@9O!W2-OiJ!w6#w#6TfUq07BbR&763{f&kKABj6IWEU?B4^Fk-O=wVde`dyC*g$ z%+UA}W2-=|NVi&LGyt^7W!x{lA$cnYX2vjR%M;xM8VCig}K(S zab9O1hliwCw<3ljk!SFB1)|N*&Lk0H`xu#VBF3Du&Qn+*p`ZZq7Iv<9=UnQXo}S!a zrm4=sJ+yEJ&*6|_PWmbm+`nI<`p}O2`KFRhgaS8({L(8~md+)FM*u4_F*#`=(Y{O* z8eKCJvy>){014kS*NtqrvV2&59uWO!0zW-A4Tr0&{HdcYgIcIJ=+w~@S~!g) z=?RfsySJ!f_1<4uzfBGw44%n0qaB{2jp1m*<`BZ$H>ILbg~gNPu>~FV-jd>CH5(l) zRwrH7-oy%29ZQ=+3?6Z$OZ^uYfT^f0C#vbGDx(!v5M+uSa(z~;9YxjA2e+U0GyeAE z;+_QJOZ((-!P0l$Bz@-v18^f|I+LVaEfb@dkp4YDMG8Z5E>D~(@~NsJeg$NL`eg5jX;*d7kbP{tkXzTZTg5 zN~#tRV+F%A-Ss{~*$38e6M1rXdxGKvGj7f$OxKvB6?YZb*(juqm=FtU1vo;G zSN|@7j3NvuDemC|9D~M#bp(dI3Y84Dk7Bo5n1gj=SKKZn4eqUu?MA05CO#I}(|NZD zu%nTSyFt@c*u#C8Rmq|RzvIoM>mMHG4>~tgKCS(24^Pz0*Yj~)gc8eZIS~CtJ-u`2 z{I@SZ`+WR5#Y%k&oJ6!nccMwAZ0B<>N

      Ad0H>>dXSx>$Er*v8JzQy#4+<_$95~YUnJUwJS_Ugj&!Ce zV(~SR|K-mz_QzIzWT0#4j?IsIX#e*JKuz&0XZf>k`Yi<_35)`B?g+q=$*@g6<3+ZOYvxPN)OcJ z6X`ZvMc`Wi&OkN zBi+OP-&!a@D^0}9J$_loWcHQSr)jkTR$nr1p<)OwgYL^jm9NFX?59CzTXgSBD+Vlh zyc!5W-m4~d)&>kHl(#K^Ye)&ZqDxED*p^;M-VPabIUKbJ(ELBstEv1q+ckBUW;j{y zuK2sVyLrKlhh7U&6k?%s>DGO3WRAN_V z{&|vZvhvlWgE*(C{|q~oAR6I+9!UUrq?VE@Sjg}u+S2*6gIQDV+jwpNN_jCb3mSt+ z9Wb!0BrNGnv9m>fQqotlCD4pzq`wkf(TmVLDIWd40XmQ+z?r>Vpp0eLFK#(G7pc=x zU?9Xo6&B5Q|0ttqw6pic_i|Vul`3O!*8{VjP?j9X<%aD1G(RO#kfEE__xFQ{`t0;F z)$52VeHxTH9=Os`dpfL~Dttpvv1>D<+4j6_vL|_P7YO5_LoOBOWqLNb z#SxS%9_Ikz@Dwiga@FPSU!}3fdkn4|*w4-OUYVw}ZQHfh8ZXld?ak6+Z+ZR{5$@rl z+&~hXu*v=vlzFh~y_bv3Nv$Qmcrnl+O&AUJ@Y|nK6`P_pJj(EWLfuOH&fgi{Hm6K` z`>E$%r62v%15cX_`*E7E9R^M`t@F*}3oB@hNZOPU56VxW^#@+MZt+^bT_~YUJ^>-W zlBgZEX%9KM*emRSZez@;lf}M|Q9YhA{mg&>V}8A416_pt|1qmo_@yOjTc$oPv`eXF_Txv?Q`?oVWU%41Fzc5Yd5OeRP7mL=GxwD|z zwZCKQy!T#yOIzhCtGt>T>Q%*gEO27Qi+Av^WMN}~#*QP{iQaN!Rbl?snY zq3qPADXr#uuX6+(VrwE#f-1JyY1vFus$P_7>*qgDQ8c~|<{;Cv%YdJZ&t!HV1vTLox z!GSMXw2TrtMld(SR6JV3j$%s4eUP|jU-y3h#Y_1mR`-&wiaK11nT=ZJy$caE$CqFJHFVB1CvZMBudY@1Dgmm+ak$ie@mV z4+)7l3^{DxZct?`OwpU$GRtJqt_`zs<+Ql+#l;h3R7k5*_QLn8W(!Nc-B4fLAP6r+ z4m|iS#1Fr5Z{*qef^DB{W~KE*pSd(1-ipQ4Y)UoWm*nbuIk7Y0P8?rD2|#zR!`hKI z$0r>9fBObrad82)?Rk$q>}2!Df4Oy1%$a!<2>LT|+(t9S8K#QqosFR3F;h368ud3z zd`TIP7Hjbs`{|>+_D#;~6P682A33ilGyIMoKQEzI`^y&?W6DhqMPIoO(9|o8W#7<0 zBhh_wMvTu*?^Kf`+xvD|=BWKOGSt(TCU)4g3u#Zbg7g^2M?iLEM8)rYc-`*(S_uvB zMB8t@GN=0QYUFcLm}*avH%+I7+9;PR`>?IUV=1l6m74yezp*Ud)1USZ_lX&Uu`T3Vkf5d3+iTao;QBUW9E(=0k+037(|*dTKr;USJxSnBV#8{@Cs@B01LM$qYn@4abo>t`n8dhbiq^(vhTt&j5Z z;crw~Lqep?$&EWH=sy6tCbWs`JT!i{PLp*d>d#SPp+Un4=(d6M3o@w+HPa6O*(?c? zkd-C9SQ+DcziK@srq_R-z$bb-@p^AoJ+*KgD|24CyhP9V3ZEubNZ!kL16jK1kW(b} ziU3>2PZ72U*LtUuX~Ma~MW(0#T6v{ux9`_jD^L$Vx@`5rCFB!;U}mMVWC`MbmOu89 z{Ze^4qF%HWV+mPBdh{b8vCqT8hrc{NYC1jx3sJ=$T^%X;UY%^T01_tX9~NYq@@s0q zMCodA#(agf0Vu~YBmI05O~qi{=6L2OR|%U%6QY68S=dJIgPet1Wh^ihs%rWZ%tw98 z#ST>C?eAp?>oeqraM77c*xdibKWdSM4Zk@mv6&2S!z0hLp4 zG2yllsWS5X(EypU_3rJHq}QEH%PhF2L!8x)XJP6x7m!j52m_@=Hurgf%@eJsspDs@ zf=DrjB5m2wQ{PBS_${XCaBSP1&5ByKH&@y|tbyxFI87O%_3O*(_NA|To@&TNY|#Ajvb36~c|7DR70 zKJmFx`rPR?em3=Ty7pb4TAn5po;DmZP)-zobE@2?++*#Uvq&2i;t;VbS^^w&ohuj*%2u<1%C2}k4kEr~S*-kn zR>U)Lne(fe_H9KCyD&bB(bYX@5aK&CEW-KA9(rvW0``6I3gWbJsP_`$)$L*j!!eqz zs^U698b@b$@t-dbCmB$O9nRqF>)pb?2|BIRiLPLkI#Fa`T%GeE0@wTMg@}sF%jxMc zuXNhl4GiB6^Jj&BFlD5p3-ZFdEr{~*m5NMSUJa3%v#9UfJgaVUMVp=dbcsaePqF`P z_2C6qZy)rTJozV|y~Q8s69xbq+af6Pyb#-<*{9tZ>Vk=@L-i$KpqNK}nsUoJC}Pzs zfb|XY#2JRS&QrB%)Y_DT?5a8e^QCzG%RdH>tQ|V}MhtMzePUb~TAs=~iDd1)W}_41 zNu(C>codhN)|)-XovFm6niK;ht<9D=K`4X%73yuw->V=2Hnv&BheXEL!fmMaGC@ka zv2E78sR|Ye1-!o9#u2S89nV1B^4Gy!d{Fl_T+5rv3KZ7@mRe%-)zJF2^)ouMnNCXD zb0*;5%`?mw5iKZw7teYsGRO`s<=z z)2Y0om0u)R1^+{GcptZ#)T=lB3hBHb(nLJ$74>*S;P}dpC51vvjl2zTFE5e5{kvhz z$wxh5NUSh<+)Xg^)35DmH*EHEf*StS@D3F$;7a}u)HkRiR&-}}njq*6!mn=aj*>!5 z+`$QJtMgh`XmRC45L2z~)@v*w%SKl&kL^~7I;CnI2C4%s(*#OT<52; zBLt;%sOEl{17GLY>yU;|X^JE*y!5{ix<8&6$Med25c*)rMt!=@VOCQUC2nauT21Oy zofhn|2creaefZRUZYLXK>mj>i=t}hfVd8MM%91_ZtFn~Tuc>#HYkQEMTwQQ;y90+NSc*Q}*M|mJ z?<+qDWv0&Nq#$&Dd=H(@e`;O5EkC+*8bwbwr zp*@sY9D(^CbUmqb}!n0+i5-3{5aL;dQYuLpN%Qu1zkbjXU zcuFE?8W_0ZSOI-wCLqJ61RAlMT2mM!qy87@9lQ~)xb5-5idyw;$Ips)WjsHoidWH= z22D^z`yMV-AT_2+sZl3@6LGWfw+;hRcHZb|3r5dmaRU-fZ|$A*POW(@6Hld$R*Q25N6f6OzHCPqJH%H&%GGBU+Wtcn4eU4bC&48-qVeeV``{ zf6>paTR~Ex6`A+DZCbQ|*ZiJZ*>P6ZMafYp0lxF&JoSc}PX_DS59QnPj4eAsTO~i_ z%!HYY(0q160g1b8kP zK+sv}U4PDnm)9$KI3!2j!TWIl$6|XlE{C#N2*IfGrrA~ejX0_C{7hcsEc!Ew zcac$$}a*(=>Ns3DXbewRvRpMb< z7Hsq0?$+%BOLS|?Zhn3bYoxe*fh=O?E?zG98+~rX8%2sLsu+%BR;>lzZ48E2AFS$x zPbqNl%ie!BNu|6|=*l!+>LjOqgZsf=HQaVmK1_GKnYz(+D_|F29%3<+3C7b)5pr47 zTJT&|jBx+$7RJhOy>|Pp)}miKTAWDdbK_pNN74ZQ0`qHKMO|mv%y#EF53+Y&lkOxE zE`Du&KC@zoH`}j;z9&`Ev6RuSuV-vcxS{`C&)D%Rhjc!yXl=r{#=z2*J0-AadkYp# zEIQri#@7Db)c{|7mp{sh$c@Yxv}`|&S1omlz0=Z-1kG}U zVk}4Zsb7>0%UJk!pzv=`>0SB_J?-JxaZLj7z@IV_+Kvq`V zw+o#uzCTY}^=#PKJR6dzj{8RT+!3RUdEWPpZ96WCr6WU&7_53n-Kp2zw>|5HwBTnk z3YQ7&^fu5g>GFy2w!o#C*8Lp|AfbvG{0WNao2Hi+ zJp<#)*_GgS-Et!pKcKW){xwzkGJzlRL-=pb*z~2Z$kliulk_-7>{fYwMc*Uotx1eW zm)1i?Y9*QmMC(-@g1?b^K0Y5kiuqT&MJSFmTTWk~{;tEfTLKkG$u>FXKx4MMLd8AZBo_Qn`ZFGW)u!=p^nO=%V&0P*PC{rLX@Z zrE7TS#z03+f1*HZ?)1#`FHEo9t-||{XEb-MYi*5McH9cL5g;%P1yC(L2jNMl^cr0?lo5{UrI+-ctPzLa_ zf9@&CF;Ue0`gJ&*uAKxaeO>0R1Jut*VEt0eW>>At~ILcVY(QI=sZ9)Gb9iTC305Z`im*4f*v|? zf^n@z|J1GqDe}{8+4tnq^z#75OV;i}&Wlh{Pju44VDv6-Oq(?~*NJ*mNkUWQebayl zqt^^?@$%q-3?kts7c}Le#0d&h>858A3An1OE-zpSXQGui+!s zUl^_GzxI)o_DlMm>%NrfvBYnLmI@C??SHg}oeRpVe@v+T`5U$5fV-$EX zsKq7e{?ne@L6BDB2Z)qj*~IIx-+MtaHQ!lMs7s@71q zl)lGxJy`%>RGl?9k8o#md`3WbREJRyR~Hc1xB-ze1YE=`3E#uR+*%vQWn8`4#&oG+ z^MLlBp1gNqxDC<9q@v%>6AXFt$N3waC3(trH>EXruV$7~qqM=3wL28l&kW3ov8J4)8x1F!FI7(nB1)Ar)K{3dQ9W|{gsBK06zGaLwFaZTQCOwwE zBKlT8*kM=Sx+kKBv+c>i$LLl(dk#NBPf1Q(dW3mhp|u^CPvFWFQSi-z9WK6I9m6rv z`o4HTLjr;WK8$WTyY~A$#=BU2djo>GdPVWgtJuH{vw6c;vMEP)9`D)gTTR&KMG(gh zQwAn4`Xdk?)?I&QDg>syqqEE#Gaay>=^zG*U3?9S?}H*;wWkj}_K& z?V~Ibv;HoDQDtfc>7UfGun$nBtk-W?U(mIn?Yd}FgL`cpeWC1_)1TkHTgOwOzuba< z*?q}Vout=LTcQ)RC6G^c##TFoq71*TNyxG?alJ2-%i#<)()5`hR+6mZs*6ZnH@Z{8 zCUV7-{{EPdaUoEsEtv9CS3)%H$!P^G3y(od>FgA_iF}}e_&!^=?G4T+)oOZrd~9@- zhZfVvIol-J-aUr9?LZ^Wq~o<;HFo(Ki(LtE0r1WDKh>5UM4}$ovx?18>0JJ0p2V5{ zTomU`;nT-Y@Eq;?{Tuit6|xP&sC(o8*t@9j^&hJO=pSX1~?{q2z#CQq{{ zv^7F{CdB0H$HM?qJ`xVU)34TJ1s^_g+gYi9>28sJ@w$YF$9vFXHM>4DZYq{KMsa@X z?1L`|Gf(e_Tw99)7Q4G2mUu7plqkCs5jAON0iT}v)cl-x6hMuQ=L-XSH@b?*!kj~@ zvX6JaD>;^xVaLL7Ne(rH4Aa(D++;Y6Fk5tqCw0_@-+zs*$Vi&}gCF(`8qNGn+Rf;^ zj7{15TlPdQvM9g+Kz}QVkN(I9k_j}902;AbL_QAckaJ3-y2$9cxarw-P;1uMSXy{x zB=!}CHEMR-jv}4j>Wvf7G6)63Da#Ue_)scI73g&mx8r<0p%;5@q7v0%LbTMN2&Adv zJR*7X0YfIO(}vzZeyT-5<`?qk&+vRyn_73m)f*Y*Z*34)Y}WJ?<%wtQ-{+9H!9m2& z58mdFI-WO?9)jyD0NL(BaAw&!c;9zP`M9fZu3_06_Ap;3#hFY!$sfTwpmhH0b7 zi`FBhIou@ag>Ku3}FLqv9*GI8qdp51M z&FUCgmOQ~a$`z16FkCfe#sTKsX4Ncn=p}{jhYw!)2HlL7j6^^#PGC*1CDo3XZyY-a zjOtx%vQ}M2_qr`bClCwIMFOS>axl#dD?pKNIVgi3yTuGYHeLGWcTt%WDYtKV1p`T3 zj-d6K#)>cQ%{8WfQ7?Kk$dzlcQIPU|C+B^rN?Wo7+#jCig0OOTE5n=Y&#C&yJ@6Zq zhqq$(`#V_q0HfZWuYWqs?e2DOw$$e!yHYMej+q!mqfsAs&VBD~7!WtuKG(Lo7+m*t zsxtgy)BA!oEK_TmoyvAnb__k)0cTEszR=g>&tJ+s zp4#i9t2-1OYI4KA!?ENspE0w5p9PN1Tbk${-VT=9RDH_z6tkC7eL?j!P+X}V_hiwGw-J8^WBsdU z+RQOokykUTzrMTg*V=#F&G6%A?d+tgH>vSo-7Ppbojju}rD(g#;z zCI~iBHCFScVgpqBpzB(>s5!s_+9_FWILZ-=q#BJ<+IiqL|3g{R_f{0k-j(T%3MhKx zoPbY9fD1)st0_8{VHB(s$tH{*m3WtumYkWTsQ(!)RZJL5MI@e6g7jyO*QTmchi$`- z6E{ixl5B|~9BRDl+5bS3dR6k1Hwb$$WVT@3>7KF#T4Q*?WnQ{^mI4XRsP&znChcv7 z{Ie0p7mDvoHVjN`R%6;?{<8rS96mG{umUbsu`3h?*N?PJoKzH}a74HqZe=aA+b;a{KU;6FAUF^y zN}`eDyZL0ijZaEQi({DN+b~cc?ZntEhlwM*p!41dgdsp=>an7=w5rtrXle&>_+D+6 z>IZ8aCLL?zp&3hXU46wrTL=kO)MF9vA?{mPF?1ZHxBr&uZH4Q!$ennwmFPzV5{{4f zNN=(BTpVt{c1uE4_o9MFc1_JSVMWse1_Ylf^w#WrR=j{Ch6OOzo=w>H@HH?z@DP8} z=CT0^=`MF1t;z*FWQK29?Kc{^K+`ksigq_*XO}9zUbkhG)A2PaeiFJ020*H@_`PPb z;^RtDlAt#-I}^0qhXaVs)?JPlSW7O6M)YR3sDip(_!9_C6$vZRl4KRF7;S2(sCMs5 zG+D)hR9wcVI0=2V>z9RzSccSB{xc|B>gyJ8QKm-lxla-U-4U6Z4tKfh?hmsZaaOEE zXGjzaH3}s{OeyK?WvPg-2CZBY=x}3L!6^1=gA4k?4E6H$6|_cIGWi({Yrs7|8Xbzj zxoyV%1_9Nif5=LigeU4VLB{COT=?I~$$`gi`(1nyu8h- zCujag3ROoSjc%yq6L}>qCU)rW08I^eW+XXE4R~L7B4KThtkLrp%M^szD9Kyewr3~( z;rm;hU$%eCQ2vG$V`}!Hoc2^mE4hSp2lif99gks8b4Hr>DY)q;~~F4yT*NM_HuSqR9I@7Kwy?07HR zg>^g>cdq{x&7L2M_=wZW&4I6;&W`3&pcAVGK4+QMsYT9<-YgxC<*r}K5e-r69jYgW zJ6u+n|I9YBw+Fq5X<5-78hCU5`_%;|;pG8Q*!OnGveu+OwO&`NlTgqNxG&a8f3@n^ zlLvpJMdQJJymcHgxmTlxOw?%h_y)is-5x&?7VM_}=+QglMM5K7%zE?w9_0*_{>4~tF)l`RaDBlfviqYrKQ zPx83=@3JHR%nQ?d=7~wT{C0Fd>Pa5l!#(TdPPnnJan@QcqCi>~4$vz~J@Wo)XjkdS zd-Zr(Y&SQ?%s^55Jy=6Y5V&r3T2ng)J=MUES5wzoYtMQ{{Ky%rB9?~vCVFngBK;0n zZ}SyqX`v6yoRh%nHR047&G+JlX>=m&`<24IqS=(IFJolfh->dA{f8Heww;?&f^K-T zelHKKCI4*Q5ngJPlHu+abuBaWqSPTUsLnnd*t+9|1!I1$8itz5FqVtutK=|VvG5)+ z&1h8)?cQuDlSvi|zo(`u9j!7pP~e)zMk*D3gVWZplK1edM zy(I1Iu*=ollS}q1cARw}^lmz3fHd15Z*^lzb}6tMRVY%{^HEB(Y2O`^W4f(P#K_7k zN>(l=6{|SaUC|sRn;*(54jO5>|2$7)$*HYy=|HBvqvw2j%R-9y`3BOMLQJRPc;T7l zzTttA$T5cZTJ-4FaVnb6^VEy@-=pNT@pi_{&lZFGr1?UEZ?@6GN+xRAy1A9Z=dl4} zcG+nWg4hL)zNehAfVz~f96Gw(x_i*c1&pH_Zc~^3rWh09?Cog^Up-V41i&g!>hITm zY^MBLw@g~?iSbG-Q(72@$uB7{2Sc@BHv>zM4Hq= zF>3lHY%z8sZzWs~7BcHYoEps|iOQ+j*ixQ+Sg3tPe+O5>ho)SbEZVB$BADwisW5!x-eA>8IlH(1t93ShHbfdA^?6 ze7g$$YC|pgHpF;|>^I+{qvnPuFo3DpPY2r`sMkmI@5vw=&H7(KuVRIgvGDQI>brcw zD`u2ba=f9EV`H=U0w!?ZoTiKUdMj}Zv~XF9)ELU;Tm)KohXC!{rq#QQTV)r+1cQk( z{1{PmvujT}0qi=1!Bh3%8oJG(*3%ba3PPmCv2)FSuN(mlf`pm7;X~ac;)ivCJLjRp z>}6XZR#54H)CYz9-VOYbtcI?W)KjPPimI&o80odlxKnh{%OCUcHyFad_m&6xCi2tI zn9OB`(?yNHe(lSRXldJ@!Km@8|MW%Bjz+ZM3jvtNyqVCxCHE!=OXcHmvA!4qe0X^@$d_z**x81Xa+M0sf&=PF@jk#My0H`(5Y63fr5&=g1ALQ* z_*c;U;6Zh^&q=cBWQP~tn&;rNeenT5)mWe66`Vd1#DB!?v;kOv-0ziQ7|~$51+@}B z#E{X_NY$O)#>*Nt$5h9D;92-F}^TL^{0gHFom*AXOPKhAc&u?=pVpoyTr)b5JI5 zT>C+dB-r%=qkG_}aZqErP5;y*0TzOi!BcFlr2q6i|Ld1hnin7qU%xL=o5vwG#*@u> zhge6aYyWjahb7SU%W=c2f1wUaZ+}jXA_Yr<8qIJ#ap`3C2Nn2wnh(u?s47(YcJx#z z?949p6P_*Uoja~6hrrurT)sJRG|cz0%Q%e2Zlj)pxnDg6HZHu^i;J84%Ix_u;skLD z8Fnt)?(*i{M)?|WC9`=m!o&dOuAy=EoSc2;FYEI(B=hR3Z{T@75FF`v=% z-dnt%ZJ&2>W5>b@=gc^dzoGO}{W>bl0+0Ly{B!uL7jFj&%G{usPX@E8p8MBz~?| z$|m?i@~v=n>Z@^>=;j!jiw*?w!+8u1krkNzrk?WIu)kG1QUyYE5lJfReIAcWHC05R zP2**}my(;kN8f(I#}^hUsHwov$ce{iiHwgmo&PGB<_3j@Qoj5R7 z%}-DudIRG(j%iPrXaE=sJ>nQNAn}Aw z`ll!-j)*sj2KE#A0nTz2I5A35 z%Tq{xf>}?}Re|^2K|moBYb^zHCuw4ozfLbH`UtF}>c)RXl8{&DEHUcTl4BHF%J0yp zntdo@w0{VUU~Y}ow^4_BO!UavWA}TwknT{)V?9JgJ-Ep0&f=yxHLxkR0n>PPD)^Jv z$dimpZ9e$rJVCS<3SOQ#f0>=nu3iJEX$6*dKz*;Dt1AF|rJmI$bl&@yJe~Ls9SYmt z_dJb_%`mtA&7SrseU8=s!ETrG`L`drx1?_OvHX5LeZIO@ZHHQ>?_GCHr+d>?Z;AF& zmmaS<9!#ZGm6{Ij3F2~%k=zryz?2zX3xJw^NUJLOl@>I5btvVB;=-R(W!U+(*?!ry zafNYJ{iCVa%jW*fe%6254dJ-9X8e<1onexJ7Vxd^{!zpYrHR#3ltMzW#lwJ+ zgyZ!EMSyClz%oa2G9L7kzDryK2CWlYUcPZhN}Y zjgv4kFut!)UR7nX+%nbWl42?Hj|tdpzh=e6%&gPy&q$UK3Ge`uva%v(ZN7I^h2;n7 zO5fo;UI88Yx1;_ec%>2?!qt^<48H8=0xyraaJY#`W}D*aZ}~{I-=Y38#0vfKj|oS- zpYu0~gCWX5XI&)I3S>1}qN?!I>R7aS zOT(4~j(*FEzUDvq6>Zw$(AWr+0J${f3vlf#H)?W!OQhmPcyR_@cSbe*rm`|s7&{JU zqf9GfEHXQ}eJkiWZhAd@Qx^QWXoB!V2P$42pBFCxp49oN5L;+qA{QyhQqxvyCodJ$ z{OQaeSRxf-U}Kg5LrG34IsV-6_V#)`3XhAv*2hNUptSA&z&>j$4+B2lABuV|(zJ*< zkoz%scI`B9U7?`-y5sLvJ!!ZfL$1KMquUIZ5EK6*xy-ha;SFgX4?`4Di(69s`#xY+ zPmN=Yt)ZC@kZ^bDH6wD|MjGNrrO9&z1gfbK-@0MU7v=lInK3d0rVj5K{hq9HJc-fu z;affqRHK*x&_$i*7NAtR1Gq(AL%0uEb@`3)*bJiU?Pw|eV1W)&(7TaJ@~4a6v%i$I z5PopVNvdu(O)|7$W&FeaXx3!KwH=a>61{9x=?)Zp&P|L=(?j9ii(+?S7o3A*Mr z0$K_b6c6<)4oF#VoC8anZ6)ekVdTCp07&7O7>a>UF;JpwYdh8Qg~H_BDw1rZGVOZC z`qix_6J$z|7Tg-Dp-zm=Blm|FAStv`Gu5cWF$3rT)MHSdoLA(st)1)##azZ>}_HKyDw+i_X6MjXX%;2f*?-fkge#T^e#zu5o@4{3I_2#(NmXE!D z6Vs6->ZhzNvH<@_-rI5H7}ZLFF0f_zJskS@gho9dV>(jAfQDwY-l<$fzC<@?^sis`^o**vQgPu|Oy&V4}UwTe8S4*68izA|xG z_8J<&{{XJ4wI-U4Jl}J9BhlZjeKhr9S3bKF$`7Qw*usH~jvc+NGCdW*5_xFg z)^D*|AQ`o}EJChasSn_$OAh~Fq-b2 zejsw~G{bcl?E}-|Sn3Fqr!6Bl3*0jqG-hrCuW4ekctN+Xe8t>8(2J&5JB@Yl2Uyuw z$^l&2R@XA{;oUzX@cvTba--!0e&FVfFjlB!No@>@C5BOR_HzFG#c=1FmEV;y#%agz zIUBx|RO+b!V$~zsR5~u@!O~VA;g&nOw+L}YxHWT3y*ny~JaC!9tb>Tg3gg@*rY3N$hdu4%0>G8))cHG8ZNYJ}%$CcaBla%;Xg^31v9?-i;a@ z5<9at-93MLzjj?JlK5KwMuB`>lcbLc!BZ#{?PO_q`lu#A zS}Wi?lC~zSp46a&l9XlL_axA|$6fdMyBT54Qdg)(p6B+{ozY)SD__CrXf03(=J?t9 z>|fH*8b|HXKOtk6#EgvP8mp&o{heOUo0qdn?*4b`t}hnD{w?Cwo4^p$W}pmEEE3;_ z0E}1H)w=ojpgkIdn*`TgUOyo2j48&FqlP&L;XSk!@1I~zbfWG(f6hut(E!K`=KLq4 z^bXSeQpAONgUn~yo6CpS0ALK{jMB?R=QY8Zh?b<%@pxLYzl&j$1mvon{g)*2aq_e& z0(irhTIKKLY$T&Gs4*xiqai9+n4gaGwy01{pZh4rGIMqCo-<9N$ty)tgHNeRoJikT zNbT(+tzASZ^Vzx9TY2_FTq#htySYINtbIcSm!D3Ve%fDskrykP`~JOdpgCG;Ntj?` z6i-R-5a1q_bR1;azyAwJ*?&F2m3e}wWRCam_&(EimhiGpJK6{b4$P8zJ#Bb*N3-bt zRjtmS-|&JwJ)AbqXaU5=xR~(#=A6t-bgOOa{IX%=fNC||vW;_q@0lR_qGJy|>oNz= zm=DJR!HPfhgdLplohrCI^j{jWP*&%KO0L0i_KuW-R|~NXzI*nbWNpo@KO^WAOa$yn zroV2lk|25?9Fe1+?7svikO*AyDY&ksW8AKhUp5i-zJvNSKSHh_oL(Oe^Nq_L!B8lI z_f=MU%0PSfQWG@shbQsQrH}nl@AjVnZ$li7fX!bHvAmAQeSr$9Sh{J*NM?Xoev_17 zSz=6n+`7!IUx`(^#4FZZ@N^cu8q0n<pl854t>90=hBdT5EMQzw%JUfB9}Xa7$w3eWATngP1KW4&J=zGs}E7 zq~CHC;2``9;)Mw8ZyugIC7tYf8@+(U@@1v!;%s=vA7j9Byrt>~dNZ*-=diM|78EqG zNMC;5ZfOP1vsFI4qB{C5r9-E;Cg(59g=tRIiApA?9t2Wo z-kG}zKA4T|^accwv#mhpX44tVC}>yYc`CN9AMP!0j`+hh9e(G9Zt6_dy{H}pb;Zll z^mlu8_}or4+8uM>KDWAb4*zF5st0Q6b!f?Y0+c&5O-eqRAyTs|=U38rIS^;-in371 z6oT%zLSqzHs77|$>j2bL3!#OsMd0`h*fpa`&P5``NkP5 z_jG&8Ue%bF)`!5={BfiWhC)bTRk=>zShVoT>D^c~_2<$~ zG?F_w&u8l^E|br-tLVQDoH0uO)iQ(Q$%8}4J2>nG({dgi!>nZLS%F9tru`nVge~!~ z4gymKhYlS}_txIRNIKIpx$!Mkk$~(EInQr&;~yVH{%0Aifg6=gpq=g5K_3UERjrY3B#O+dU)5MTD%foW#l_ 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

      tXmCazT0w6mC_(NcV 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%0Dewc$*wZl|cRJ0OZnuT|(fW>Hub0W*VYMaZS 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 Date: Fri, 10 Jan 2020 23:41:30 -0600 Subject: [PATCH 108/203] this is blackmajors fault im not gonna lie --- code/game/machinery/Sleeper.dm | 4 ++-- .../items/circuitboards/machine_circuitboards.dm | 4 ++++ .../designs/machine_desings/machine_designs_medical.dm | 10 +++++++++- code/modules/research/techweb/all_nodes.dm | 2 +- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 4fd4a7929d..88b0e804b7 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -373,7 +373,7 @@ /obj/machinery/sleeper/syndie/Initialize() . = ..() component_parts = list() - component_parts += new /obj/item/circuitboard/machine/sleeper(null) + component_parts += new /obj/item/circuitboard/machine/sleeper/syndie(null) component_parts += new /obj/item/stock_parts/matter_bin/super(null) component_parts += new /obj/item/stock_parts/manipulator/pico(null) component_parts += new /obj/item/stack/sheet/glass(null) @@ -384,7 +384,7 @@ /obj/machinery/sleeper/syndie/fullupgrade/Initialize() . = ..() component_parts = list() - component_parts += new /obj/item/circuitboard/machine/sleeper(null) + component_parts += new /obj/item/circuitboard/machine/sleeper/syndie(null) component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) component_parts += new /obj/item/stock_parts/manipulator/femto(null) component_parts += new /obj/item/stack/sheet/glass(null) diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index c1833ba44a..1ba91db246 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -7,6 +7,10 @@ /obj/item/stack/cable_coil = 1, /obj/item/stack/sheet/glass = 2) +/obj/item/circuitboard/machine/sleeper/syndie + name = "Syndicate Sleeper (Machine Board)" + build_path = /obj/machinery/sleeper/syndie + /obj/item/circuitboard/machine/vr_sleeper name = "VR Sleeper (Machine Board)" build_path = /obj/machinery/vr_sleeper diff --git a/code/modules/research/designs/machine_desings/machine_designs_medical.dm b/code/modules/research/designs/machine_desings/machine_designs_medical.dm index 2f95954e01..329fb7bf6e 100644 --- a/code/modules/research/designs/machine_desings/machine_designs_medical.dm +++ b/code/modules/research/designs/machine_desings/machine_designs_medical.dm @@ -24,7 +24,15 @@ id = "sleeper" build_path = /obj/item/circuitboard/machine/sleeper departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_ENGINEERING - category = list ("Medical Machinery") + category = list("Medical Machinery") + +/datum/design/board/syndiesleeper + name = "Machine Design (Syndicate Sleeper Board)" + desc = "The circuit board for a Syndicate sleeper, with controls inside." + id = "syndiesleeper" + build_path = /obj/item/circuitboard/machine/sleeper/syndie + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_ENGINEERING + category = list("Medical Machinery") /datum/design/board/cryotube name = "Machine Design (Cryotube Board)" diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index a44495fccb..4dd09fd2ad 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -1081,7 +1081,7 @@ display_name = "Illegal Technology" description = "Dangerous research used to create dangerous objects." prereq_ids = list("adv_engi", "adv_weaponry", "explosive_weapons") - design_ids = list("decloner", "borg_syndicate_module", "suppressor", "largecrossbow", "donksofttoyvendor") + design_ids = list("decloner", "borg_syndicate_module", "suppressor", "largecrossbow", "donksofttoyvendor", "syndiesleeper") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000) export_price = 5000 hidden = TRUE From 2006ccf4efa0b4bafb6b731691c12cd7af467652 Mon Sep 17 00:00:00 2001 From: Hatterhat Date: Sat, 11 Jan 2020 00:12:52 -0600 Subject: [PATCH 109/203] nicc you buffoon you never adjusted the hood type --- code/modules/mining/equipment/explorer_gear.dm | 1 + code/modules/mining/machine_vending.dm | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm index 86889c5d00..bdca4bb7df 100644 --- a/code/modules/mining/equipment/explorer_gear.dm +++ b/code/modules/mining/equipment/explorer_gear.dm @@ -29,6 +29,7 @@ resistance_flags = FIRE_PROOF /obj/item/clothing/suit/hooded/explorer/standard + hoodtype = /obj/item/clothing/head/hooded/explorer/standard /obj/item/clothing/head/hooded/explorer/standard diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index e5cab4438a..54f8e11b07 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -302,7 +302,7 @@ /obj/item/storage/backpack/duffelbag/mining_cloned name = "mining replacement kit" - desc = "A large bag that has advance tools and a spare jumpsuit, boots, and gloves for a newly cloned miner to get back in the field. Even as a new Id!" + desc = "A large bag that has advance tools and a spare jumpsuit, boots, and gloves for a newly cloned miner to get back in the field. Even has a new ID!" /obj/item/storage/backpack/duffelbag/mining_cloned/PopulateContents() new /obj/item/pickaxe/mini(src) From e0587aeac0e90a996db1c3bc0e4b8b68ec48985e Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 10 Jan 2020 23:33:26 -0800 Subject: [PATCH 110/203] another dumb patch --- code/controllers/subsystem/vote.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index e0ec031183..3e9c3a923e 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -256,8 +256,9 @@ SUBSYSTEM_DEF(vote) if(RANKED_CHOICE_VOTING) for(var/i=1,i<=voted.len,i++) var/list/myvote = voted[voted[i]] - for(var/j=1,j<=myvote.len,j++) - SSblackbox.record_feedback("nested tally","voting",1,list(vote_title_text,"[j]\th",choices[myvote[j]])) + if(islist(myvote)) + for(var/j=1,j<=myvote.len,j++) + SSblackbox.record_feedback("nested tally","voting",1,list(vote_title_text,"[j]\th",choices[myvote[j]])) if(obfuscated) //CIT CHANGE - adds obfuscated votes. this messages admins with the vote's true results var/admintext = "Obfuscated results" if(vote_system == RANKED_CHOICE_VOTING) From 312da86424744cd0862e65d72d883a5d67e21a1d Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 11 Jan 2020 01:28:49 -0800 Subject: [PATCH 111/203] Suggested changes --- _maps/map_files/generic/CentCom.dmm | 1 + code/game/objects/structures/ghost_role_spawners.dm | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index 2cca63db46..9a94fd3f61 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -17753,6 +17753,7 @@ /obj/item/stack/sheet/glass/fifty, /obj/item/stack/sheet/metal/fifty, /obj/item/storage/toolbox/mechanical, +/obj/item/stack/sheet/plastic/fifty, /obj/item/multitool, /turf/open/indestructible/hotelwood, /area/centcom/holding) diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 8aa84f2210..0cce1de41b 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -629,7 +629,7 @@ if(!..()) return 0 var/mob/M = target - if(HAS_TRAIT(M,TRAIT_SIXTHSENSE)) + if(HAS_TRAIT_FROM(M,TRAIT_SIXTHSENSE,GHOSTROLE_TRAIT)) REMOVE_TRAIT(M,TRAIT_SIXTHSENSE,GHOSTROLE_TRAIT) to_chat(M,"You're no longer hearing deadchat.") else From 9d3873f26fae7d12fa11e90748a1aa8bbfe080c1 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 11 Jan 2020 03:32:14 -0800 Subject: [PATCH 112/203] traitor always available --- code/controllers/subsystem/vote.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 3e9c3a923e..022943351d 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -433,6 +433,7 @@ SUBSYSTEM_DEF(vote) for(var/tag in modes_to_add) if(probabilities[tag] <= 0) modes_to_add -= tag + modes_to_add -= "traitor" // makes it so that traitor is always available choices.Add(modes_to_add) if("dynamic") for(var/T in config.storyteller_cache) From 85f6367df554cac2bb6da5241d9a04d38cdab241 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 11 Jan 2020 03:50:19 -0800 Subject: [PATCH 113/203] weh --- code/controllers/subsystem/vote.dm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 022943351d..97672da363 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -151,7 +151,8 @@ SUBSYSTEM_DEF(vote) sorted_insert(scores_by_choice[choice],this_vote[choice],/proc/cmp_numeric_asc) // START BALLOT GATHERING pretty_vote += choice - pretty_vote[choice] = GLOB.vote_score_options[this_vote[choice]] + if(this_vote[choice] in GLOB.vote_score_options) + pretty_vote[choice] = GLOB.vote_score_options[this_vote[choice]] SSblackbox.record_feedback("associative","voting_ballots",1,pretty_vote) // END BALLOT GATHERING for(var/score_name in scores_by_choice) @@ -191,7 +192,8 @@ SUBSYSTEM_DEF(vote) for(var/ckey in voted) var/list/this_vote = voted[ckey] for(var/choice in this_vote) - sorted_insert(scores_by_choice[choice],this_vote[choice],/proc/cmp_numeric_asc) + if(choice in scores_by_choice) + sorted_insert(scores_by_choice[choice],this_vote[choice],/proc/cmp_numeric_asc) var/middle_score = round(GLOB.vote_score_options.len/2,1) for(var/score_name in scores_by_choice) var/list/score = scores_by_choice[score_name] From 600732728a5a382bdacefebef88ab58e829c2aad Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 11 Jan 2020 08:03:47 -0600 Subject: [PATCH 114/203] Automatic changelog generation for PR #10465 [ci skip] --- html/changelogs/AutoChangeLog-pr-10465.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10465.yml diff --git a/html/changelogs/AutoChangeLog-pr-10465.yml b/html/changelogs/AutoChangeLog-pr-10465.yml new file mode 100644 index 0000000000..26dff901b2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10465.yml @@ -0,0 +1,8 @@ +author: "Putnam3145" +delete-after: True +changes: + - rscadd: "Ghost dojo now has an autoylathe." + - rscdel: "Ghost dojo no longer has VR or modular computer access." + - tweak: "Ghost dojo mobs are pacifists." + - tweak: "Ghost dojo booze-o-mat is now all access." + - bugfix: "Ghost dojo crematorium now has a button." From 6264e368f4fec2a7350da65fe26c1c07ad01d2f0 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 11 Jan 2020 08:06:23 -0600 Subject: [PATCH 115/203] Automatic changelog generation for PR #10523 [ci skip] --- html/changelogs/AutoChangeLog-pr-10523.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10523.yml diff --git a/html/changelogs/AutoChangeLog-pr-10523.yml b/html/changelogs/AutoChangeLog-pr-10523.yml new file mode 100644 index 0000000000..999fc1dd92 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10523.yml @@ -0,0 +1,4 @@ +author: "Hatterhat" +delete-after: True +changes: + - bugfix: "Explorer hoods on standard explorer suits can be reinforced with goliath hide plates again." From 49bc21d906f713d37dce5208922acf2281dbae54 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 11 Jan 2020 08:07:57 -0600 Subject: [PATCH 116/203] Automatic changelog generation for PR #10511 [ci skip] --- html/changelogs/AutoChangeLog-pr-10511.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10511.yml diff --git a/html/changelogs/AutoChangeLog-pr-10511.yml b/html/changelogs/AutoChangeLog-pr-10511.yml new file mode 100644 index 0000000000..5f3bf739cb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10511.yml @@ -0,0 +1,4 @@ +author: "kevinz000" +delete-after: True +changes: + - bugfix: "health analyzers now work" From bd53100e72bcea8fa74f1e4fcdcf0bdadb312f97 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 11 Jan 2020 08:09:39 -0600 Subject: [PATCH 117/203] Automatic changelog generation for PR #10495 [ci skip] --- html/changelogs/AutoChangeLog-pr-10495.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10495.yml diff --git a/html/changelogs/AutoChangeLog-pr-10495.yml b/html/changelogs/AutoChangeLog-pr-10495.yml new file mode 100644 index 0000000000..02ffedf5fc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10495.yml @@ -0,0 +1,4 @@ +author: "kevinz000" +delete-after: True +changes: + - rscadd: "guests can now looc" From 7a41fc4ee8aa067664c33b8b91e151f8b007d053 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 11 Jan 2020 08:21:11 -0600 Subject: [PATCH 118/203] Automatic changelog generation for PR #10505 [ci skip] --- html/changelogs/AutoChangeLog-pr-10505.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10505.yml diff --git a/html/changelogs/AutoChangeLog-pr-10505.yml b/html/changelogs/AutoChangeLog-pr-10505.yml new file mode 100644 index 0000000000..dd0932c50e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10505.yml @@ -0,0 +1,5 @@ +author: "LetterN" +delete-after: True +changes: + - tweak: "Shockcolar and electropack uses the new signaler ui" + - tweak: "Renaming shockcolar requires a pen" From ec01d60b4904b3707c1e2d707d8b368e160ffc2e Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 11 Jan 2020 08:28:07 -0600 Subject: [PATCH 119/203] Automatic changelog generation for PR #10497 [ci skip] --- html/changelogs/AutoChangeLog-pr-10497.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10497.yml diff --git a/html/changelogs/AutoChangeLog-pr-10497.yml b/html/changelogs/AutoChangeLog-pr-10497.yml new file mode 100644 index 0000000000..5acb6f8c47 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10497.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - code_imp: "Makes more folders and files for uplink." From 81fee7384d55fd80c68083a4e11c2d185aa4d790 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 11 Jan 2020 08:29:28 -0600 Subject: [PATCH 120/203] Automatic changelog generation for PR #10247 [ci skip] --- html/changelogs/AutoChangeLog-pr-10247.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10247.yml diff --git a/html/changelogs/AutoChangeLog-pr-10247.yml b/html/changelogs/AutoChangeLog-pr-10247.yml new file mode 100644 index 0000000000..b78e5c415d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10247.yml @@ -0,0 +1,5 @@ +author: "Seris02" +delete-after: True +changes: + - rscadd: "added atmos holofirelocks and temperature blocking" + - tweak: "tweaked how atmos holofan looks" From af562d1421dc4cf7bc935ff8e1d53123277106ed Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Sat, 11 Jan 2020 06:54:29 -0800 Subject: [PATCH 121/203] Update bloodsucker_life.dm --- code/modules/antagonists/bloodsucker/bloodsucker_life.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/antagonists/bloodsucker/bloodsucker_life.dm b/code/modules/antagonists/bloodsucker/bloodsucker_life.dm index bbb8aeca30..10728d0664 100644 --- a/code/modules/antagonists/bloodsucker/bloodsucker_life.dm +++ b/code/modules/antagonists/bloodsucker/bloodsucker_life.dm @@ -84,7 +84,7 @@ //It is called from your coffin on close (by you only) if(poweron_masquerade == TRUE || owner.current.AmStaked()) return FALSE - owner.current.adjustStaminaLoss(-2 + (regenRate * 8) * mult, 0) // Humans lose stamina damage really quickly. Vamps should heal more. + owner.current.adjustStaminaLoss(-2 + (regenRate * -8) * mult, 0) // Humans lose stamina damage really quickly. Vamps should heal more. owner.current.adjustCloneLoss(-0.1 * (regenRate * 2) * mult, 0) owner.current.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1 * (regenRate * 4) * mult) //adjustBrainLoss(-1 * (regenRate * 4) * mult, 0) // No Bleeding From 1aee5e880a61cbb23c8b8962c01d94dceadea03a Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Sat, 11 Jan 2020 12:24:23 -0500 Subject: [PATCH 122/203] god --- .../items/devices/radio/electropack.dm | 61 ++++++++----------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index 231818be77..5b13537a44 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -156,6 +156,7 @@ Code: strip_delay = 60 equip_delay_other = 60 materials = list(MAT_METAL=5000, MAT_GLASS=2000) + var/tagname = null /datum/design/electropack/shockcollar @@ -170,18 +171,17 @@ Code: if(loc == user && user.get_item_by_slot(SLOT_NECK)) to_chat(user, "The collar is fastened tight! You'll need help taking this off!") return - ..() + return ..() /obj/item/electropack/shockcollar/receive_signal(datum/signal/signal) if(!signal || signal.data["code"] != code) return if(isliving(loc) && on) - if(shock_cooldown != 0) + if(shock_cooldown == TRUE) return - shock_cooldown = 1 - spawn(100) - shock_cooldown = 0 + shock_cooldown = TRUE + addtimer(VARSET_CALLBACK(src, shock_cooldown, FALSE), 100) var/mob/living/L = loc step(L, pick(GLOB.cardinals)) @@ -196,33 +196,26 @@ Code: master.receive_signal() return -/obj/item/electropack/shockcollar/attack_self(mob/user) //Turns out can't fully source this from the parent item, spritepath gets confused if power toggled. Will come back to this when I know how to code better and readd powertoggle.. - var/option = "Change Name" - option = input(user, "What do you want to do?", "[src]", option) as null|anything in list("Change Name", "Change Frequency") - switch(option) - if("Change Name") - var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text - if(t) - tagname = copytext(sanitize(t), 1, MAX_NAME_LEN) - name = "[initial(name)] - [tagname]" - if("Change Frequency") - if(!ishuman(user)) - return - user.set_machine(src) - var/dat = {"
      - Frequency/Code for shock collar:
      - Frequency: -
      - - - [format_frequency(frequency)] - + - +
      - Code: - - - - [code] - + - +
      - "} +/obj/item/electropack/shockcollar/attackby(obj/item/W, mob/user, params) //moves it here because on_click is being bad + if(istype(W, /obj/item/pen)) + var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text + if(t) + tagname = copytext(sanitize(t), 1, MAX_NAME_LEN) + name = "[initial(name)] - [tagname]" + else + return ..() - user << browse(dat, "window=radio") - onclose(user, "radio") - return +/obj/item/electropack/shockcollar/ui_interact(mob/user) //on_click calls this + var/dat = {" + +Frequency/Code for shock collar:
      +Frequency: +[format_frequency(src.frequency)] +Set
      +Code: +[src.code] +Set
      +
      "} + user << browse(dat, "window=radio") + onclose(user, "radio") + return From 108e585cf1e2821d7df0d5d3f4982350a89ac359 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Sat, 11 Jan 2020 12:25:38 -0500 Subject: [PATCH 123/203] shit --- .../items/devices/radio/electropack.dm | 109 +++++++++--------- 1 file changed, 55 insertions(+), 54 deletions(-) diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index 5b13537a44..f9da35ec18 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -10,22 +10,23 @@ slot_flags = ITEM_SLOT_BACK w_class = WEIGHT_CLASS_HUGE materials = list(MAT_METAL=10000, MAT_GLASS=2500) - var/on = TRUE + var/code = 2 var/frequency = FREQ_ELECTROPACK - var/shock_cooldown = 0 + var/on = TRUE + var/shock_cooldown = FALSE -/obj/item/electropack/suicide_act(mob/user) +/obj/item/electropack/suicide_act(mob/living/carbon/user) user.visible_message("[user] hooks [user.p_them()]self to the electropack and spams the trigger! It looks like [user.p_theyre()] trying to commit suicide!") return (FIRELOSS) /obj/item/electropack/Initialize() . = ..() - SSradio.add_object(src, frequency, RADIO_SIGNALER) + set_frequency(frequency) /obj/item/electropack/Destroy() SSradio.remove_object(src, frequency) - return ..() + . = ..() //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/item/electropack/attack_hand(mob/user) @@ -36,7 +37,7 @@ return return ..() -/obj/item/electropack/attackby(obj/item/W, mob/user, params) +/obj/item/electropack/attackby(obj/item/W, mob/living/user, params) if(istype(W, /obj/item/clothing/head/helmet)) var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit(user) A.icon = 'icons/obj/assemblies.dmi' @@ -57,43 +58,47 @@ return ..() /obj/item/electropack/Topic(href, href_list) - //..() var/mob/living/carbon/C = usr if(usr.stat || usr.restrained() || C.back == src) return - if((ishuman(usr) && usr.contents.Find(src)) || usr.contents.Find(master) || (in_range(src, usr) && isturf(loc))) - usr.set_machine(src) - if(href_list["freq"]) - SSradio.remove_object(src, frequency) - frequency = sanitize_frequency(frequency + text2num(href_list["freq"])) - SSradio.add_object(src, frequency, RADIO_SIGNALER) - else - if(href_list["code"]) - code += text2num(href_list["code"]) - code = round(code) - code = min(100, code) - code = max(1, code) - else - if(href_list["power"]) - on = !( on ) - icon_state = "electropack[on]" - if(!( master )) - if(ismob(loc)) - attack_self(loc) - else - for(var/mob/M in viewers(1, src)) - if(M.client) - attack_self(M) - else - if(ismob(master.loc)) - attack_self(master.loc) - else - for(var/mob/M in viewers(1, master)) - if(M.client) - attack_self(M) - else + + if(!usr.canUseTopic(src, BE_CLOSE)) usr << browse(null, "window=radio") + onclose(usr, "radio") return + + if(href_list["set"]) + if(href_list["set"] == "freq") + var/new_freq = input(usr, "Input a new receiving frequency", "Electropack Frequency", format_frequency(frequency)) as num|null + if(!usr.canUseTopic(src, BE_CLOSE)) + return + new_freq = unformat_frequency(new_freq) + new_freq = sanitize_frequency(new_freq, TRUE) + set_frequency(new_freq) + + if(href_list["set"] == "code") + var/new_code = input(usr, "Input a new receiving code", "Electropack Code", code) as num|null + if(!usr.canUseTopic(src, BE_CLOSE)) + return + new_code = round(new_code) + new_code = CLAMP(new_code, 1, 100) + code = new_code + + if(href_list["set"] == "power") + if(!usr.canUseTopic(src, BE_CLOSE)) + return + on = !(on) + icon_state = "electropack[on]" + + if(usr) + attack_self(usr) + + return + +/obj/item/electropack/proc/set_frequency(new_frequency) + SSradio.remove_object(src, frequency) + frequency = new_frequency + SSradio.add_object(src, frequency, RADIO_SIGNALER) return /obj/item/electropack/receive_signal(datum/signal/signal) @@ -101,10 +106,10 @@ return if(isliving(loc) && on) - if(shock_cooldown != 0) + if(shock_cooldown == TRUE) return - shock_cooldown = 1 - addtimer(VARSET_CALLBACK(src, shock_cooldown, 0), 100) + shock_cooldown = TRUE + addtimer(VARSET_CALLBACK(src, shock_cooldown, FALSE), 100) var/mob/living/L = loc step(L, pick(GLOB.cardinals)) @@ -119,25 +124,21 @@ master.receive_signal() return -/obj/item/electropack/attack_self(mob/user) - +/obj/item/electropack/ui_interact(mob/user) if(!ishuman(user)) return + user.set_machine(src) - var/dat = {"Turned [on ? "On" : "Off"] - -Toggle
      + var/dat = {" + +Turned [on ? "On" : "Off"] - Toggle
      Frequency/Code for electropack:
      Frequency: -- -- [format_frequency(frequency)] -+ -+
      - +[format_frequency(src.frequency)] +Set
      Code: -- -- [code] -+ -+
      +[src.code] +Set
      "} user << browse(dat, "window=radio") onclose(user, "radio") From eb93e3d1d3f0b6c6b7ef23746c4e9f3a4326a841 Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Sat, 11 Jan 2020 12:35:04 -0500 Subject: [PATCH 124/203] hi --- .../items/devices/radio/electropack.dm | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index f468121048..f10ee2b63f 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -144,3 +144,81 @@ Code: user << browse(dat, "window=radio") onclose(user, "radio") return + +/obj/item/electropack/shockcollar + name = "shock collar" + desc = "A reinforced metal collar. It seems to have some form of wiring near the front. Strange.." + icon = 'modular_citadel/icons/obj/clothing/cit_neck.dmi' + alternate_worn_icon = 'modular_citadel/icons/mob/citadel/neck.dmi' + icon_state = "shockcollar" + item_state = "shockcollar" + body_parts_covered = NECK + slot_flags = ITEM_SLOT_NECK | ITEM_SLOT_DENYPOCKET //no more pocket shockers + w_class = WEIGHT_CLASS_SMALL + strip_delay = 60 + equip_delay_other = 60 + materials = list(MAT_METAL=5000, MAT_GLASS=2000) + + var/tagname = null + +/datum/design/electropack/shockcollar + name = "Shockcollar" + id = "shockcollar" + build_type = AUTOLATHE + build_path = /obj/item/electropack/shockcollar + materials = list(MAT_METAL=5000, MAT_GLASS=2000) + category = list("hacked", "Misc") + +/obj/item/electropack/shockcollar/attack_hand(mob/user) + if(loc == user && user.get_item_by_slot(SLOT_NECK)) + to_chat(user, "The collar is fastened tight! You'll need help taking this off!") + return + return ..() + +/obj/item/electropack/shockcollar/receive_signal(datum/signal/signal) + if(!signal || signal.data["code"] != code) + return + + if(isliving(loc) && on) + if(shock_cooldown == TRUE) + return + shock_cooldown = TRUE + addtimer(VARSET_CALLBACK(src, shock_cooldown, FALSE), 100) + var/mob/living/L = loc + step(L, pick(GLOB.cardinals)) + + to_chat(L, "You feel a sharp shock from the collar!") + var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread + s.set_up(3, 1, L) + s.start() + + L.Knockdown(100) + + if(master) + master.receive_signal() + return + +/obj/item/electropack/shockcollar/attackby(obj/item/W, mob/user, params) //moves it here because on_click is being bad + if(istype(W, /obj/item/pen)) + var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text + if(t) + tagname = copytext(sanitize(t), 1, MAX_NAME_LEN) + name = "[initial(name)] - [tagname]" + else + return ..() + +/obj/item/electropack/shockcollar/ui_interact(mob/user) //on_click calls this + var/dat = {" + +Frequency/Code for shock collar:
      +Frequency: +[format_frequency(src.frequency)] +Set
      + +Code: +[src.code] +Set
      +
      "} + user << browse(dat, "window=radio") + onclose(user, "radio") + return From 8afef6b2091c59cb9b5130b275cc4150aee4027f Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Sat, 11 Jan 2020 12:35:10 -0500 Subject: [PATCH 125/203] bye --- .../items/devices/radio/shockcollar.dm | 77 ------------------- 1 file changed, 77 deletions(-) delete mode 100644 modular_citadel/code/game/objects/items/devices/radio/shockcollar.dm diff --git a/modular_citadel/code/game/objects/items/devices/radio/shockcollar.dm b/modular_citadel/code/game/objects/items/devices/radio/shockcollar.dm deleted file mode 100644 index 94bf1ba30a..0000000000 --- a/modular_citadel/code/game/objects/items/devices/radio/shockcollar.dm +++ /dev/null @@ -1,77 +0,0 @@ -/obj/item/electropack/shockcollar - name = "shock collar" - desc = "A reinforced metal collar. It seems to have some form of wiring near the front. Strange.." - icon = 'modular_citadel/icons/obj/clothing/cit_neck.dmi' - alternate_worn_icon = 'modular_citadel/icons/mob/citadel/neck.dmi' - icon_state = "shockcollar" - item_state = "shockcollar" - body_parts_covered = NECK - slot_flags = ITEM_SLOT_NECK | ITEM_SLOT_DENYPOCKET //no more pocket shockers - w_class = WEIGHT_CLASS_SMALL - strip_delay = 60 - equip_delay_other = 60 - materials = list(MAT_METAL=5000, MAT_GLASS=2000) - - var/tagname = null - -/datum/design/electropack/shockcollar - name = "Shockcollar" - id = "shockcollar" - build_type = AUTOLATHE - build_path = /obj/item/electropack/shockcollar - materials = list(MAT_METAL=5000, MAT_GLASS=2000) - category = list("hacked", "Misc") - -/obj/item/electropack/shockcollar/attack_hand(mob/user) - if(loc == user && user.get_item_by_slot(SLOT_NECK)) - to_chat(user, "The collar is fastened tight! You'll need help taking this off!") - return - return ..() - -/obj/item/electropack/shockcollar/receive_signal(datum/signal/signal) - if(!signal || signal.data["code"] != code) - return - - if(isliving(loc) && on) - if(shock_cooldown == TRUE) - return - shock_cooldown = TRUE - addtimer(VARSET_CALLBACK(src, shock_cooldown, FALSE), 100) - var/mob/living/L = loc - step(L, pick(GLOB.cardinals)) - - to_chat(L, "You feel a sharp shock from the collar!") - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(3, 1, L) - s.start() - - L.Knockdown(100) - - if(master) - master.receive_signal() - return - -/obj/item/electropack/shockcollar/attackby(obj/item/W, mob/user, params) //moves it here because on_click is being bad - if(istype(W, /obj/item/pen)) - var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text - if(t) - tagname = copytext(sanitize(t), 1, MAX_NAME_LEN) - name = "[initial(name)] - [tagname]" - else - return ..() - -/obj/item/electropack/shockcollar/ui_interact(mob/user) //on_click calls this - var/dat = {" - -Frequency/Code for shock collar:
      -Frequency: -[format_frequency(src.frequency)] -Set
      - -Code: -[src.code] -Set
      -
      "} - user << browse(dat, "window=radio") - onclose(user, "radio") - return From 8a7e6d49a65656e408185f005bec0afb54dbedde Mon Sep 17 00:00:00 2001 From: kappa-sama <44128284+kappa-sama@users.noreply.github.com> Date: Sat, 11 Jan 2020 12:35:49 -0500 Subject: [PATCH 126/203] e --- code/game/objects/items/devices/radio/electropack.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index f9da35ec18..f10ee2b63f 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -136,6 +136,7 @@ Turned [on ? "On" : "Off"] - Toggle
      Frequency: [format_frequency(src.frequency)] Set
      + Code: [src.code] Set
      @@ -213,6 +214,7 @@ Code: Frequency: [format_frequency(src.frequency)] Set
      + Code: [src.code] Set
      From c709a9e4a90d397fc8be15e9865a21017f44acb0 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Sat, 11 Jan 2020 18:45:54 +0100 Subject: [PATCH 127/203] A few reagents related fixes. --- .../reagents/chemistry/machinery/chem_dispenser.dm | 7 +++++-- code/modules/reagents/reagent_containers/borghydro.dm | 9 ++++++--- code/modules/reagents/reagent_dispenser.dm | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 217c915a9e..4580a51a1f 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -92,8 +92,11 @@ /obj/machinery/chem_dispenser/Initialize() . = ..() - for(var/list/L in list(dispensable_reagents, emagged_reagents, upgrade_reagents, upgrade_reagents2, upgrade_reagents3)) - L = sortList(L, /proc/cmp_reagents_asc) + emagged_reagents = sortList(emagged_reagents, /proc/cmp_reagents_asc) + upgrade_reagents = sortList(upgrade_reagents, /proc/cmp_reagents_asc) + upgrade_reagents2 = sortList(upgrade_reagents2, /proc/cmp_reagents_asc) + upgrade_reagents3 = sortList(upgrade_reagents3, /proc/cmp_reagents_asc) + dispensable_reagents = sortList(dispensable_reagents, /proc/cmp_reagents_asc) update_icon() /obj/machinery/chem_dispenser/Destroy() diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index 980e823a82..48a5c10e3b 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -31,6 +31,7 @@ Borg Hypospray var/accepts_reagent_upgrades = TRUE //If upgrades can increase number of reagents dispensed. var/list/modes = list() //Basically the inverse of reagent_ids. Instead of having numbers as "keys" and strings as values it has strings as keys and numbers as values. //Used as list for input() in shakers. + var/list/reagent_names = list() /obj/item/reagent_containers/borghypo/Initialize() . = ..() @@ -54,7 +55,7 @@ Borg Hypospray return 1 // Use this to add more chemicals for the borghypo to produce. -/obj/item/reagent_containers/borghypo/proc/add_reagent(reagent) +/obj/item/reagent_containers/borghypo/proc/add_reagent(datum/reagent/reagent) reagent_ids |= reagent var/datum/reagents/RG = new(30) RG.my_atom = src @@ -64,9 +65,11 @@ Borg Hypospray R.add_reagent(reagent, 30) modes[reagent] = modes.len + 1 + reagent_names[initial(reagent.name)] = reagent -/obj/item/reagent_containers/borghypo/proc/del_reagent(reagent) +/obj/item/reagent_containers/borghypo/proc/del_reagent(datum/reagent/reagent) reagent_ids -= reagent + reagent_names -= initial(reagent.name) var/datum/reagents/RG var/datum/reagents/TRG for(var/i in 1 to reagent_ids.len) @@ -112,7 +115,7 @@ Borg Hypospray log_combat(user, M, "injected", src, "(CHEMICALS: [english_list(injected)])") /obj/item/reagent_containers/borghypo/attack_self(mob/user) - var/chosen_reagent = modes[input(user, "What reagent do you want to dispense?") as null|anything in reagent_ids] + var/chosen_reagent = modes[reagent_names[input(user, "What reagent do you want to dispense?") as null|anything in reagent_names]] if(!chosen_reagent) return mode = chosen_reagent diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index e9f8053631..1a8c960b2f 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -184,7 +184,7 @@ icon_state = "virus_food" anchored = TRUE density = FALSE - reagent_id = /datum/reagent/toxin/mutagen/mutagenvirusfood + reagent_id = /datum/reagent/consumable/virus_food /obj/structure/reagent_dispensers/cooking_oil name = "vat of cooking oil" From 29e7c49627ee2a394b581ef355567b8900c1c2ff Mon Sep 17 00:00:00 2001 From: TrilbySpaceClone Date: Sat, 11 Jan 2020 13:07:02 -0500 Subject: [PATCH 128/203] Pss got any of the good stuf Hydro? --- code/controllers/subsystem/research.dm | 616 +++++++++++++++---------- strings/tips.txt | 5 +- 2 files changed, 374 insertions(+), 247 deletions(-) diff --git a/code/controllers/subsystem/research.dm b/code/controllers/subsystem/research.dm index ab27658efd..0b805d0063 100644 --- a/code/controllers/subsystem/research.dm +++ b/code/controllers/subsystem/research.dm @@ -25,264 +25,388 @@ SUBSYSTEM_DEF(research) var/list/techweb_boost_items = list() //associative double-layer path = list(id = list(point_type = point_discount)) var/list/techweb_nodes_hidden = list() //Node ids that should be hidden by default. var/list/techweb_point_items = list( //path = list(point type = value) - /obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 5000), // Cit three more anomalys anomalys - /obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 7500), - /obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 10000), - // - Slime Extracts! - - /obj/item/slime_extract/grey = list(TECHWEB_POINT_TYPE_GENERIC = 500), // Adds in slime core deconing - /obj/item/slime_extract/metal = list(TECHWEB_POINT_TYPE_GENERIC = 750), - /obj/item/slime_extract/purple = list(TECHWEB_POINT_TYPE_GENERIC = 750), - /obj/item/slime_extract/orange = list(TECHWEB_POINT_TYPE_GENERIC = 750), - /obj/item/slime_extract/blue = list(TECHWEB_POINT_TYPE_GENERIC = 750), - /obj/item/slime_extract/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 1000), - /obj/item/slime_extract/silver = list(TECHWEB_POINT_TYPE_GENERIC = 1000), - /obj/item/slime_extract/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 1000), - /obj/item/slime_extract/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 1000), - /obj/item/slime_extract/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 1250), - /obj/item/slime_extract/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 1250), - /obj/item/slime_extract/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 1250), - /obj/item/slime_extract/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 1250), - /obj/item/slime_extract/red = list(TECHWEB_POINT_TYPE_GENERIC = 1250), - /obj/item/slime_extract/green = list(TECHWEB_POINT_TYPE_GENERIC = 1250), - /obj/item/slime_extract/pink = list(TECHWEB_POINT_TYPE_GENERIC = 1250), - /obj/item/slime_extract/gold = list(TECHWEB_POINT_TYPE_GENERIC = 1250), - /obj/item/slime_extract/black = list(TECHWEB_POINT_TYPE_GENERIC = 1500), - /obj/item/slime_extract/adamantine =list (TECHWEB_POINT_TYPE_GENERIC = 1500), - /obj/item/slime_extract/oil = list(TECHWEB_POINT_TYPE_GENERIC = 1500), - /obj/item/slime_extract/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 1500), - /obj/item/slime_extract/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 10000), + // - Slime Extracts! - Basics + /obj/item/slime_extract/grey = list(TECHWEB_POINT_TYPE_GENERIC = 500), + /obj/item/slime_extract/metal = list(TECHWEB_POINT_TYPE_GENERIC = 750), + /obj/item/slime_extract/purple = list(TECHWEB_POINT_TYPE_GENERIC = 750), + /obj/item/slime_extract/orange = list(TECHWEB_POINT_TYPE_GENERIC = 750), + /obj/item/slime_extract/blue = list(TECHWEB_POINT_TYPE_GENERIC = 750), + /obj/item/slime_extract/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 1000), + /obj/item/slime_extract/silver = list(TECHWEB_POINT_TYPE_GENERIC = 1000), + /obj/item/slime_extract/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 1000), + /obj/item/slime_extract/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 1000), + /obj/item/slime_extract/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 1250), + /obj/item/slime_extract/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 1250), + /obj/item/slime_extract/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 1250), + /obj/item/slime_extract/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 1250), + /obj/item/slime_extract/red = list(TECHWEB_POINT_TYPE_GENERIC = 1250), + /obj/item/slime_extract/green = list(TECHWEB_POINT_TYPE_GENERIC = 1250), + /obj/item/slime_extract/pink = list(TECHWEB_POINT_TYPE_GENERIC = 1250), + /obj/item/slime_extract/gold = list(TECHWEB_POINT_TYPE_GENERIC = 1250), + /obj/item/slime_extract/black = list(TECHWEB_POINT_TYPE_GENERIC = 1500), + /obj/item/slime_extract/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 1500), + /obj/item/slime_extract/oil = list(TECHWEB_POINT_TYPE_GENERIC = 1500), + /obj/item/slime_extract/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 1500), + /obj/item/slime_extract/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 2500), // Reproductive - Crossbreading Cores! - (Grey Cores) - /obj/item/slimecross/reproductive/grey = list(TECHWEB_POINT_TYPE_GENERIC = 1000), - /obj/item/slimecross/reproductive/orange = list(TECHWEB_POINT_TYPE_GENERIC = 1500), - /obj/item/slimecross/reproductive/purple = list(TECHWEB_POINT_TYPE_GENERIC = 1500), - /obj/item/slimecross/reproductive/blue = list(TECHWEB_POINT_TYPE_GENERIC = 1500), - /obj/item/slimecross/reproductive/metal = list(TECHWEB_POINT_TYPE_GENERIC = 1500), - /obj/item/slimecross/reproductive/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 1750), - /obj/item/slimecross/reproductive/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 1750), - /obj/item/slimecross/reproductive/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 1750), - /obj/item/slimecross/reproductive/silver = list(TECHWEB_POINT_TYPE_GENERIC = 1750), - /obj/item/slimecross/reproductive/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 2000), - /obj/item/slimecross/reproductive/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 2000), - /obj/item/slimecross/reproductive/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 2000), - /obj/item/slimecross/reproductive/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 2000), - /obj/item/slimecross/reproductive/red = list(TECHWEB_POINT_TYPE_GENERIC = 2250), - /obj/item/slimecross/reproductive/green = list(TECHWEB_POINT_TYPE_GENERIC = 2250), - /obj/item/slimecross/reproductive/pink = list(TECHWEB_POINT_TYPE_GENERIC = 2250), - /obj/item/slimecross/reproductive/gold = list(TECHWEB_POINT_TYPE_GENERIC = 2250), - /obj/item/slimecross/reproductive/oil = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/reproductive/black = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/reproductive/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/reproductive/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/reproductive/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/reproductive/grey = list(TECHWEB_POINT_TYPE_GENERIC = 1000), + /obj/item/slimecross/reproductive/orange = list(TECHWEB_POINT_TYPE_GENERIC = 1500), + /obj/item/slimecross/reproductive/purple = list(TECHWEB_POINT_TYPE_GENERIC = 1500), + /obj/item/slimecross/reproductive/blue = list(TECHWEB_POINT_TYPE_GENERIC = 1500), + /obj/item/slimecross/reproductive/metal = list(TECHWEB_POINT_TYPE_GENERIC = 1500), + /obj/item/slimecross/reproductive/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 1750), + /obj/item/slimecross/reproductive/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 1750), + /obj/item/slimecross/reproductive/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 1750), + /obj/item/slimecross/reproductive/silver = list(TECHWEB_POINT_TYPE_GENERIC = 1750), + /obj/item/slimecross/reproductive/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 2000), + /obj/item/slimecross/reproductive/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 2000), + /obj/item/slimecross/reproductive/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 2000), + /obj/item/slimecross/reproductive/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 2000), + /obj/item/slimecross/reproductive/red = list(TECHWEB_POINT_TYPE_GENERIC = 2250), + /obj/item/slimecross/reproductive/green = list(TECHWEB_POINT_TYPE_GENERIC = 2250), + /obj/item/slimecross/reproductive/pink = list(TECHWEB_POINT_TYPE_GENERIC = 2250), + /obj/item/slimecross/reproductive/gold = list(TECHWEB_POINT_TYPE_GENERIC = 2250), + /obj/item/slimecross/reproductive/oil = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/reproductive/black = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/reproductive/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/reproductive/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/reproductive/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), // Burning - Crossbreading Cores! - (Orange Cores) - /obj/item/slimecross/burning/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2000), - /obj/item/slimecross/burning/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/burning/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/burning/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/burning/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/burning/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/burning/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/burning/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/burning/silver = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/burning/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/burning/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/burning/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/burning/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/burning/red = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/burning/green = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/burning/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/burning/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/burning/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/burning/black = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/burning/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/burning/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/burning/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/burning/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2000), + /obj/item/slimecross/burning/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/burning/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/burning/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/burning/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/burning/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/burning/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/burning/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/burning/silver = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/burning/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/burning/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/burning/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/burning/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/burning/red = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/burning/green = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/burning/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/burning/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/burning/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/burning/black = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/burning/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/burning/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/burning/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 3750), // Regenerative - Crossbreading Cores! - (Purple Cores) - /obj/item/slimecross/regenerative/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2000), - /obj/item/slimecross/regenerative/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/regenerative/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/regenerative/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/regenerative/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/regenerative/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/regenerative/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/regenerative/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/regenerative/silver = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/regenerative/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/regenerative/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/regenerative/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/regenerative/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/regenerative/red = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/regenerative/green = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/regenerative/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/regenerative/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/regenerative/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/regenerative/black = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/regenerative/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/regenerative/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/regenerative/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/regenerative/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2000), + /obj/item/slimecross/regenerative/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/regenerative/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/regenerative/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/regenerative/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/regenerative/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/regenerative/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/regenerative/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/regenerative/silver = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/regenerative/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/regenerative/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/regenerative/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/regenerative/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/regenerative/red = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/regenerative/green = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/regenerative/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/regenerative/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/regenerative/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/regenerative/black = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/regenerative/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/regenerative/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/regenerative/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 3750), // Stabilized - Crossbreading Cores! - (Blue Cores) - /obj/item/slimecross/stabilized/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2000), - /obj/item/slimecross/stabilized/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/stabilized/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/stabilized/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/stabilized/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/stabilized/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/stabilized/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/stabilized/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/stabilized/silver = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/stabilized/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/stabilized/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/stabilized/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/stabilized/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/stabilized/red = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/stabilized/green = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/stabilized/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/stabilized/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/stabilized/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/stabilized/black = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/stabilized/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/stabilized/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/stabilized/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/stabilized/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2000), + /obj/item/slimecross/stabilized/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/stabilized/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/stabilized/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/stabilized/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/stabilized/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/stabilized/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/stabilized/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/stabilized/silver = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/stabilized/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/stabilized/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/stabilized/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/stabilized/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/stabilized/red = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/stabilized/green = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/stabilized/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/stabilized/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/stabilized/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/stabilized/black = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/stabilized/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/stabilized/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/stabilized/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 3750), // Industrial - Crossbreading Cores! - (Metal Cores) - /obj/item/slimecross/industrial/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2000), - /obj/item/slimecross/industrial/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/industrial/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/industrial/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/industrial/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/industrial/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/industrial/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/industrial/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/industrial/silver = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/industrial/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/industrial/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/industrial/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/industrial/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/industrial/red = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/industrial/green = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/industrial/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/industrial/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/industrial/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/industrial/black = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/industrial/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/industrial/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/industrial/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/industrial/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2000), + /obj/item/slimecross/industrial/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/industrial/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/industrial/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/industrial/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/industrial/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/industrial/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/industrial/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/industrial/silver = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/industrial/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/industrial/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/industrial/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/industrial/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/industrial/red = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/industrial/green = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/industrial/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/industrial/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/industrial/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/industrial/black = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/industrial/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/industrial/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/industrial/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 3750), // Charged - Crossbreading Cores! - (Yellow Cores) - /obj/item/slimecross/charged/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2250), - /obj/item/slimecross/charged/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/charged/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/charged/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/charged/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/charged/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/charged/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/charged/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/charged/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/charged/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/charged/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/charged/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/charged/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/charged/red = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/charged/green = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/charged/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/charged/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/charged/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/charged/black = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/charged/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/charged/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/charged/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/charged/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2250), + /obj/item/slimecross/charged/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/charged/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/charged/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/charged/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/charged/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/charged/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/charged/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/charged/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/charged/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/charged/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/charged/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/charged/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/charged/red = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/charged/green = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/charged/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/charged/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/charged/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/charged/black = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/charged/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/charged/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/charged/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4000), // Selfsustaining - Crossbreading Cores! - (Dark Purple Cores) - /obj/item/slimecross/selfsustaining/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2250), - /obj/item/slimecross/selfsustaining/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/selfsustaining/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/selfsustaining/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/selfsustaining/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/selfsustaining/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/selfsustaining/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2250), + /obj/item/slimecross/selfsustaining/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/selfsustaining/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/selfsustaining/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/selfsustaining/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/selfsustaining/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3000), /obj/item/slimecross/selfsustaining/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/selfsustaining/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/selfsustaining/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/selfsustaining/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/selfsustaining/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/selfsustaining/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/selfsustaining/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/selfsustaining/red = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/selfsustaining/green = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/selfsustaining/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/selfsustaining/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/selfsustaining/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/selfsustaining/black = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/selfsustaining/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/selfsustaining/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/selfsustaining/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/selfsustaining/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/selfsustaining/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/selfsustaining/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/selfsustaining/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/selfsustaining/red = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/selfsustaining/green = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/selfsustaining/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/selfsustaining/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/selfsustaining/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/selfsustaining/black = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/selfsustaining/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), /obj/item/slimecross/selfsustaining/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/selfsustaining/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/selfsustaining/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4000), // Consuming - Crossbreading Cores! - (Sliver Cores) - /obj/item/slimecross/consuming/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2250), - /obj/item/slimecross/consuming/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/consuming/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/consuming/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/consuming/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/consuming/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/consuming/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/consuming/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/consuming/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/consuming/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/consuming/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/consuming/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/consuming/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/consuming/red = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/consuming/green = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/consuming/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/consuming/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/consuming/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/consuming/black = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/consuming/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/consuming/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/consuming/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/consuming/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2250), + /obj/item/slimecross/consuming/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/consuming/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/consuming/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/consuming/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/consuming/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/consuming/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/consuming/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/consuming/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/consuming/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/consuming/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/consuming/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/consuming/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/consuming/red = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/consuming/green = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/consuming/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/consuming/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/consuming/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/consuming/black = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/consuming/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/consuming/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/consuming/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4000), // Prismatic - Crossbreading Cores! - (Pyrite Cores) - /obj/item/slimecross/prismatic/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/prismatic/orange = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/prismatic/purple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/prismatic/blue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/prismatic/metal = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/prismatic/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/prismatic/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/prismatic/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/prismatic/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/prismatic/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/prismatic/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/prismatic/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/prismatic/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/prismatic/red = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/prismatic/green = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/prismatic/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/prismatic/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/prismatic/oil = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - /obj/item/slimecross/prismatic/black = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - /obj/item/slimecross/prismatic/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - /obj/item/slimecross/prismatic/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - /obj/item/slimecross/prismatic/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4250), + /obj/item/slimecross/prismatic/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/prismatic/orange = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/prismatic/purple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/prismatic/blue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/prismatic/metal = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/prismatic/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/prismatic/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/prismatic/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/prismatic/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/prismatic/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/prismatic/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/prismatic/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/prismatic/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/prismatic/red = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/prismatic/green = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/prismatic/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/prismatic/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/prismatic/oil = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/prismatic/black = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/prismatic/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/prismatic/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/prismatic/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4250), // Recurring - Crossbreading Cores! - (Cerulean Cores) - /obj/item/slimecross/recurring/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/recurring/orange = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/recurring/purple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/recurring/blue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/recurring/metal = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/recurring/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/recurring/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/recurring/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/recurring/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/recurring/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/recurring/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/recurring/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/recurring/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/recurring/red = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/recurring/green = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/recurring/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/recurring/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/recurring/oil = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - /obj/item/slimecross/recurring/black = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - /obj/item/slimecross/recurring/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - /obj/item/slimecross/recurring/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - /obj/item/slimecross/recurring/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4250) - ) // End of Cit changes + /obj/item/slimecross/recurring/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/recurring/orange = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/recurring/purple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/recurring/blue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/recurring/metal = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/recurring/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/recurring/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/recurring/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/recurring/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/recurring/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/recurring/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/recurring/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/recurring/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/recurring/red = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/recurring/green = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/recurring/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/recurring/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/recurring/oil = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/recurring/black = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/recurring/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/recurring/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/recurring/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4250), + // Seed Packs (Vender Stuff) - 2050 points + /obj/item/seeds/ambrosia = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/apple = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/banana = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/berry = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/cabbage = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/carrot = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/cherry = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/chanter = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/chili = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/cocoapod = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/coconut = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/coffee = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/cotton = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/corn = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/eggplant = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/grape = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/grass = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/lemon = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/lime = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/onion = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/orange = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/peach = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/peanutseed = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/pineapple = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/potato = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/poppy = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/pumpkin = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/replicapod = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/wheat/rice = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/soya = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/sugarcane = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/sunflower = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/strawberry = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/tea = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/tobacco = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/tomato = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/tower = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/watermelon = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/wheat = list(TECHWEB_POINT_TYPE_GENERIC = 50), + /obj/item/seeds/whitebeet = list(TECHWEB_POINT_TYPE_GENERIC = 50), + // Seed Packs (Weeds/Hacked) - 675 points + /obj/item/seeds/amanita = list(TECHWEB_POINT_TYPE_GENERIC = 75), + /obj/item/seeds/glowshroom = list(TECHWEB_POINT_TYPE_GENERIC = 75), + /obj/item/seeds/liberty = list(TECHWEB_POINT_TYPE_GENERIC = 75), + /obj/item/seeds/nettle = list(TECHWEB_POINT_TYPE_GENERIC = 75), + /obj/item/seeds/plump = list(TECHWEB_POINT_TYPE_GENERIC = 75), + /obj/item/seeds/reishi = list(TECHWEB_POINT_TYPE_GENERIC = 75), + /obj/item/seeds/cannabis = list(TECHWEB_POINT_TYPE_GENERIC = 75), + /obj/item/seeds/starthistle = list(TECHWEB_POINT_TYPE_GENERIC = 75), + /obj/item/seeds/random = list(TECHWEB_POINT_TYPE_GENERIC = 75), + /obj/item/seeds/amanita = list(TECHWEB_POINT_TYPE_GENERIC = 75), + // Seed Packs (Mutations) From Basic -> Mutation 1 + /obj/item/seeds/ambrosia/deus = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/berry/poison = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/berry/glow = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/apple/gold = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/banana/mime = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/banana/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/banana/exotic_banana = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/soya/koi = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/cherry/blue = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/cherry/bulb = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/grape/green = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/cannabis/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/cannabis/death = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/cannabis/white = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/cannabis/ultimate = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/wheat/oat = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/wheat/meat = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/chili/ice = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/chili/ghost = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/lime/electric = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/orange_3d = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/firelemon = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/cocoapod/vanillapod = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/cocoapod/bungotree = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/corn/snapcorn = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/cotton/durathread = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/eggplant/eggy = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/poppy/geranium = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/poppy/lily = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/sunflower/novaflower = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/sunflower/moonflower = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/grass/carpet = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/grass/fairy = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/watermelon/holy = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/starthistle/corpse_flower = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/galaxythistle = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/cherry/bomb = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/angel = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/plump/walkingmushroom = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/chanterelle/jupitercup = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/glowshroom/glowcap = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/glowshroom/shadowshroom = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/nettle/death = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/onion/red = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/potato/sweet = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/pumpkin/blumpkin = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/carrot/parsnip = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/redbeet = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/tea/astra = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/coffee/robusta = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/tobacco/space = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/tomato/blue = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/tomato/blood = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/tomato/killer = list(TECHWEB_POINT_TYPE_GENERIC = 100), + /obj/item/seeds/tower/steel = list(TECHWEB_POINT_TYPE_GENERIC = 100), + // Seed Packs (Mutations) Mutation 1 -> Mutation 2 + /obj/item/seeds/ambrosia/gaia = list(TECHWEB_POINT_TYPE_GENERIC = 125), + /obj/item/seeds/berry/death = list(TECHWEB_POINT_TYPE_GENERIC = 125), + /obj/item/seeds/bee_balm = list(TECHWEB_POINT_TYPE_GENERIC = 125), + /obj/item/seeds/poppy/lily/trumpet = list(TECHWEB_POINT_TYPE_GENERIC = 125), + /obj/item/seeds/berry/death = list(TECHWEB_POINT_TYPE_GENERIC = 125), + /obj/item/seeds/tea/catnip = list(TECHWEB_POINT_TYPE_GENERIC = 125), + /obj/item/seeds/tomato/blue/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 125), + // Seed Packs (Mutations) Mutation 2 -> Mutation 4 + /obj/item/seeds/bee_balm = list(TECHWEB_POINT_TYPE_GENERIC = 150), + // Seed Packs (Mutations) Mutation 3 -> Mutation 5 + Lava Land Plants + /obj/item/seeds/bee_balm/honey = list(TECHWEB_POINT_TYPE_GENERIC = 175), + /obj/item/seeds/lavaland/cactus = list(TECHWEB_POINT_TYPE_GENERIC = 175), + /obj/item/seeds/gatfruit = list(TECHWEB_POINT_TYPE_GENERIC = 175), + /obj/item/seeds/lavaland/polypore = list(TECHWEB_POINT_TYPE_GENERIC = 175), + /obj/item/seeds/lavaland/porcini = list(TECHWEB_POINT_TYPE_GENERIC = 175), + /obj/item/seeds/lavaland/inocybe = list(TECHWEB_POINT_TYPE_GENERIC = 175), + /obj/item/seeds/lavaland/ember = list(TECHWEB_POINT_TYPE_GENERIC = 175), + /obj/item/seeds/kudzu = list(TECHWEB_POINT_TYPE_GENERIC = 175) //Placing here do to all its mutations + ) var/list/errored_datums = list() var/list/point_types = list() //typecache style type = TRUE list //---------------------------------------------- diff --git a/strings/tips.txt b/strings/tips.txt index e9c1350469..e874167753 100644 --- a/strings/tips.txt +++ b/strings/tips.txt @@ -55,7 +55,8 @@ As a Scientist, you can disable anomalies by scanning them with an analyzer, the As a Scientist, researchable stock parts can seriously improve the efficiency and speed of machines around the station. In some cases, it can even unlock new functions. As a Scientist, you can generate research points by letting the tachyon-doppler array record increasingly large explosions. As a Scientist, getting drunk just enough will speed up research. Skol! -As a Scientist, you can get points by placing slime cores into the deconstructive analyzer! This even works with crossbred slime cores. +As a Scientist, you can get points by placing slime cores into the deconstructive analyzer! This even works with crossbred slime cores. +As a Scientist, work with botanists to get different types of seeds, as each type of seed can be used in the deconstructive analyzer for a small amount of Rnd type points! As a Roboticist, keep an ear out for anomaly announcements. If you get your hands on an anomaly core, you can build a Phazon mech! As a Roboticist, you can repair your cyborgs with a welding tool. If they have taken burn damage from lasers, you can remove their battery, expose the wiring with a screwdriver and replace their wires with a cable coil. As a Roboticist, you can reset a cyborg's module by cutting and mending the reset wire with a wire cutter. @@ -148,6 +149,8 @@ As a Botanist, you can hack the MegaSeed Vendor to get access to more exotic see As a Botanist, you can mutate the plants growing in your hydroponics trays with unstable mutagen or, as an alternative, crude radioactives from chemistry to get special variations. As a Botanist, you should look into increasing the potency of your plants. This increases the size, amount of chemicals, points gained from grinding them in the biogenerator, and lets people know you are a proficient botanist. As a Botanist, you can combine production trait chemicals just like a Chemist. Chlorine (blumpkin) + radium and phosphorus (glowshrooms) equals unstable mutagen! +As a Botanist, Rnd might pester you for different type of seed packets, perhaps a deal can be made in turn. +As a Botanist, plants have different reactions to different chemicals, think logical like how in many gardeners use ash as a mulch. As a Cook, you can load your food into snack vending machines. As a Cook, you can rename your custom made food with a pen. As a Cook, any food you make will be much healthier than the junk food found in vendors. Having the crew routinely eating from you will provide minor buffs. From 16db38a08f15ec77cbf39572769689f0c1413153 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Sat, 11 Jan 2020 20:51:15 +0100 Subject: [PATCH 129/203] Travis man good --- code/game/objects/items/extinguisher.dm | 2 +- code/modules/food_and_drinks/food/snacks_other.dm | 2 +- .../reagents/chemistry/machinery/chem_dispenser.dm | 12 ++++++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/code/game/objects/items/extinguisher.dm b/code/game/objects/items/extinguisher.dm index 4585685cde..81317b6eab 100644 --- a/code/game/objects/items/extinguisher.dm +++ b/code/game/objects/items/extinguisher.dm @@ -65,7 +65,7 @@ icon_state = "foam_extinguisher0" //item_state = "foam_extinguisher" needs sprite dog_fashion = null - chem = "firefighting_foam" + chem = /datum/reagent/firefighting_foam tanktype = /obj/structure/reagent_dispensers/foamtank sprite_name = "foam_extinguisher" precision = TRUE diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm index a85623cabd..0c17814c98 100644 --- a/code/modules/food_and_drinks/food/snacks_other.dm +++ b/code/modules/food_and_drinks/food/snacks_other.dm @@ -615,7 +615,7 @@ name = "marshmallow" desc = "A marshmallow filled with fluffy marshmallow fluff." icon_state = "marshmallow" - list_reagents = list("sugar" = 5, "nutriment" = 2) + list_reagents = list(/datum/reagent/consumable/sugar = 5, /datum/reagent/consumable/nutriment = 2) filling_color = "#fafafa" w_class = WEIGHT_CLASS_TINY tastes = list("marshmallow" = 2) diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 4580a51a1f..424f2bce30 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -92,10 +92,14 @@ /obj/machinery/chem_dispenser/Initialize() . = ..() - emagged_reagents = sortList(emagged_reagents, /proc/cmp_reagents_asc) - upgrade_reagents = sortList(upgrade_reagents, /proc/cmp_reagents_asc) - upgrade_reagents2 = sortList(upgrade_reagents2, /proc/cmp_reagents_asc) - upgrade_reagents3 = sortList(upgrade_reagents3, /proc/cmp_reagents_asc) + if(emagged_reagents) + emagged_reagents = sortList(emagged_reagents, /proc/cmp_reagents_asc) + if(upgrade_reagents) + upgrade_reagents = sortList(upgrade_reagents, /proc/cmp_reagents_asc) + if(upgrade_reagents2) + upgrade_reagents2 = sortList(upgrade_reagents2, /proc/cmp_reagents_asc) + if(upgrade_reagents3) + upgrade_reagents3 = sortList(upgrade_reagents3, /proc/cmp_reagents_asc) dispensable_reagents = sortList(dispensable_reagents, /proc/cmp_reagents_asc) update_icon() From 47fd3823e800e1c931d00f9fcd2868cbf71d67ff Mon Sep 17 00:00:00 2001 From: Hatterhat Date: Sat, 11 Jan 2020 15:58:24 -0600 Subject: [PATCH 130/203] staff assistant jumpsuit gang --- code/modules/clothing/under/miscellaneous.dm | 12 +++++++++++- code/modules/vending/clothesmate.dm | 5 +++-- goon/icons/mob/worn_js_rank.dmi | Bin 0 -> 67658 bytes goon/icons/obj/item_js_rank.dmi | Bin 0 -> 16677 bytes .../code/modules/client/loadout/_service.dm | 6 ++++++ 5 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 goon/icons/mob/worn_js_rank.dmi create mode 100644 goon/icons/obj/item_js_rank.dmi diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm index 06aa5aeb0c..61fa5c7c77 100644 --- a/code/modules/clothing/under/miscellaneous.dm +++ b/code/modules/clothing/under/miscellaneous.dm @@ -527,6 +527,16 @@ item_color = "assistant_formal" can_adjust = FALSE +/obj/item/clothing/under/staffassistant + name = "staff assistant's jumpsuit" + desc = "It's a generic grey jumpsuit. That's about what assistants are worth, anyway." + icon = 'goon/icons/obj/item_js_rank.dmi' + alternate_worn_icon = 'goon/icons/mob/worn_js_rank.dmi' + icon_state = "assistant" + item_state = "gy_suit" + item_color = "assistant" + mutantrace_variation = NONE + /obj/item/clothing/under/blacktango name = "black tango dress" desc = "Filled with Latin fire." @@ -935,4 +945,4 @@ icon_state = "christmasfemaleg" item_state = "christmasfemaleg" body_parts_covered = CHEST|GROIN - can_adjust = FALSE \ No newline at end of file + can_adjust = FALSE diff --git a/code/modules/vending/clothesmate.dm b/code/modules/vending/clothesmate.dm index 6144f4c57a..0bc5d66d4a 100644 --- a/code/modules/vending/clothesmate.dm +++ b/code/modules/vending/clothesmate.dm @@ -144,8 +144,9 @@ /obj/item/clothing/suit/jacket/letterman_syndie = 5, /obj/item/clothing/under/jabroni = 2, /obj/item/clothing/suit/vapeshirt = 2, - /obj/item/clothing/under/geisha = 4,, - /obj/item/clothing/under/keyholesweater = 3) + /obj/item/clothing/under/geisha = 4, + /obj/item/clothing/under/keyholesweater = 3, + /obj/item/clothing/under/staffassistant = 5) premium = list(/obj/item/clothing/under/suit_jacket/checkered = 4, /obj/item/clothing/head/mailman = 2, /obj/item/clothing/under/rank/mailman = 2, diff --git a/goon/icons/mob/worn_js_rank.dmi b/goon/icons/mob/worn_js_rank.dmi new file mode 100644 index 0000000000000000000000000000000000000000..8235c3ff3db7d238561c2c97498c9baa8fb12648 GIT binary patch literal 67658 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

      p(%LIJ-wW>8$wXxCP7Xc+ep3R8M}4 zmpf}-p6>0Ptxi#hV{%N4kdE((q_UvR@84icNwBE6c#e^=>dRfT>q}n~j$8Kh3oIR7 zgnLqQ1&}^J0-^t(!J>+Q6;uj$e?^$vynFLHpC>kpy$c9?vo3s3(Z>6H3 z5Z%}zG*aLSVY@QLV80>;U``J}^^L&;KGgyj1=FWr>sC5NUnR$aEq`?{F3+Tfd{HUj zu-n!2xYB+=)Gnv5q5^a!8s|@AqN4IPf=`WzOpdU?q%6axvgb*qB}|r4?fX?`tJA&c zbuLkyct-gzx>+MFKvT%)d&MnLmf0z%e^Bu~T{R&gAsEcEBqb#cMiD~!2)KvacO`xO zn4+TR2@TagIA%4`*O{>9edNc3=KG;|4+25Ye0~VGvtt7*!VhtEvje-=lm8Qtg%X}S zsrPKeq-S zh_yCN%4(J3d(&WYhw1{LDGXJI(s5pTX)%to*QSMfz9k(6$)6P+1B)56XI(JClmx}) zFzNu@BMz?9^(h1jin{5OXdpX4Y*}YvAr2_50`EN?d*N%Pe$xfZ&zPq*j=_kT}&U zaDnpY+v=a=u?EoyB4Xko0F`iaYi?bGN?M=(eebB~(yDU`0Uh9S2Zv%FNgu8y@naKCiZ8fYQ&@lg4`d=0MVa?M zLMGW&RUa?^d%H{kLX^LgD-0`%!}Mmj(~x*PotaXWckS_d7+|rW`H9FaNI1yPI?xSUJ}t z`Nh0bt6tHSO~V4vc03Jz7KUnK?mH8fN!dnwzy^eWz=uwp2@f{J4Tz3Rk&V&9*N=hX zDkuXY;D#N2$I4=7hE-YD}>!T*e~wIP7Ue*(8BtUoz6fFEEDbjn^n&LBRuB+ z#&xH&xBxcrfKv{efB+L(O%syM^shE(w}3%ladwv8(hG!Q&Qf^9z1LGy6k2*HN*!>B z04g{zV`A<@uUS?MaO&`g05&53;Q~m1?0bY#JDAjP)%4s;Vd&HWPBj)nH_Sz(JS(^` z$ZDWk!uH*-UzpYxSYyDdBszC3zm(ymscgw{U8K;>hXrp!WpQ>m>klJe2~TGct)bQ6 zDRP=MH`wJCVV^R7dyU-B0xQ+{vt`oPK0HBC2q`9Lk=G) zqcmVU$Qo^ndY!O7ebLUb4Afu&Ee2rGv{qU%kD~wqk=qj$$R_iH^a;#hBbr(XBs`ef ztG8Z~_#OioF7$4A-73%=C(7%XyOp0l6bCq2@PZVA{10e-4q-H2n~!Yfe>{j0MexZn z5<_%A8uAa(r)@aOyWo#aH5*uX)XjS_tN6C_rAq;NY4)%M&_f(X1E698rfG#XY_se2 zFn7)lP*MB;wVwIRRXT+*I_J_PFMUV=?0BBEQX&Fk`FOxx+kXvuR-paZGr*s~m;}nY zNeHpL4>C;#pwDCe<`FLp_P6k?3JJ;QzDVMkIo$qZT)kg2tU_06e2=0WIcfLkH<Cm0>`a?2l(<;g)T_mZ5lIf<31P99a;@ zqDW%+^~^$raSs8s{B0|hvQ+Ml@lSVs90UU4(wLJI)JzLb25Ml-hPVG<52fSDzaPgL z$qi?al>O{+@5k-FuMC7*%d%+KmPlV>(fauJ(87O6U!nj7{Pv6!c}8MD+f3OZ{-{dO zW>;r?dv#jP!o{UBj8beNTh0cAn%^H!UyB;{SFOITItpy#!4AUjWF%^A%YH;u8$40X z$t%y6_Yc*`NnW=6$m~dSQ^RHJEw|<8zw@~bx52Bxw=AIk$?T8V5EddbK{LmCH{*&Z z-iMxOGat!+Mw)o0o)aE@kgi&d^6c&uSs3i0HOojDKCqAy+W6%;AauN4Tplq)<9niv zj)~cqk>U_)j^oTr)p;5%(MW;Lu|ZoU$z+GT%2J!4YgN&=3R6u=5((nhS&3=y_ZnsvrU{zJU<-n3SD`5`|NL&yUn5Z zQlqP8TuEZ%j1yYcxw}e`lL+Oen-krE-f9a>|MxCN$qa17Tf<*Mzb@4^G*JYTsxE-{`mz)7I068R!_o3<$9Dqg93OLN2mz6|`_H$Aj(z7d zn=%U~`-n){dz3{zpI8YEfdMSAC6e^<5ptiqxbOg8P)12Ov!@5b|W=Pa@}WOr-r;W zn1D~ZyLPg$%^S($aR~vTcB;Y*b0QA)P<&`=u8zGxz&mc9)8qQ9&@vV z^^{W|q~LbnG_KnNkc+dn`HbwZq{CiXKgir;0zVxzD^Q+Owyt*9e{5YhpH}ym9YlTb z9*w&>W`Bi2&(n^>JBQ?_kj9~-b*I%6qz}%EefcCc>!q;FyR@}B zfq7SxkpITAdV}rx4}?u4*u1D%`=~vfp>w5QbY;lqa!|X?O6lWTs_o`$|3k0p4pzj+ z!xb*;*GxVI*=X*R0z+0SPNQ2=#qva`FF68-9J8L{lqZ$MszuKEo}Zq5n64CfNbqOB zJw?RX;r8~n!rhhNCvs-I|K>tHB%)otazI&`( zw~@yLUc2zdeJ7_YwRxky#YNZ7S8;lJIyTW2Vwq#F8>PmTYiybe1!ZkvZ5^+hlQR^Z z_-v=bZ(>2!CjA~M>0T`@RFZkhJKmSzNG4reXzjHIJ*Uf=bXE9yx#LMlZjnjKVR(Y@Km*a$N1bw+kE}HwM-o zF*D<8*V$n}X?%`%FoS3+T>FbQ-nV4|Uvj2S7BO{oGH7vTK`&sg(Y;>_&A@gutfuWW zC!*Pp66sfeNA{cURsq&VQ@A@)hXA@L8V`U}uK=avHeMs6D<`JhW#(X5P-EHNJA?X+ zufbvZ`%uEhwnggSvgJ*4Pmm2tJhkn78_mj=mOu!ur-S_TNC6NqOQOk0__SuHYv(>P z=TFgofZvNbtB+7>v2vxWy?vJnL}ADi#k!@x&i!-KY@&4!pNYmY0B}K1yY_ zQ$HO0@#BZpRT993NE7nBul1A*eHnlKyg@f4J$KJ?Y^vH%%eKx{gG z4qVnd()gW2b60(-dDX2jqO4X{6urmKYlTJ}d1b(8v$t3F3-pHCS;KgKi0K+@$G^Eh zFf`{6AKpQk{ii7uBuC-kjrEcRdlWMwm+~b+3k%m4#jWw4SUxNGsN{b0oJ=a@{WFh- zqM;_=fzO^T($a>>9_RLTEgDOdsm)A3&KsBJ))cqzqv*-YM!(CO%xQ_xOB|IDsV(2$Zwef|0rNM$-~LnUcUWWlngsxBa{_162}2=HVSyTeZLhn?#A16 z5h%MldR}0_!@IQo^4z=R9hWf?xHbqX7)?^W(U?V{Bx^VLvYf zi2;CYV2s=G7BpUXJdT;6LPFbeMQpfNv?fxQ*(<_CwsSNB zKdcK%+-KES=r}PABF_GCZA7EttJ3pGoO}p>Yu6jh6)GPuoVZb)Zv~VFAQcVbksf3S zep}s&bM$tKzYsaqUFHIun55gejWc0fzo)26E@TQ`Jdx4M#ozkWhKwXEzhKkw-CH`x zcxBI&`|W@M9qT>mC7AB6hzK9H6N-{ft%_!Zz}2O3OSTR8c;ZIpFRxBh z$oM(g!}8`6N5QZT*q|$eISgIrnFr5mMG=i|rCG`~bu*nkw+U_t$RR)fpTyK1uXaO_NMzY_WAEmH z`4wGw!C(=hn3JQU^xK!0 zm+$*Cwj5|Y1l04=MZX0IlNI9LrFk31p-$C3Zq38Zot2#pTU%ROu6hf+-@asJi9I|( zSrED4WnjRFmu?=+2SN<`3S-I^Ju1`}VgutJe?<*Rl#jgy+A*d@| zw1W#9$_hU=*QuzB7=?W^&BKnOY4zSD(}zwp#DmU|O(cu?N z40z&#utGu|;F!OA_Xq#M3oV~T>PIblIHH~#3Hndw`;ea_WFB5@Auv3yac}|v|yNj{)H*w$!LWs#&1h8 zN+f1$%W7rKprT-PqBrBgIehh2Mz&u`OA9lKktlIaNeHi;l)K18KC9J?HbLZbFRroD zqvwkFQa^?%&n?}f#6y}1*0Rb&^w3;*EtUV|erQgx{|%=hSAf1leq4kEVVtWlwRq}#ij>?m2-ec?FfZUbo z3z-pO`{3(yMc>D>o9?uuLJ+z*5xTe>!BcY!h{o1mA%I!JgzmB}fdl zM}_Dv1Wv#7 zeEVZCvDq*k5AS&^o(hb1>etG#BuhW`(AGf9AvtPAaIsG#`ale5AI$XD>UC%$T#4`SE zkNiOTKCWo?Ze+z{&bM(pgVj#VEbTwZGw;uM`nhi-b>(Uia8+1qk9v*672H=^$KJw% z2#&tH45HfMGY5#4%*Dn~y*~=w%BMPyyjAXwS=DHJgNF+QS>~p_yuB;89qzsGYWZ|) zR6(4Pk-=6Adh=&j^oKt#P=L_!d?Y*WYj`=?B>SH|Bcj$cq*1!UY{uUX{)^oS{hwwX z<+6HY1pDPQBYr>a+(%7q{5%K{gRFnIxRN_e+Xxo#h9=H9``_9t+pcr8NevhnVhplQ}O{=eI1(>!tP&0Aa3p_q_nwIsbIDi2v z(nCQvJdmaYH2rX=X^>$Qvw(M~w-nUz0v~Fmczr)9Wl6NCw z&-*zjv#nu}ye%O!rmD&QF(g`lAKi8BWt~{A%|R;1+Q!Q4M&!`L z8$7?vI&F2~^%DU>K|@YnH0b{Q`xU^sboi3#$rA`-SvPZWb2D1&ORV?SD`DAKNELyE z8V*SCFwrt*-DPZ6ve{p6-^k}vCd<79mYdSy&nX*7$sQTCKC4?LdW@OYTUvqrsK{b$ zax&5l@*n1-8rcngsDu>lHQ7Z<<3VnWTMiD>f=ap~SmSHX|4BM6DG9{jFks;cc(iDc zV`k9keA_^7w!7Jip@s+U;VG7X9>LnAtB;Cil0y_~17&3Wd`_)<72Zge&*ZCwOvJ(^Hwnb^vT zj_fc>C+N}Ey|T$%JJ;z3r}ck94vNmjERP~AD$m{vH1o|*N03?5MkrpdWWt}vG$)vk zx`+28&#pQQw%lEH9&*dR9TJ4+?|#lW8OX%>{gLGB$}$9jDmb(+7u_9~YS`S}l>}la zn%jP9$iKQfdK`!D_Zzpob8>RBk){9{`$>c z6i}y4Yfq+6`|HfO_;{||Qa~+}oha*$a7}Hn@G|cD{#&!k?Ii#LLT!%CR-(jik#zBu zNLn7qU_}Hxh*K%KK|~KWYUhrzo=SEbntvn!JKxC2NN80fLceh2w-mP!K^3Q8s5Q!T z0=kSGX9kTb7yA;Kr@R1tWNKXhX=F1mLi7Cb{HbWLboKA$*FXXUewCizG4b->={XOt zeQB#1aU>JvLbi_bT zHt6jGC?BgnFb0&r!R7bV?V$!YOKdRk zcD9zBgajlrJPkc)7d~Bp!z=c4=HAAz7IM9o-*Rg>3CsERZ8XvDK$k8fCT#z6hpfVC zcH?^Z#to<+K)7(g_4taU?K9ayO84y@6>H^;26o7LT}j-2Nf76Pu^KRO_IN7q@~%f9lSbp7=HHcb_y8FeB<<$cH|tO)<%bxhdLUJBNv~txy=ANm7>?q zwn5(@t1$itQtQ_%GVV6bUobFrR^(z^kF``WM}0 ztETpMfD#P0nDUAosxLxh&br?neE8j;dWYC_^1Qp;?=)fNO04f3svp2oVk!Q_p1W~# z`-O0>`M~$wl)!m)DhmOB8efWf$_~}#FZ}L8^=xO3&;gci%i*(D-vS?6UYZ}i1Mtlv zCB2Ej`knDiKt^?~sktCbCq)KA?@on>cTPbd?v0$>!>ZpF++Qjxl+I|=nA{q5<&coW zw>;ok?$tzNmSQKL<%we7CvPFC>6u|V^96KSCZa_V3$nnixA=v7NnVppUN z7rE5d8#J~sVR56uy0QDGdtjyPboe1t7~%oDI5RUq_&Dj&1-K*QvfRew^! z7X^a`8}zH6wuDUPup3Mn+-PF%4K|E@vV2YZ7^VFwAG;RtkyAn*41n&whx^{pZ;90L z2p)xJ&2eB-U>1p?3@nj@NNaM6zY&|oR919$O0so8yj0Q4Mm`*W?Q}pW3B2WIWHOdA z$ok^O?dBfYL4yZ6R&dtaY1UKhs1MZ3Cwaz4KkCMv_qp}X&wrol_oMHbPP32ao9i#HBSG#q)Ms~vKXsg5Ax|n~tIs>s{%pv14Hrlxin&(70}R*DAwAkbjp zcB(6d51Ih0mQ3Y^r>Ey^L0B3sc7Qyh^{!|#D^F^aHFUW1F)3uBNu+wz@JEI1y(AnD zpDo#*_QWA`SZnnb=FN2vXj|@?VFGLfBMgUz911m1HG3&@5t`zBOsk3t{j?(d4R!%XF+ZVHnCl9rrUey&E z8NW^eo&%U%C|>|{MR_U5O9n|izDfsi7ILbu$V|{ClJzl3h>7VDp4uDo#>Vs@F9Xo4 z;S`TEvH{|g)8sy0q%vT`RANhRMG`__4GD%)m_w9crL?k#AiNvQYj2Kg2U5HD?Uc*w z$`o|ezfg+GQ)P`*PjfmnVJlf~5Z1q7v7t0E*7|($^s)WMAnNWf$SEJ})Rv*Y4P&Bq zi>*C2S_;%u>+~n?S}PNv0Eh_`jD!Dt%iWac&<%mNjbze5ik4AAXT8#%o()s^V}x{K zrBVPqD^Z_(4U!+`a8R6tM|?mZ>ep@IVv!1|#S{;Z2pXoq5Nn7W{JILe0f9N-i}dOG*aai zV9Dv7;DEr>AcDlb*ii4l|DlK!-JgVgOA>hlN0*7MHfTGI6uww5_}csCiKkF%AMsX9 zQ)6T53|B#i;kQ3StPMMA+oE(qO()V0I+ zLIrOr=JIe>#zS**JVc$UCNEBqD+3Tw8Lq>=%~|kPreLbPcq_WG@AYEB7^BWpWp4*A zE8_SZB&{=~q^{2MWDVS5C%MF7_ayEkDd1j9I5qQim&SRN88&)yCdHER(B78XY4Xq1 zobYm_*XkIpY~y_kt;7}taW>9{n}7^|&ije;+{zPpR;M;3{GP($3wTd5nTLSK{v1Na zSYnHr7IuW-etg%>?Nw(ytd2y_>uI{QfOkVG{-- zT#ES8=9(X#_gR9Bw@wwL(20+E)*b)l=4|)$5li>T%YnchHF#Fn^V*|{q>m}JX!T{q zsz>Pw+_wJPEOeR+BH_QPsUvd#?*7K#kDrt5^s-GYxoWmiF1k>-%Pgh(0vn8gu|G$^ z-O>DuHqbF*siOU#;f5HPf@5^^*x2*)vP6+vz(U+a!h~}LFF*=Z&67i z0D$52q;Q4kTt)o*|A0(>Af4*sHWZMppl{ikg(YTV!{Xo88f1Rh7Mo!YG*M9r4^THG z)m3i=38BFNT-lNeTlYvgJ`FZMT-o`SB5Xt?g@SqLIr1MticANr^sSNLd#6>VnSO+N zW!CN;>4)QCj4bR%dp{1MDgQ%`0*5FVjPF8c7wnxYzIl3R0YKky^P`$D<~*^_DvPN( zZ9f#Bs$%2Vs%*L@P--p3Y@xys4Mj-WhsBcQcU9+o=SC=k@B9$TNeHuE4**W=Ske>fxcpD1*|Uk;VAU!Xt{9lxe=&$(y4woTB-{;Tf U2!)JGLg440*9wwl5(a_)8`LNtTmS$7 literal 0 HcmV?d00001 diff --git a/goon/icons/obj/item_js_rank.dmi b/goon/icons/obj/item_js_rank.dmi new file mode 100644 index 0000000000000000000000000000000000000000..b61e07a15575bfcdacd17a0ae2d1562e3239d65b GIT binary patch literal 16677 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 SBjDd3fYg+<6szT5NBkdgT5m!C literal 0 HcmV?d00001 diff --git a/modular_citadel/code/modules/client/loadout/_service.dm b/modular_citadel/code/modules/client/loadout/_service.dm index 86823f5661..e57ca4662c 100644 --- a/modular_citadel/code/modules/client/loadout/_service.dm +++ b/modular_citadel/code/modules/client/loadout/_service.dm @@ -4,6 +4,12 @@ path = /obj/item/clothing/under/color/grey restricted_roles = list("Assistant") +/datum/gear/staffassistanttide + name "Staff Assistant's jumpsuit" + category = SLOT_W_UNIFORM + path = /obj/item/clothing/under/staffassistant + restricted_roles = list("Assistant") + /datum/gear/neetsuit name = "D.A.B. suit" category = SLOT_WEAR_SUIT From 7216ae545c80f8854177a50d6ad2678b38b5a8ee Mon Sep 17 00:00:00 2001 From: Hatterhat Date: Sat, 11 Jan 2020 16:08:51 -0600 Subject: [PATCH 131/203] how the hell did that fall out --- modular_citadel/code/modules/client/loadout/_service.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_citadel/code/modules/client/loadout/_service.dm b/modular_citadel/code/modules/client/loadout/_service.dm index e57ca4662c..b584c21ccd 100644 --- a/modular_citadel/code/modules/client/loadout/_service.dm +++ b/modular_citadel/code/modules/client/loadout/_service.dm @@ -5,7 +5,7 @@ restricted_roles = list("Assistant") /datum/gear/staffassistanttide - name "Staff Assistant's jumpsuit" + name = "Staff Assistant's jumpsuit" category = SLOT_W_UNIFORM path = /obj/item/clothing/under/staffassistant restricted_roles = list("Assistant") From ae46c1f63d091592c0564b3cf54bae4b12709b88 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sat, 11 Jan 2020 16:16:29 -0600 Subject: [PATCH 132/203] Automatic changelog generation for PR #10509 [ci skip] --- html/changelogs/AutoChangeLog-pr-10509.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10509.yml diff --git a/html/changelogs/AutoChangeLog-pr-10509.yml b/html/changelogs/AutoChangeLog-pr-10509.yml new file mode 100644 index 0000000000..4e1ede0631 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10509.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Made reagent containers examine text less annoying." From 38dcb78625f8ba0c1178f28fd347282f8ab3f1d1 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 11 Jan 2020 18:15:50 -0800 Subject: [PATCH 133/203] chemistry fixes --- code/game/objects/items/devices/scanners.dm | 2 +- .../reagents/chemistry/machinery/chem_master.dm | 10 +++++----- .../reagents/chemistry/reagents/other_reagents.dm | 2 +- code/modules/reagents/reagent_containers.dm | 3 +-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 069c921914..568d5e2d20 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -466,7 +466,7 @@ SLIME SCANNER msg += "Subject is not addicted to any reagents.\n" var/datum/reagent/impure/fermiTox/F = M.reagents.has_reagent(/datum/reagent/impure/fermiTox) - if(istype(F)) + if(istype(F,/datum/reagent/impure/fermiTox)) switch(F.volume) if(5 to 10) msg += "Subject contains a low amount of toxic isomers.\n" diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index e6b19417d8..9c877fc053 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -434,11 +434,11 @@ state = "Gas" var/const/P = 3 //The number of seconds between life ticks var/T = initial(R.metabolization_rate) * (60 / P) - var/datum/chemical_reaction/Rcr = get_chemical_reaction(R.type) + var/datum/chemical_reaction/Rcr = get_chemical_reaction(R) if(Rcr && Rcr.FermiChem) fermianalyze = TRUE var/pHpeakCache = (Rcr.OptimalpHMin + Rcr.OptimalpHMax)/2 - var/datum/reagent/targetReagent = beaker.reagents.has_reagent(R.type) + var/datum/reagent/targetReagent = beaker.reagents.has_reagent(R) if(!targetReagent) CRASH("Tried to find a reagent that doesn't exist in the chem_master!") @@ -463,9 +463,9 @@ var/T = initial(R.metabolization_rate) * (60 / P) if(istype(R, /datum/reagent/fermi)) fermianalyze = TRUE - var/datum/chemical_reaction/Rcr = get_chemical_reaction(R.type) + var/datum/chemical_reaction/Rcr = get_chemical_reaction(R) var/pHpeakCache = (Rcr.OptimalpHMin + Rcr.OptimalpHMax)/2 - var/datum/reagent/targetReagent = reagents.has_reagent(R.type) + var/datum/reagent/targetReagent = reagents.has_reagent(R) if(!targetReagent) CRASH("Tried to find a reagent that doesn't exist in the chem_master!") @@ -483,7 +483,7 @@ /obj/machinery/chem_master/proc/end_fermi_reaction()//Ends any reactions upon moving. - if(beaker.reagents.fermiIsReacting) + if(beaker && beaker.reagents.fermiIsReacting) beaker.reagents.fermiEnd() /obj/machinery/chem_master/proc/isgoodnumber(num) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index dbede29e5f..f960633d94 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -60,7 +60,7 @@ B = new(T) if(data["blood_DNA"]) B.blood_DNA[data["blood_DNA"]] = data["blood_type"] - if(!B.reagents) + if(B.reagents) B.reagents.add_reagent(type, reac_volume) B.update_icon() diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 97bc054ecd..af12b2caa0 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -128,8 +128,7 @@ target.visible_message("[M] has been splashed with something!", \ "[M] has been splashed with something!") for(var/datum/reagent/A in reagents.reagent_list) - R += A.type + " (" - R += num2text(A.volume) + ")," + R += "[A.type] ([A.volume])," if(thrownby) log_combat(thrownby, M, "splashed", R) From 37c611970815e4f424cd84c64d39ae013c78964b Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 11 Jan 2020 18:26:32 -0800 Subject: [PATCH 134/203] Sanity this is a commit by jimmy buffett --- code/controllers/subsystem/vote.dm | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 97672da363..d1c8ec56be 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -143,16 +143,18 @@ SUBSYSTEM_DEF(vote) // https://en.wikipedia.org/wiki/Majority_judgment var/list/scores_by_choice = list() for(var/choice in choices) + scores_by_choice += choice scores_by_choice[choice] = list() for(var/ckey in voted) var/list/this_vote = voted[ckey] var/list/pretty_vote = list() - for(var/choice in this_vote) - sorted_insert(scores_by_choice[choice],this_vote[choice],/proc/cmp_numeric_asc) - // START BALLOT GATHERING - pretty_vote += choice - if(this_vote[choice] in GLOB.vote_score_options) - pretty_vote[choice] = GLOB.vote_score_options[this_vote[choice]] + for(var/choice in choices) + if(choice in this_vote && choice in scores_by_choice) + sorted_insert(scores_by_choice[choice],this_vote[choice],/proc/cmp_numeric_asc) + // START BALLOT GATHERING + pretty_vote += choice + if(this_vote[choice] in GLOB.vote_score_options) + pretty_vote[choice] = GLOB.vote_score_options[this_vote[choice]] SSblackbox.record_feedback("associative","voting_ballots",1,pretty_vote) // END BALLOT GATHERING for(var/score_name in scores_by_choice) @@ -188,11 +190,12 @@ SUBSYSTEM_DEF(vote) /datum/controller/subsystem/vote/proc/calculate_scores(var/blackbox_text) var/list/scores_by_choice = list() for(var/choice in choices) + scores_by_choice += choice scores_by_choice[choice] = list() for(var/ckey in voted) var/list/this_vote = voted[ckey] - for(var/choice in this_vote) - if(choice in scores_by_choice) + for(var/choice in choices) + if(choice in this_vote && choice in scores_by_choice) sorted_insert(scores_by_choice[choice],this_vote[choice],/proc/cmp_numeric_asc) var/middle_score = round(GLOB.vote_score_options.len/2,1) for(var/score_name in scores_by_choice) From 0c64ea1351383bc084a03c8cfc4de7e7dbae04c9 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sat, 11 Jan 2020 18:37:16 -0800 Subject: [PATCH 135/203] wow that was fucking dumb --- code/controllers/configuration/configuration.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index 240f7de2d5..b0ed6e57af 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -341,7 +341,7 @@ if(probabilities[M.config_tag]<=0) qdel(M) continue - if(!(M.config_tag in SSvote.stored_modetier_results)) + if(CONFIG_GET(flag/modetier_voting) && !(M.config_tag in SSvote.stored_modetier_results)) qdel(M) continue if(min_pop[M.config_tag]) From b265959f2a0908beee85dd2a273477ac33103d78 Mon Sep 17 00:00:00 2001 From: Savotta Date: Sun, 12 Jan 2020 04:23:08 +0100 Subject: [PATCH 136/203] ports hShark snout from hyper-station-13 you people wouldn't know intelligent writing if it kicked you in the fucking nuts, you drooling retarded apes. i'm so FUCKIGN pissed. you are so fucking retarded, it's insane. i am stuck in a world filled with retards, and am being exiled from it for being the only shred of intelligent life found upon it. i just want somebody to listen to what the FUCK i have to say. nobody here is interested in intelligent discussion about topics that actually matter, they're only interested in erping with each other. disgusting fucking creatures. these people infuriate me to no end. why does nobody want to have a discussion? why does nobody want to talk about fuckign SHIT. THE ONLY TIME ANYONE EVER TALKSTO ME IS WHEN THEY WANT TO FUCKING ERP WITH ME!!! WHAT'S WRONG WITH YOU FUCKING PEOPLE. I'VE HAD THE SAME FUCKNG GUY PDA MESSAGE ME EVERY DAY, ACTING ALL NICE AND SHIT, AND I KNOW IT'S JUST BECAUSE HE WANTS TO ERP!! THAT'S ALL ANY OF YOU PEOPLE FUCKING WANT. I'M TRYING TO HAVE SUBSTANCE-FILLED FUCKING CONVERSATION, AND ANALYZE MY FAVORITE SOUNDTRACK IN ALL OF GAMING HISTORY, AND YOU PEOPLE CAN'T GET YOUR HEADS OUT OF YOUR ASSES FOR 5 FUCKING SECONDS TO HOLD ANY MODICUM OF FUCKING RESPECT OR APPRECIATION FOR IT WHATSOEVER. FUCK YOU ALL. FUCK YOU. FUCK YOU. --- .../new_player/sprite_accessories/snouts.dm | 4 ++++ modular_citadel/icons/mob/mam_snouts.dmi | Bin 11839 -> 12077 bytes 2 files changed, 4 insertions(+) diff --git a/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm b/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm index be2ab152a8..55bdc31aef 100644 --- a/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm +++ b/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm @@ -244,6 +244,10 @@ name = "Shark" icon_state = "shark" +/datum/sprite_accessory/mam_snouts/hshark + name = "hShark" + icon_state = "hshark" + /datum/sprite_accessory/mam_snouts/toucan name = "Toucan" icon_state = "toucan" diff --git a/modular_citadel/icons/mob/mam_snouts.dmi b/modular_citadel/icons/mob/mam_snouts.dmi index d0f5d5631482270edcfb2562cbb60e7d1304cdcd..80371ce83fb2202d482bd3fd5cf83426ce83eaef 100644 GIT binary patch literal 12077 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 HQ`G+gv&OQx literal 11839 zcmd6t2Urtpx9CzpQxFgv1f)op7L*M_=u(0}2!dEC8l;#|HS`hz z=_Mip3Is58fzV56A+(Twhy9)UoO8Z=pXZ+Mp39SYGn34d8RlL8wbuJv>!pd2?g0T& z0RR9FK=f{!0st?#%QL=r5BS#8+cyIq1O}U1``>i-b9&_FrVIO@ zb^S1Vv87c}IB-Ih7<2Gf<6!-n@}roVz&ELZA^iKPNW5J;z{LAFKtYo@nYHuxaGeHxcFH zKiog=(>G6zx^zCWtp17ny9>byw{AD_#uc7qo|w*i+;qL9?JnUV?^{DPUa8q#JOTa$ z__oq?X41I&F~{c+8#w{qY`^fs>+)ZYd`^1tdh);@fq7qNoAw|iiq1>FmfuuaKjLyQ zbocSkUl-6H#nG?sAHVivz7at;46=UeWL9xws>6Vcyb%mpw7)?JG~)nryw!1^fB4G* zfFuC9sbe0LvOJ>WYByI;qmCVo`0b{Dy!*{B*I!i8?DyWNdtrEK8-0F1(KMhBqO13 zTkal@P~3PdGWS?n_tcLqy}6XPEN0KlzvkyqR%^rhH+8HXR%7c6bw`?E-%FZ>x?hf;mvXl0Cm1k32>#!7D; z{649+J9;X^YD6|m7}1QlB<8N-v~0~a&kInyVP=EtxOl(r$w~4_i=(`q!6Kxyt3kzc zNWRrfK?WYhIcC>WYqH)*))d+BMunZUdoowyL}-2K@Pa0bK^5=GxuMWuq!*bg!FDD* zH?B03Q>7V8=gE^@Zx9LN{vA=l^33 z=P#krcXNyoEE3BY|2)PwdiJr=gP1-v;th$mNQ#1_FYanlsTWK)VB}&;^a%LxB`cc1 zHi+z;Z(HlHMpCladoZR=wHJPNEGL^?;ThK}b}>ZfZX42^C||3vFJ&O7 z@NYM8D2{@Bs+E(p;5U5f;NCEQohB41L3s^|;@pbjcS1_(Y3mtq<=K!ScMhGy7oJ#J zS@*eI91tZ%^&V{7%R`srIt$T$QP`)#wfE#`8leez%1B7fQLVm=uCty-mQT z3(S2TY7sUQX=`0ii^Sqviza3j-OA|(ZNDbCi6+y?^56t&alb>TdG3n6YwIxi%3v&$ z>33VB$)(4)zxGo?+#d1GkXuFwiX8AGbL7XU^7dC_IUdgdhkZ?L#oeva1kW=1+%h~z zx!CwY?z|l}t~uC3nVaG-lbjs3o}}EfdEK*Mo4P$%dttELJ0I%QfLw+>oy8K98sMcO zcHOmYEjs7C&u_KP4IObV01yHrc|$ou00gbfVkD`jb8`wdx~8^HdV1cHw5QI+#cO-r zmD}ItMOTwoW!JSglAj8?i&EHC_4j;=G$zbOe=;ukLT%s&g+7fesa?wM9E;SOiSELM z`bf-0v}}J2tMY(H^rVKReK}ZGSV)J)E89%EPZ{|zRJHgMWi+8SS-Pd9C5ah7XM#H7 zk5G59)|vzjBlWQLK z;l;m`AmDiTukS#S0>^HG!xzb&-`aBo9R52`&3MQ}@D3te>I6rb*`Yq{%SmAi;?MJ2 zGN1tim!~6IWaRZ~+`Lz0AUSs3c6ErH$%}&$>AQ5L5ioyNiDw}&{^O+I{g&DbeH~~c zgQ39u;}~MeX5+Zq0P0=K$9%L~hpmOs(xpZFZo;_fditp3Vf0}P5>d(^7O2dL)17in z>LUhpeyXI@5e5`0#;xlXLhcd|KvW=x5O2NUj3wA=erCbj&LEZ*>sv@L##tI4I|U5*Lp`qeB!_LrvmS6q4Co4a_(R9jwpV^ zz5fkHn2t@yRoh)Jl0~7l2*~>0TsY%mc{4Dc5;Bc&&p)VxIACuT*%K3_5%omu(h%z* zY$3XFm-Cc~lEfoebbUDVEt3Ku}7n{d`-%p3; zesYn)Mt6mq6&-fv0O6iepfx!j=I%cXTH!z1(*BP9c9+@GvyM})(;Ci7jBFV{gp>ct z1bG1CIFcn0TYX{5J{jg>n3Lt9(HCt<9%MMKes+iGPu;a3D9;w<3k1H8U#d?>Jd-(aPAq(;imL)SbfU4AshRqmv(3uprGe&SBcd)}TI&ovWu&B>*-c=c9S7j{(8JtbKI zfIrqEd_bCA@j>k?H(H`eF9FJSDtZRbjF#iHLgaXl-fkL*{f#Spy;8R*I8Aq*Hf$7?N4 zO{Y&n93efpRIb0ooipKY%(7IV@X?jHK*V^uP=9mOid3F|q>h(=_^b@uM zs{?7Lh8(@6J!}7A!v2`0>cOUSaE@7w^XC0JwqnFah{}w)*_&zUs1Y_)k3&;U+of20 zK_fwv>kflKRAT1gRLn#D_sHfcMRN4*UUM^*a+#BdOma;!ncj!ZE-Uol6sdt3%d6hx_B3uUi+PF7 zp&6k&m%l@=-Whh|pwMRbrU{};_hDA_7L`f?7*IwUKWPp4JHaWz_DJ<-c_7n&y(1@A47`j z6D?b47XbQgD|t;CSu|%p$@~zJ)0-M#*s95_>2xJJ0v^F4FeT#BJAZRSh+1#&d(%0* za4W*Hyl)n2Sx@M#7mSxJXWT4=qDJZ5NM&Y&zq0Dg?4Q**u1%qm#*iClI8PTibInHB zyMQHfeYEz%F>l+31rj6~+2jzYQz>oFu$R$sRS8YKda6DfmdGiowzBI^!B&>ZZRpQx zBSs$Gv~^$@|K-)cY46(ok4hl^w?ar;rtJfO!1rtg*L%cISdB&thg#ddxz)8jbCM96 zfmU3^;%}fhjf-pd)h}Hq$0!a_B3h)&A2C~`e?+xi|I)7D8dT<;cv)DcR|Y&UO%Keg z&yZb}R*uEH$Yxd8C9le;jrX#WWDd-3DHhZmeuMUD2y>52KdZhQ+g+YAtd>}-dEQfI z_r{hQ@Z9e5vVC{v(w|0*AX9s0(Pgqd`05TxrG7^W**_%sj>$C~>^`d9rH|C_ioA!3Q@ zo+hYl0nyj*j}<;xOpuN-K*#qY6zcnzJo(05d|=LfIdf(9J?m7DLKS4*`Z-rfO}3Gf zxLh&afNEXsw1`&kDmBzTdhV_E9F{V55{+j?eJVcd)hk`;7s}4)Q$(tMPoG%`$&q^y z^(TK(>7DIy8yjYYti>R>%J?z1&xrdSF}km~6tDB9HyO1MPYm_ope(h8<~hn4dPUZ! zVz@_~=S{QnkGDR7g7jbd>ek59A(|e>=Lb2-!!87LxC1W-ndss4{7=F&3qw&Q& zloi=VTIjK2DLWFngzhPg8WnKpzs?4EWVv`t@HocAlcEgB*Mp4uio#DklDgFuuP9Xe z3%Gg_Db>yLQ*|G-wJ%j<1f97V25Cqb)^AqjoP!+&fQ<8Dr#<9=?xnkb{FSRyp**|( zU*++CUxv1-$jQKY+La|~XdTD-GHo?xAIZh}WRJJrh&!(OdDYrHq7!QV9A@7`JUA`DFp@?`FaM#~w_zP@+6G-)ZqA|g!0IgK{s zu(f#m$4d?uxnd!|=8)iJcJ12bK8tj8ye20n$JQ!ufMn{Sh!y+kqELK5{hI_pc8uw3 z6e2?E9L1k@`?cDK|I?lCT3a!%uCDIpa^={gO_8iD{0AH-Up-7QnY&ro!R`BHwTNyh znKcIQe%5&8Ao#-tQn`gCdQ)kZya(;V0)_)Beg{4|FkEk*!(CB(aQG9)R}fg*O`nBY z?5(k3p8H*h_iqjx4;s)vXvOzmTFPK=LS&4|3}xB8mP}pB_CuUVL(V)}i#{4ou)i|6 zH-xs*S06(A45v7pgq`po)%Nq7#Jp)hQb?NYCCtkJ?XqFbAD1_pdbGB#a@%eIz^XM} zZK4)VDQ0pS5X?Ju^gy+bivu_Vlo67qlNI+kxT{$b0#12iR7>kR?!<0jqi|)kMwWm* zR5!mrndEm7t2QiMf7WVrH`5I~*JpcmqK`R%gW{H`w6Z`vl_l3-#@6ClQV5`Y9X!pH ze-=(Z_Dpz^UD_%cg`);>uQfY`F=`K`G_)t$^=Q4evIDQ>VE?M&3f1s(==P^<9CW|4 zT4v}vrPs>jV@JM*K?6O9DOMyfPOaF~4PTe_DhqwH4$9-1-=VG~)zfq0X@_>yGuCo- zjOAWJ#V#kSIvfu|&tSONLtfTI6#RbPQ(wK-ld5Ovl`9dMn`Wwh3vL%gaj?7UFyH{*E9x|TuErsa#$axA)d9RDT*8#}vRzb?(3=H^=m z_V0IfcFu}k9~No|TMRxXDvFZM@;tt#!Z^YU=JM@rXm%;qawMCXsKx6VFe=ft3^kz& zKT>I}Z5Ti(IIFWq`HO3Zj45Z4Dq-#*&ML0qSED;H^fJB&k6N)Gdj@E| z%G1}{ZH-tTb?y833eS^UGi&s19e0c+7w*}n#?8Op4XQD7ObT$%m%CMN*4%q%IUJ1)ab4bsoZ*OWUE zX6%;z@g1{@&W6i2`*}upNNoE9B^9@P`k;jTw>zGmoPxF;9*J{!%*kN&d#opY{>74U zw&LaDp8mlt=qreZCq#uKJ-E5HHavj;nabVHS@gNAgzyS=N=s9lC^s2f?WxMGW3Rkx z*?ehJ;!raw@p`kZVU2<+-hH&kn}c$xNpu=M7j{*vQ!CKM>0gkm^k|6&H@K0nzQE%I zcCFPNv~!=ZD7 zu0QW6UNCN`0e}Reg;B5X_Fu?VL)G$snF`j~0 zL6f2qu@{|u>dlik8Z7Kp;)?UD8<`A{hXU+Dp?!0q?xy3f6Q!- znv>JWllP9E9;aqjR8h*&sE)DG!~x){bvZ~wrn^GDfXDKHcPY0JeqXMDH;z$HfLX|d z<{s8EpKplC8F}ENugJOYOySU7{>-Dp4Jd7qMA%0KQvn-tD&F{ZsE-q>CBcweRVsLG z$GewW3EYr(PJeb@4}CVX|IW%b9o-(s$dc{$1CloyvpzWa))p>jy~$~uqZ+hv#3fZ$ z;o?+{xU!$VYXOYrE41&-e)E$N4AC0lNL$3f5AOr2-1oEu&8^Rjk`ws0?W@~HCuqgN zN)!m>=A@-W zidsRKX;p!qSUVu@hJ{l%t_Da`C`$s37CR`gEKQ=i+*A58#iEkJB9wwqp$1GK7TXhC)3l1d@bQ!=I zK7H^Gz8Hhxe*^j@-E@c+H>^IUQnz!k4>u%NkPy?KPrlSxlvT~S-vkpX4h3zH6GG3k>Za(7orS^g%xo@O6q&{$DZJ;oS22IKY)-@9+{@ySZ&V z4)duw;+>YSh1ddj^=%muQSG_3w zR&7DkaTwUlqLnL=f50*@(;ckP5mf@vT9WSOeCh$L&?gAm;C5ewr{>9V>Gq8DHckDzkslz1J9(PUTem zgck&bY`S-l*N}2uJB@p*FJP_yG4q^SGOQx^&!&1v^pTS~MHbN|r8TbUWD@Ij1BzmIaGrjg!LCX&D9 zfu;7KonC+|tEGZvW<%@v?CeDIo)=*v_{Z5PG;R<}CiUkFG%P>60{c-3wc=gm&?N_S z^3Nrf&f?yBEG90ga;Gb#)fCB9*xUQ~M2AX7LoExui}wuVLSl}Pb4xuxo~{L5tNMKp zj(ma|Ti#iv_mv7$QYF>ddEL97ZZKqyZL!;8<;;#Hk!g51(cep#GwJ)wXg#SnrA^dZ z^^mvgO&tUEk2Rg|RJj4EFA3Uu!A|9LwVaBuku)pd6R8e9@ud!Hl@Ku3E>nLz%}1&) zSzGet1y*+L$2#)$b=MVvPuRz9!6KIK9r=oKfVKCiz%{=0u_U2zuxOmzOOXaEG0zs% zKSClYx4;SVyp2vp#pa(SKSQgVEwBbAtGe3fIdD8PkWbbnhgbaZN8-Fr9VRvTVYQS3b2D+kdBOR=5ffZBap1uF3 z!Qns43Bc3-@kxp8AwavPdqZJfS47~d1OS*kA?>;bV|DSv4Nz%^Iv*W&Wn2~)UJ!pY z@foi3ytGEvj9tvOOxaKXU-R{yLDTqG#bvWq6d@@8{LA!->Ljyf_mX*0qlV{Gh()mZ z03B~yq~K<1stM<^Kv2T6R*Q#m#S2-r|D zFCi^&d12+b9cbYd{x$tWnxp2bhvgw^F&%j6lYTl=)gV@MLd|01j}o&Y(sunDREa9K zygJLd{>A|{EzJiRGvK78J|2t4cRyB=55C%VH4wKpS6UNChl;#lnO}4=?f30l6!_xm zQAGf<;U^~sJ827 zd-{R3ht&)c`IWWQ*~bZ4v^d~)q&s8?(_Q2-{E8{4S$48`Hqt=KG4Rr`nrRm)UG`N2 zBd+xXSgPtW3PdA|o(5xTj;DlS`Y>KC2>gLgJ1})OKqV#^GKSlVTjr$g74Dx`;LoYH zo?5o{yOMT8d)v>5p+SJ=JMIq~%$U_>i_unE+x;B{YoR7Cb2me#>C?*LStH~biqZLAcfX9~D zKb3KhfTsSBH{pM768dKirH!t6ufTQMQO{&RwEIaZnD}cnU+a02+GT!74Rr1CMu7q_ zo>y89bdNrD2+SxM)eT?_PBoJMVj*VIcyn_L8pv%5{Q~s94ph zSg@#N3Tuzr2Ys|lpMbnaboAnu<_q%V?VDSyRNa360plxR-(HPysvd6o4SWWx*kFbj z7`Svo(9ASbpoxwMcd(3@6+LX?DuCOv`EbRHm|NbLeNKq z5-0ic$t%-c`*OdtUJlRTN$|Id4%|yAAwgQ;*0AaeX=P7tD#AOGmALL%bj8JO=ME(3 zj+@$o2`pF{T#9}68ZF9aVr6$ulD&y-YD*H{zEKxYG9&ihDXdNz)&3(-yw%BM=yFGp zNVb5@k@qiK#a}yvO-NK$_5Qg|g2-L!&pDLVllLg)qg@3udAY5%Vk&ilWO{mqgpjiM zL%;R(iY#1(=2!6U?t{dV7%m*f8CYGNxB-%q{GsYDvE#>o5{ag6t)zVlf1|M ze(LmPB>=i;Kp|iRovfTgU}Lp=k#uj$hy%h=L_)pv16}y z;K9$IcM;6xN;|f0tuLqYcc8Fc@kiz73aO;gr_6g|7|f5T$x^f*LriQ@q7pc>hX>Tn z|4h40_<73UVF;e;t(zIA zgT$5maO_SY^Zn=wq$N|LLTL*W-o^FUp5y9z!n`mGlSTA z6(mM)uuaboxob4O28$B10hIoFw>ym0-UjkVClI8*K_gJtb@~iHrDxOZ_U}N^dL)~% z*(Q#BTMkz0(yYN+V?`q;(c?b=)$|tD>^HT77^j@`QC4JdS4wk5S=i!fc<6f9z}UhG zkHt7(&Uoas=5#2Pku(7!{+%r<&Om)d1c$74YDu9(3{qY-?eoc=7P(!< zWufco8;u7HY}ORcCtNs4u4*c=6gaWo(h{0e1*eb}mU}}FNodv8C_|scppmrdjfEix z|HEym2unw(;#HFgZDs~1(%?K^GZU0_#0{6;jU1W_BuW-fetwCQn;Q2ZA9aYw62raS&bDA3xb{|se(H;78=h{}x4Ud+oTJL~XEL&O zEge6HW3&t07?t3YW;1SFTMGLtOibc=_xwMrV{~mXcXvM|Z8G-*0OHHey5&Cv!-XpV zh*gj6xX3l;&bXrh47;-jwlj|)VD*k;wlzNc;mZ$rK>yE>DIaiE24uI|OqZ_*4jwEX zQoDRPHyxpLe`PE_m9w%-)>$e8mgl0*4* Date: Sun, 12 Jan 2020 12:50:45 +0800 Subject: [PATCH 137/203] string broke --- .../equipment/instruments_lefthand.dmi | Bin 6718 -> 7717 bytes .../equipment/instruments_righthand.dmi | Bin 7264 -> 8201 bytes icons/obj/musician.dmi | Bin 15973 -> 16662 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/mob/inhands/equipment/instruments_lefthand.dmi b/icons/mob/inhands/equipment/instruments_lefthand.dmi index 55f690e4450aae9643699b76bcb706ba276ee2b7..9de54aed6312672fd4d8db72ded2fa70e6066f66 100644 GIT binary patch literal 7717 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 diff --git a/icons/mob/inhands/equipment/instruments_righthand.dmi b/icons/mob/inhands/equipment/instruments_righthand.dmi index 1878fdefe3143ac61efdfa54b0d20773bff83f05..1a3bb055a7b5d16eefbe7311fe864728fabafe37 100644 GIT binary patch literal 8201 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�IZZvs4lg=>_04~3V$gQ3%gk2HFW7C$<){KQZAD}z$Nl}<+Umqk54xQ56x zuduPV6{2ovDgutKe_pxF6!BcouF(J&i|yHU&s##@_Ngy~)dUf+&=W}SN$80=9*JW) z-L{x)DMb*rNXq@Q6#E;!B>TbF-bNy<@3YFq)WgIZ8_`#o*NLwXgP#9X>$z$UI2pPA5S%nJ%Xmu&e(n>s{tD5)K$a|Nux!Gb(1+mk*L z)&4aIGCaW;55H9e0GUpcc4ZG8;xzq$ z%=AzszK|P{E8I=m3p7gPkNfL%)9t;o0FG=N!J1JlaU1u3`jI3Tyy)F>X^8OEtt8ek z+r}O{>l^&|bL;OgDq&D67V+tmMZX*vUjqTSxH*N$LMX8GADG^Te}{Z$Q`#tHkrsqL z2Tyi@w`&TQERfq5m`&ac{KjN%FhSyMob+)01p#OhCV-_i%g`-_;1ltDVJLRT;mUQLn zV#>nYnjH3Vi|BR7UjtS?{(Pk{daQo;)3$cI1j#+o7~%XvK3om?Of4}^@QMr9_V(mK zc2+f?kQ$(4l{ifi&oU@yu!0H!!0S2Fsfcmm8imwA@S`Rw5JiC(MsXley*JW0Y#JTn z#h4qwaot;{KRncCn-R*8HnfZ~*6|-c>3iqjbisTqtI)4E*xiPfuUa-RVA($TFoTH` z@laoR^T!D_vmD#My7i4rKsjq-Uk8uxlmyV|CZv`UTd@37J9d`XuEBiasCE)jLS7G~ z2`1#>W~Ri)(908R#vB_?OMS`Lt+Jkk_vZt}3&>M-5+$D?w|2MT^}9^Pa`|$xyDs)e z(lk0a%me-TvOG_HLftJZVy$kLxU>>`oy&LU#mI;O2i`5}&~eOr&uhW%3$Y_(m!5tP z-&pmImtY3eigfx7N*z&Ca)7xb8~Zqwf-aPPNCBG@{&ZL zkuTAfE|*`sE1eXZh=@hKT=BE}ZR@PFYz-K}DQsX<_1JOMxJZr6VoN&@rVh{YM7kV; zgR+yqwX5?Bbqv#~oP*BVEQCHnpAl(#dWW2gI7A9qDTTfeaAZita$t)?)P9M;1OMH? zF5CkSS{y|h@Kt0fc=5#IZ>Kb9(*?wJS2-J z8hu`$fp<4h`MhKYKXLIsA{-n84j{p}h``om6HM9vi&a#B7#ctQlhbYEu+Y5ih7_;7 zIIb?FKlKg=5PUjPO0+1CzbS(6T%V86Q_Q>x03b;_=<&(=O!Ep@%uo_O%PL45@px7k zObccfM`+fKr}iSFKBc|7kgiHeE!)`~UJ)*vkL)|Ijw_KaiTtgQ4dR>4{m9Ih z;!E(tZMQrL|Cv!wW&d!1D4oc3RpyI#Y@k|^fNQi}u0J`ewP=x9VS zIs-AanNStzF*X#LkR^_Jkpx~qFM64m;xQCL5m0x%NX2laROb7X=_LW#22TWsA^26n z7uuk|jq6i*TbAj)pXU%Cd?f{p#7U!aEMApvouImTindORIkh*?KL6}I$#PSFOS*N) zo#R#BW}c{u;+z)VA4Cb@!ORNnZtD*FT;WdqVx3cq#=kwRK5n>{$Zbh0g{%`^T3T6( zA9U6r5B|4nf4BV?&nt6cukZ&O0b+1pBENRfnm=WumahI}abNzbNS;zM#)w!A*3%i3@1~EBCr4$r-PAvRytoP> zXe5D?mCvmob}&BDDE+q$TkF_M*_+6k00t_WwC+fre5Fa={58wx&X)Ccm*)X;tPsrp z@xaL+G1WyGH#yg!-f!bq@3+3H)IRv8a(r^#IcCrIZ~M`$p%q#<(DP=|*LUa!-kCe( z3jVd>S*2U3uWyS}A}KLU>piXy6Qg^oy3(8<5O+7B9L=rEBH|1ZbC zTZ>!=<9^JYP}ra#3*R?UHxNwpOuK^rbjN!7?O@U{)#Q~+NEc>FzRb3|7@w6Cqm;sD zC;8ZnXT&e7u~X4+CRMLYwtmIPm3uL>$mVQCm26?eH5~YtSik+68W-XQ= z@dIq|sXdX0Rr3Vc>a~|FEf3OFkuq!HNGJ?6_gs6(no0T>@Rd7ge+jHG0wq2Qvf83n zwq2qLac;1NS6dF_Nr$5VgKB5gFvXG$f#1OW2**mYM7_+wN@9>0mZ!VV<#e4CdBXr#}68P=7Vp(0Ui1dR$|L>v9lLnbwG01OLjf z$cEW#0#x}2A5`z6p*hHD9bLU=O(Ug1bJpc|u8{~jNw_C+S(`J>QK<|tgPnhf%~=Rs zUZ{8oQvMn4MJ0Qd5FgJFvhZxXm)6Ii=?S#$rw@ru5Bz@4wJcmq2)KwpVtbsrb*kdJ z7C4K#U!y@j&`!SG!q&lNzbocU*^(@Zsl;Q)Nl6-f?(xjRbUtxqpahEqH_7*RzpcYB z>L=#8rpRu=y7x>sTjM7znqrdK57kX7B52GbBenW5jszvEa`Y z_ce8i@iPqwm6~Xy(z}BZ`kVB{06l1~!r0zijHxU>))^6mNc={jHdrC8^BglW{1fxh zAo7ZJ^mpIMQ+*>bwU5b=y5(VmgT&^>O@Pbr9}S{fWF@89B(|;3o0boZ?XN=1VIxop zbHyf&XQih?MZ=F{*me9uH>DHe1KBnvk}zog1~5KV1-X56mV2uzs};ay;2OTvV7U>t zzr5rBRgD!wzWM&VJa^{RvYzUnffxn-FQH5QuOF*X*=#SuBaL;!vU!Em9JNltjULMVSk&~LA1aY zhMLMSzS%5!8`c$Bp7h5f#?r-7B-wUz5gGjL4_Z)QV~##V-Fy`K*d&e8z8y zNIiQEHKF85nj|jO_|MTY8?;7gAZj%;lc*T@5)^gto(8D6tDaNV4Fo*|rtG@w^`LWh z4*01@W63rB*wnJ2Eq>E0GF&|O*g%n zbEmSN($S1nC%1JC?OWM~MKuW%k-i0rH$5YjsMFY-ZBIY*&*qbCV?yv{h(ND%H_&_( zrOq||o{mo$XJ%Kl;^MC9e_mTtsSL>q<+3JFxa0Zo9tG_a9!xQ7>OLC$zvy)q*{z%VQ(t6y=8%pVRk+xebl=?H6L~)jV|2rU;Lgz#sE(< z-K<=o=MQD>&Hhk|DT$8jD5Zj9j%2RFn5zA>W$@jWf*paN`#nPL-Y4oDt2zW~(Q~E0 zdYhuReL!R9b9ol)Ns1vAW|(1D@);)$uQjLHzW0S!OL=qm6p{UETQd^LTb#qy&wDFG zDomg-{PU-S;B5(sDw>_wdl5s)$>y&C-<(ulzi<+<>93Y4?w6gq!T$7ZVy@ildAIf5 z_2Iu}{pX1>M66dG{TE*qrn2JG%TqEwunD>IhZ@0PW`F^iQvI)fcQR z87&>9;ZRj7@m2)77kv#LD%1aZMLraCo>wbeiI$6|aNT z_f526=#}t5=gX(WIvXqjXI(CJ?3lretvw3qK8^}I5R`}Yw%3e{PhhRx@7vxkDqNAZd|Qs&#fdyKzM3@6&vnn?@2SnVSzO(JVW2^#YF=I zM8x>bO>-pR@MxiD=vX+jB`KZk?_gFvkHQEaR;x9PiJAtnFhN$LcW8qhNt~*?8gNA9 zYYLkpa@3vqay{%0#6b?3Yog;pb3?pZ@s&@AC_M<4A9XN2 z_sXNo9u8-EZ++Cxwo`%&3@Hcz3|q!X01=jz4f1&AFUPp06&t%)T9X?tp87%9;-#Ft zx2j~}t)QDLxd{-idm|0I2C`MhXa$Xu)PQV9X}C+dJv80Y@NznjJ2Z$01R05a@a)kV z1h6<616>IdW4-sQ#Khj}i8~JlM=bTxG*t8^t&cQSmm|)TdpYBvvd6 zk%zqsQRQez`i7TbxbUhU_RwfVPmKYyhAs4B9v^-gAephNcQDt3qhHlEEgNjPF*S!V zLB~=_u+k$~PP*_=JhM5~sh|>@tuDz)&Mroyx9ZP9(X6PjwvIr~p{$V7*X#thZ@cxX zscWCqm$!}f-8wnjXjv?$vJEjbmb=))^^Sm?(9j{o2TKA zkDbhV-d=aw`^xj#m3K|;Ln6(jfTa?`l5AHY4W*ot5;JU;G|Z)3cFWa=UBTc}$qI(t>UHn2+RFv*6hwhz=BVs`-9JZ=2(GLae_|DIJ+uJ1N(0^W*E60TlCcAecxU<|bQEw9aGKBn+L@)X@ zYEKA=R;@*8^xnkA<>uv+O-K-MW(lzyA;>}tQpsA-F3e)vdFcByE2K}OS3tMP^WGdIka$l>)h zSMj<+e}*U2mq!$fSLr?%=K9hjXSQposIIQi=^v2jNii1aO8^__0G4jowidY^F+l;8 zp+Sj(#m|WSD4Kon4(e2ErM6W;*67GEcN6^NyKZy5`opQ_q*up2TPPa@^s}_Pdco$#(hy?(vnYZdj6P!<3)S2Y@G3nC6q9SOq z5)XpkV&CD!X*gV%gAeJed?al6Cd@%!*KPZeV<42P1K)Q7l6^I0tV^~EaUiN$OxVAq zTsxg$*~qA8eE|KY5IQ*so|1g1ZBj${x>He{`M;i9LhA#kSMIkk?5IAr@;h?fy{To8}#0@*cJp!00JzF~hPv763 zoKHl5#RUw$?*Vl<8c0m2Vc5Fx!1Uh*AV1V6S^*towOMu{ Date: Sat, 11 Jan 2020 22:17:18 -0800 Subject: [PATCH 138/203] daddy compiler please stop hating me --- code/controllers/subsystem/vote.dm | 35 ++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index d1c8ec56be..6593c46fbe 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -143,18 +143,18 @@ SUBSYSTEM_DEF(vote) // https://en.wikipedia.org/wiki/Majority_judgment var/list/scores_by_choice = list() for(var/choice in choices) - scores_by_choice += choice - scores_by_choice[choice] = list() + scores_by_choice += "[choice]" + scores_by_choice["[choice]"] = list() for(var/ckey in voted) var/list/this_vote = voted[ckey] var/list/pretty_vote = list() for(var/choice in choices) - if(choice in this_vote && choice in scores_by_choice) - sorted_insert(scores_by_choice[choice],this_vote[choice],/proc/cmp_numeric_asc) + if("[choice]" in this_vote && "[choice]" in scores_by_choice) + sorted_insert(scores_by_choice["[choice]"],this_vote["[choice]"],/proc/cmp_numeric_asc) // START BALLOT GATHERING - pretty_vote += choice - if(this_vote[choice] in GLOB.vote_score_options) - pretty_vote[choice] = GLOB.vote_score_options[this_vote[choice]] + pretty_vote += "[choice]" + if(this_vote["[choice]"] in GLOB.vote_score_options) + pretty_vote["[choice]"] = GLOB.vote_score_options[this_vote["[choice]"]] SSblackbox.record_feedback("associative","voting_ballots",1,pretty_vote) // END BALLOT GATHERING for(var/score_name in scores_by_choice) @@ -190,13 +190,13 @@ SUBSYSTEM_DEF(vote) /datum/controller/subsystem/vote/proc/calculate_scores(var/blackbox_text) var/list/scores_by_choice = list() for(var/choice in choices) - scores_by_choice += choice - scores_by_choice[choice] = list() + scores_by_choice += "[choice]" + scores_by_choice["[choice]"] = list() for(var/ckey in voted) var/list/this_vote = voted[ckey] for(var/choice in choices) - if(choice in this_vote && choice in scores_by_choice) - sorted_insert(scores_by_choice[choice],this_vote[choice],/proc/cmp_numeric_asc) + if("[choice]" in this_vote && "[choice]" in scores_by_choice) + sorted_insert(scores_by_choice["[choice]"],this_vote["[choice]"],/proc/cmp_numeric_asc) var/middle_score = round(GLOB.vote_score_options.len/2,1) for(var/score_name in scores_by_choice) var/list/score = scores_by_choice[score_name] @@ -654,9 +654,20 @@ SUBSYSTEM_DEF(vote) SSpersistence.saved_votes[usr.ckey][mode] = list() voted[usr.ckey] = SSpersistence.saved_votes[usr.ckey][mode] if(islist(voted[usr.ckey])) - saved += usr.ckey + var/malformed = FALSE + if(vote_system == SCORE_VOTING) + for(var/thing in voted[usr.ckey]) + if(!(thing in choices)) + malformed = TRUE + if(!malformed) + saved += usr.ckey + else + to_chat(usr,"Your saved vote was malformed! Start over!") + SSpersistence.saved_votes[usr.ckey] -= mode + voted -= usr.ckey else to_chat(usr,"Your saved vote was malformed! Start over!") + voted -= usr.ckey else if(vote_system == SCORE_VOTING) submit_vote(round(text2num(href_list["vote"])),round(text2num(href_list["score"]))) From f5995cfaaa9fd466670eecfa91de5e2ec8c24a41 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Sun, 12 Jan 2020 00:36:52 -0800 Subject: [PATCH 139/203] this is a massive security risk --- code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm index 5b6d2155c5..97a799824b 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2_wrappers.dm @@ -217,9 +217,6 @@ /proc/_step_away(ref, trg, max) step_away(ref, trg, max) -/proc/_file(name) - return file(name) - /proc/_instantiate_at(thing, location) new thing(location) From 555747df90d1f0ff9ac6bbdc127c4001919c529b Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 12 Jan 2020 02:37:15 -0600 Subject: [PATCH 140/203] Automatic changelog generation for PR #10516 [ci skip] --- html/changelogs/AutoChangeLog-pr-10516.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10516.yml diff --git a/html/changelogs/AutoChangeLog-pr-10516.yml b/html/changelogs/AutoChangeLog-pr-10516.yml new file mode 100644 index 0000000000..39dd05a4db --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10516.yml @@ -0,0 +1,4 @@ +author: "BonniePandora" +delete-after: True +changes: + - admin: "Added another SDQL option. Using \"UPDATE selectors SET #null=value\" will now resolve value and discard the return. This is useful if you only care about the side effect of a proc." From ef00d1522cbb38e9e92e5132472dae43f9e474c6 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 12 Jan 2020 02:37:36 -0600 Subject: [PATCH 141/203] Automatic changelog generation for PR #10513 [ci skip] --- html/changelogs/AutoChangeLog-pr-10513.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10513.yml diff --git a/html/changelogs/AutoChangeLog-pr-10513.yml b/html/changelogs/AutoChangeLog-pr-10513.yml new file mode 100644 index 0000000000..6428c4e281 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10513.yml @@ -0,0 +1,4 @@ +author: "r4d6" +delete-after: True +changes: + - rscadd: "Added a message when pulsing the open wire." From 958abdc51520ec5ec115bfdc5e378c3f478e37e3 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 12 Jan 2020 02:38:46 -0600 Subject: [PATCH 142/203] Automatic changelog generation for PR #10518 [ci skip] --- html/changelogs/AutoChangeLog-pr-10518.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10518.yml diff --git a/html/changelogs/AutoChangeLog-pr-10518.yml b/html/changelogs/AutoChangeLog-pr-10518.yml new file mode 100644 index 0000000000..29de186e50 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10518.yml @@ -0,0 +1,6 @@ +author: "Seris02" +delete-after: True +changes: + - balance: "Explosions now cause knockdown instead of KOs, with the amount of time scaling off bomb armor. Heavy explosions still cause a ~2 second KO for follow up attacks." + - balance: "Devastating explosions now no longer gib players with more than 50 bomb armor. This used to be more or less random depending on the amount of bomb armor." + - code_imp: "Removed reagent explosion code that would trigger for <1 amount reactions." From 58f41ffee211bfc0f80e793f3316e43f61395002 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 12 Jan 2020 02:40:20 -0600 Subject: [PATCH 143/203] Automatic changelog generation for PR #10522 [ci skip] --- html/changelogs/AutoChangeLog-pr-10522.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10522.yml diff --git a/html/changelogs/AutoChangeLog-pr-10522.yml b/html/changelogs/AutoChangeLog-pr-10522.yml new file mode 100644 index 0000000000..b03b990762 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10522.yml @@ -0,0 +1,4 @@ +author: "Hatterhat" +delete-after: True +changes: + - rscadd: "Syndicate sleepers (read: the ones that're red and have controls in them) can now be recreated with a sufficient basis in nonstandard (read: illegal) technologies!" From 33a705e0671abfac2aa65e48880186bf91ca9930 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 12 Jan 2020 02:41:03 -0600 Subject: [PATCH 144/203] Automatic changelog generation for PR #10532 [ci skip] --- html/changelogs/AutoChangeLog-pr-10532.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10532.yml diff --git a/html/changelogs/AutoChangeLog-pr-10532.yml b/html/changelogs/AutoChangeLog-pr-10532.yml new file mode 100644 index 0000000000..cf742b47f7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10532.yml @@ -0,0 +1,6 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Virus food dispensers dispense virus food again." + - bugfix: "Borg hypos inputs do not display typepaths anymore." + - bugfix: "Restored chem dispensers alphabetical order." From f13851704fd9ac7d8c0b0560fe0b012660bdfd0f Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 12 Jan 2020 02:41:50 -0600 Subject: [PATCH 145/203] Automatic changelog generation for PR #10480 [ci skip] --- html/changelogs/AutoChangeLog-pr-10480.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10480.yml diff --git a/html/changelogs/AutoChangeLog-pr-10480.yml b/html/changelogs/AutoChangeLog-pr-10480.yml new file mode 100644 index 0000000000..7ecfd7057e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10480.yml @@ -0,0 +1,4 @@ +author: "Putnam3145" +delete-after: True +changes: + - rscadd: "Second, temporary flavor text!" From d9d0e7c5e7006b430804f5e67c4ffee00a2322e9 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 12 Jan 2020 02:42:21 -0600 Subject: [PATCH 146/203] Automatic changelog generation for PR #10504 [ci skip] --- html/changelogs/AutoChangeLog-pr-10504.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10504.yml diff --git a/html/changelogs/AutoChangeLog-pr-10504.yml b/html/changelogs/AutoChangeLog-pr-10504.yml new file mode 100644 index 0000000000..7e35ac6e72 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10504.yml @@ -0,0 +1,5 @@ +author: "Xantholne" +delete-after: True +changes: + - rscadd: "Botany bee pet, Bumbles" + - rscadd: "New bee models that aren't 1 tile big of 0 opacity pixels" From abd47546315340fc7e797efba4db877340f94d39 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 12 Jan 2020 02:45:23 -0600 Subject: [PATCH 147/203] Automatic changelog generation for PR #10416 [ci skip] --- html/changelogs/AutoChangeLog-pr-10416.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10416.yml diff --git a/html/changelogs/AutoChangeLog-pr-10416.yml b/html/changelogs/AutoChangeLog-pr-10416.yml new file mode 100644 index 0000000000..13432b283c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10416.yml @@ -0,0 +1,10 @@ +author: "r4d6" +delete-after: True +changes: + - rscadd: "Animations for the RCD" + - bugfix: "Said animations being pulled by the Singulo" + - balance: "Prevent Reinforced Doors from being RCD'ed" + - bugfix: "Deconstructing Floors now cost MUs like everything else" + - tweak: "changed the RCD's upgrades into flags" + - rscadd: "Allow RCDs to print APC, Firelocks and Fire Alarms with the right upgrade" + - balance: "Allow Engineers to print RCDs and RPDs from their protolathe without needing to hack one." From ca848e547f1c05c785960b7944bafa1192c150bc Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 12 Jan 2020 02:49:42 -0600 Subject: [PATCH 148/203] Automatic changelog generation for PR #10492 [ci skip] --- html/changelogs/AutoChangeLog-pr-10492.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-10492.yml diff --git a/html/changelogs/AutoChangeLog-pr-10492.yml b/html/changelogs/AutoChangeLog-pr-10492.yml new file mode 100644 index 0000000000..de6ab309ab --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10492.yml @@ -0,0 +1,4 @@ +author: "Trilbyspaceclone" +delete-after: True +changes: + - rscadd: "Glitter is now makeable with ground plastic and some crayons" From be6612fd48cd70f524c9c9038754c563424fce57 Mon Sep 17 00:00:00 2001 From: Hatterhat Date: Sun, 12 Jan 2020 02:55:54 -0600 Subject: [PATCH 149/203] oh my fucking GOD what was i THINKING --- code/modules/research/designs/tool_designs.dm | 40 ++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/code/modules/research/designs/tool_designs.dm b/code/modules/research/designs/tool_designs.dm index 2e40f06537..300fe6c68a 100644 --- a/code/modules/research/designs/tool_designs.dm +++ b/code/modules/research/designs/tool_designs.dm @@ -2,16 +2,46 @@ /////////////////Tools/////////////////// ///////////////////////////////////////// -/datum/design/rcd_upgrade - name = "Advanced RCD designs upgrade" - desc = "Adds the computer frame and machine frame designs to the RCD." - id = "rcd_upgrade" +/datum/design/rcd_upgrade/frames + name = "RCD frames designs upgrade" + desc = "Adds the computer frame and machine frame to the RCD." + id = "rcd_upgrade_frames" build_type = PROTOLATHE materials = list(MAT_METAL = 5000, MAT_GLASS = 2500, MAT_SILVER = 1500, MAT_TITANIUM = 2000) - build_path = /obj/item/rcd_upgrade + build_path = /obj/item/rcd_upgrade/frames category = list("Tool Designs") departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING +/datum/design/rcd_upgrade/simple_circuits + name = "RCD simple circuits designs upgrade" + desc = "Adds the simple circuits to the RCD." + id = "rcd_upgrade_simple_circuits" + build_type = PROTOLATHE + materials = list(MAT_METAL = 5000, MAT_GLASS = 2500, MAT_SILVER = 1500, MAT_TITANIUM = 2000) + build_path = /obj/item/rcd_upgrade/simple_circuits + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/rcd_loaded + name = "Rapid Construction Device" + desc = "A tool that can construct and deconstruct walls, airlocks and floors on the fly." + id = "rcd_loaded" + build_type = PROTOLATHE + materials = list(MAT_METAL = MINERAL_MATERIAL_AMOUNT, MAT_GLASS = MINERAL_MATERIAL_AMOUNT) // costs more than what it did in the autolathe, this one comes loaded. + build_path = /obj/item/construction/rcd/loaded + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + +/datum/design/rpd + name = "Rapid Pipe Dispenser" + desc = "A tool that can construct and deconstruct pipes on the fly." + id = "rpd" + build_type = PROTOLATHE + materials = list(MAT_METAL = 75000, MAT_GLASS = 37500) + build_path = /obj/item/pipe_dispenser + category = list("Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING + /datum/design/handdrill name = "Hand Drill" desc = "A small electric hand drill with an interchangeable screwdriver and bolt bit" From 295c134243eb2eb750a8ae0f406e8391b54e2282 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sun, 12 Jan 2020 03:06:17 -0800 Subject: [PATCH 150/203] i'm so dumb dude --- code/controllers/subsystem/vote.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 6593c46fbe..bb1d1c7e43 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -312,6 +312,7 @@ SUBSYSTEM_DEF(vote) for(var/score_name in stored_modetier_results) if(stored_modetier_results[score_name] <= raw_score_numbers[CONFIG_GET(number/dropped_modes)]) stored_modetier_results -= score_name + stored_modetier_results += "traitor" if("dynamic") if(SSticker.current_state > GAME_STATE_PREGAME)//Don't change the mode if the round already started. return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.") From 3f5e68765ed1324fb02fe8f458d92c1c9f172fb8 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sun, 12 Jan 2020 03:10:42 -0800 Subject: [PATCH 151/203] am i fucking stupid? --- code/controllers/configuration/entries/game_options.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index eea5789a0e..84f0ac1f55 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -396,7 +396,6 @@ config_entry_value = TRUE /datum/config_entry/flag/modetier_voting - config_entry_value = TRUE /datum/config_entry/number/dropped_modes config_entry_value = 3 From 82d8900e5d729bb3862510caa1a1d70ba608cde1 Mon Sep 17 00:00:00 2001 From: Putnam Date: Sun, 12 Jan 2020 03:36:47 -0800 Subject: [PATCH 152/203] aaand move this over --- code/controllers/subsystem/ticker.dm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 0948e428ff..c9562bcfd1 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -188,6 +188,12 @@ SUBSYSTEM_DEF(ticker) tipped = TRUE if(timeLeft <= 0) + if(SSvote.mode && (SSvote.mode == "roundtype" || SSvote.mode == "dynamic" || SSvote.mode == "mode tiers")) + SSvote.result() + SSpersistence.SaveSavedVotes() + for(var/client/C in SSvote.voting) + C << browse(null, "window=vote;can_close=0") + SSvote.reset() current_state = GAME_STATE_SETTING_UP Master.SetRunLevel(RUNLEVEL_SETUP) if(start_immediately) @@ -221,12 +227,6 @@ SUBSYSTEM_DEF(ticker) var/init_start = world.timeofday //Create and announce mode var/list/datum/game_mode/runnable_modes - if(SSvote.mode && (SSvote.mode == "roundtype" || SSvote.mode == "dynamic" || SSvote.mode == "mode tiers")) - SSvote.result() - SSpersistence.SaveSavedVotes() - for(var/client/C in SSvote.voting) - C << browse(null, "window=vote;can_close=0") - SSvote.reset() if(GLOB.master_mode == "random" || GLOB.master_mode == "secret") runnable_modes = config.get_runnable_modes() From 16a37e276922ce88e70483f0a8f44651f9e0241a Mon Sep 17 00:00:00 2001 From: AffectedArc07 Date: Sun, 12 Jan 2020 14:28:01 +0000 Subject: [PATCH 153/203] Standardises all files from CRLF to LF --- code/__DEFINES/admin.dm | 182 +- code/__DEFINES/atmospherics.dm | 596 +- code/__DEFINES/combat.dm | 398 +- code/__DEFINES/components.dm | 696 +- code/__DEFINES/configuration.dm | 18 +- code/__DEFINES/flags.dm | 186 +- code/__DEFINES/jobs.dm | 178 +- code/__DEFINES/machines.dm | 212 +- code/__DEFINES/medal.dm | 56 +- code/__DEFINES/networks.dm | 6 +- code/__DEFINES/preferences.dm | 168 +- code/__DEFINES/research.dm | 150 +- code/__DEFINES/sound.dm | 162 +- code/__DEFINES/stat.dm | 44 +- code/__DEFINES/tgs.config.dm | 20 +- code/__DEFINES/tgs.dm | 482 +- code/__DEFINES/tools.dm | 42 +- code/__DEFINES/wires.dm | 100 +- code/__HELPERS/_lists.dm | 1162 ++-- code/__HELPERS/files.dm | 146 +- code/__HELPERS/game.dm | 1140 ++-- code/__HELPERS/global_lists.dm | 256 +- code/__HELPERS/icons.dm | 2422 +++---- code/__HELPERS/mobs.dm | 1168 ++-- code/__HELPERS/names.dm | 496 +- code/__HELPERS/qdel.dm | 20 +- code/__HELPERS/radio.dm | 38 +- code/__HELPERS/text.dm | 1590 ++--- code/__HELPERS/time.dm | 166 +- code/__HELPERS/type2type.dm | 1262 ++-- code/_compile_options.dm | 114 +- code/_globalvars/bitfields.dm | 428 +- code/_globalvars/configuration.dm | 76 +- code/_globalvars/game_modes.dm | 22 +- code/_globalvars/genetics.dm | 54 +- code/_globalvars/lists/flavor_misc.dm | 446 +- code/_globalvars/lists/mapping.dm | 104 +- code/_globalvars/lists/mobs.dm | 206 +- code/_globalvars/lists/names.dm | 100 +- code/_globalvars/lists/objects.dm | 86 +- code/_globalvars/logging.dm | 128 +- code/_globalvars/misc.dm | 70 +- code/_js/byjax.dm | 96 +- code/_onclick/adjacent.dm | 210 +- code/_onclick/click.dm | 1040 +-- code/_onclick/cyborg.dm | 370 +- code/_onclick/drag_drop.dm | 294 +- code/_onclick/hud/_defines.dm | 330 +- code/_onclick/hud/credits.dm | 138 +- code/_onclick/hud/fullscreen.dm | 362 +- code/_onclick/hud/ghost.dm | 190 +- code/_onclick/hud/hud.dm | 594 +- code/_onclick/hud/human.dm | 1056 +-- code/_onclick/hud/monkey.dm | 330 +- code/_onclick/hud/robot.dm | 614 +- code/_onclick/hud/screen_objects.dm | 1430 ++--- code/_onclick/item_attack.dm | 334 +- code/_onclick/observer.dm | 166 +- code/_onclick/other_mobs.dm | 520 +- .../controllers/configuration/config_entry.dm | 480 +- .../configuration/configuration.dm | 768 +-- .../configuration/entries/comms.dm | 54 +- .../configuration/entries/dbconfig.dm | 102 +- .../configuration/entries/game_options.dm | 804 +-- .../configuration/entries/general.dm | 862 +-- code/controllers/failsafe.dm | 204 +- code/controllers/globals.dm | 110 +- code/controllers/subsystem/atoms.dm | 302 +- code/controllers/subsystem/blackbox.dm | 670 +- code/controllers/subsystem/dbcore.dm | 730 +-- code/controllers/subsystem/medals.dm | 174 +- code/controllers/subsystem/moods.dm | 8 +- code/controllers/subsystem/nightshift.dm | 110 +- code/controllers/subsystem/npcpool.dm | 68 +- code/controllers/subsystem/pathfinder.dm | 96 +- .../subsystem/processing/networks.dm | 102 +- .../subsystem/processing/projectiles.dm | 46 +- .../subsystem/processing/wet_floors.dm | 14 +- code/controllers/subsystem/research.dm | 1060 +-- code/controllers/subsystem/spacedrift.dm | 118 +- code/controllers/subsystem/vote.dm | 1352 ++-- code/datums/actions/flightsuit.dm | 234 +- code/datums/actions/ninja.dm | 102 +- code/datums/ai_laws.dm | 928 +-- code/datums/browser.dm | 930 +-- code/datums/components/_component.dm | 628 +- code/datums/components/jousting.dm | 148 +- code/datums/components/lockon_aiming.dm | 478 +- code/datums/components/ntnet_interface.dm | 136 +- code/datums/components/riding.dm | 718 +-- code/datums/components/slippery.dm | 30 +- .../components/storage/concrete/_concrete.dm | 416 +- .../storage/concrete/bag_of_holding.dm | 72 +- .../components/storage/concrete/implant.dm | 36 +- .../components/storage/concrete/rped.dm | 72 +- code/datums/components/storage/storage.dm | 1600 ++--- code/datums/components/wet_floor.dm | 422 +- code/datums/datacore.dm | 592 +- code/datums/datum.dm | 320 +- code/datums/datumvars.dm | 2860 ++++----- code/datums/diseases/advance/advance.dm | 990 +-- code/datums/diseases/advance/presets.dm | 82 +- .../datums/diseases/advance/symptoms/beard.dm | 102 +- .../diseases/advance/symptoms/choking.dm | 296 +- .../diseases/advance/symptoms/confusion.dm | 122 +- .../datums/diseases/advance/symptoms/cough.dm | 150 +- .../diseases/advance/symptoms/deafness.dm | 118 +- .../datums/diseases/advance/symptoms/dizzy.dm | 104 +- .../datums/diseases/advance/symptoms/fever.dm | 120 +- .../diseases/advance/symptoms/flesh_eating.dm | 258 +- .../diseases/advance/symptoms/genetics.dm | 156 +- .../diseases/advance/symptoms/hallucigen.dm | 130 +- .../diseases/advance/symptoms/headache.dm | 118 +- code/datums/diseases/advance/symptoms/heal.dm | 970 +-- .../diseases/advance/symptoms/itching.dm | 106 +- .../diseases/advance/symptoms/oxygen.dm | 134 +- .../diseases/advance/symptoms/shedding.dm | 110 +- .../diseases/advance/symptoms/shivering.dm | 116 +- .../diseases/advance/symptoms/sneeze.dm | 102 +- .../diseases/advance/symptoms/symptoms.dm | 160 +- .../diseases/advance/symptoms/voice_change.dm | 162 +- .../datums/diseases/advance/symptoms/vomit.dm | 126 +- .../diseases/advance/symptoms/weight.dm | 100 +- .../datums/diseases/advance/symptoms/youth.dm | 114 +- code/datums/diseases/appendicitis.dm | 72 +- code/datums/diseases/beesease.dm | 76 +- code/datums/diseases/brainrot.dm | 118 +- code/datums/diseases/cold.dm | 104 +- code/datums/diseases/cold9.dm | 76 +- code/datums/diseases/dna_spread.dm | 148 +- code/datums/diseases/fake_gbs.dm | 64 +- code/datums/diseases/flu.dm | 108 +- code/datums/diseases/fluspanish.dm | 72 +- code/datums/diseases/gbs.dm | 62 +- code/datums/diseases/magnitis.dm | 134 +- code/datums/diseases/pierrot_throat.dm | 108 +- code/datums/diseases/retrovirus.dm | 166 +- code/datums/diseases/rhumba_beat.dm | 90 +- code/datums/diseases/transformation.dm | 654 +- code/datums/diseases/wizarditis.dm | 234 +- code/datums/dna.dm | 870 +-- code/datums/forced_movement.dm | 180 +- code/datums/helper_datums/getrev.dm | 242 +- code/datums/helper_datums/teleport.dm | 334 +- code/datums/helper_datums/topic_input.dm | 124 +- code/datums/holocall.dm | 704 +- code/datums/hud.dm | 260 +- code/datums/map_config.dm | 326 +- code/datums/mind.dm | 1560 ++--- code/datums/mood_events/drug_events.dm | 230 +- code/datums/mood_events/mood_event.dm | 40 +- code/datums/mood_events/needs_events.dm | 124 +- code/datums/position_point_vector.dm | 450 +- code/datums/spawners_menu.dm | 106 +- code/datums/verbs.dm | 204 +- code/datums/wires/airlock.dm | 372 +- code/datums/wires/mulebot.dm | 60 +- code/datums/wires/particle_accelerator.dm | 94 +- code/datums/wires/robot.dm | 172 +- code/datums/wires/syndicatebomb.dm | 184 +- code/game/area/Space_Station_13_areas.dm | 2704 ++++---- code/game/area/ai_monitored.dm | 60 +- code/game/atoms.dm | 1730 ++--- code/game/atoms_movable.dm | 1748 ++--- code/game/communications.dm | 398 +- code/game/gamemodes/brother/traitor_bro.dm | 144 +- code/game/gamemodes/changeling/changeling.dm | 254 +- .../game/gamemodes/changeling/traitor_chan.dm | 168 +- code/game/gamemodes/events.dm | 164 +- code/game/gamemodes/extended/extended.dm | 64 +- code/game/gamemodes/game_mode.dm | 1212 ++-- code/game/gamemodes/meteor/meteor.dm | 118 +- code/game/gamemodes/objective_items.dm | 530 +- code/game/gamemodes/sandbox/airlock_maker.dm | 282 +- code/game/gamemodes/sandbox/h_sandbox.dm | 606 +- code/game/gamemodes/sandbox/sandbox.dm | 42 +- code/game/gamemodes/traitor/double_agents.dm | 164 +- code/game/gamemodes/traitor/traitor.dm | 198 +- code/game/gamemodes/wizard/wizard.dm | 146 +- code/game/machinery/Beacon.dm | 96 +- code/game/machinery/PDApainter.dm | 286 +- code/game/machinery/Sleeper.dm | 824 +-- code/game/machinery/ai_slipper.dm | 96 +- code/game/machinery/airlock_control.dm | 326 +- code/game/machinery/autolathe.dm | 764 +-- code/game/machinery/buttons.dm | 536 +- code/game/machinery/camera/camera_assembly.dm | 296 +- code/game/machinery/camera/motion.dm | 154 +- code/game/machinery/camera/presets.dm | 178 +- code/game/machinery/camera/tracking.dm | 302 +- code/game/machinery/cell_charger.dm | 260 +- code/game/machinery/cloning.dm | 1112 ++-- code/game/machinery/computer/Operating.dm | 256 +- code/game/machinery/computer/aifixer.dm | 300 +- code/game/machinery/computer/atmos_alert.dm | 200 +- code/game/machinery/computer/atmos_control.dm | 610 +- .../game/machinery/computer/buildandrepair.dm | 290 +- code/game/machinery/computer/camera.dm | 508 +- code/game/machinery/computer/card.dm | 1260 ++-- code/game/machinery/computer/cloning.dm | 1028 +-- .../game/machinery/computer/communications.dm | 1518 ++--- code/game/machinery/computer/crew.dm | 418 +- code/game/machinery/computer/law.dm | 142 +- code/game/machinery/computer/medical.dm | 1170 ++-- code/game/machinery/computer/pod.dm | 266 +- code/game/machinery/computer/robot.dm | 330 +- code/game/machinery/computer/security.dm | 1624 ++--- code/game/machinery/computer/station_alert.dm | 196 +- .../machinery/computer/telecrystalconsoles.dm | 430 +- code/game/machinery/constructable_frame.dm | 558 +- code/game/machinery/doors/alarmlock.dm | 84 +- code/game/machinery/doors/brigdoors.dm | 512 +- code/game/machinery/doors/door.dm | 770 +-- code/game/machinery/doors/firedoor.dm | 952 +-- code/game/machinery/doors/poddoor.dm | 182 +- code/game/machinery/doors/shutters.dm | 26 +- code/game/machinery/doors/unpowered.dm | 42 +- code/game/machinery/doors/windowdoor.dm | 1070 ++-- code/game/machinery/doppler_array.dm | 374 +- .../embedded_controller/access_controller.dm | 630 +- .../embedded_controller/airlock_controller.dm | 628 +- .../embedded_controller_base.dm | 174 +- .../simple_vent_controller.dm | 144 +- code/game/machinery/flasher.dm | 410 +- code/game/machinery/hologram.dm | 1400 ++-- code/game/machinery/igniter.dm | 274 +- code/game/machinery/lightswitch.dm | 134 +- code/game/machinery/magnet.dm | 760 +-- code/game/machinery/mass_driver.dm | 76 +- code/game/machinery/navbeacon.dm | 428 +- code/game/machinery/pipe/construction.dm | 472 +- code/game/machinery/pipe/pipe_dispenser.dm | 424 +- .../machinery/porta_turret/portable_turret.dm | 2186 +++---- code/game/machinery/recharger.dm | 326 +- code/game/machinery/rechargestation.dm | 270 +- code/game/machinery/recycler.dm | 424 +- code/game/machinery/requests_console.dm | 1068 ++-- code/game/machinery/status_display.dm | 736 +-- code/game/machinery/suit_storage_unit.dm | 886 +-- code/game/machinery/syndicatebeacon.dm | 330 +- .../machinery/telecomms/computers/message.dm | 932 +-- .../telecomms/machines/message_server.dm | 360 +- .../machinery/telecomms/telecomunications.dm | 304 +- code/game/machinery/washing_machine.dm | 568 +- code/game/machinery/wishgranter.dm | 86 +- code/game/mecha/combat/combat.dm | 20 +- code/game/mecha/combat/durand.dm | 42 +- code/game/mecha/combat/gygax.dm | 136 +- code/game/mecha/combat/honker.dm | 310 +- code/game/mecha/combat/marauder.dm | 188 +- code/game/mecha/combat/phazon.dm | 58 +- code/game/mecha/combat/reticence.dm | 58 +- code/game/mecha/equipment/mecha_equipment.dm | 334 +- .../mecha/equipment/tools/medical_tools.dm | 1110 ++-- code/game/mecha/equipment/weapons/weapons.dm | 888 +-- code/game/mecha/mech_fabricator.dm | 848 +-- code/game/mecha/mecha.dm | 2134 +++--- code/game/mecha/mecha_construction_paths.dm | 3546 +++++----- code/game/mecha/mecha_control_console.dm | 284 +- code/game/mecha/mecha_parts.dm | 678 +- code/game/mecha/mecha_wreckage.dm | 506 +- code/game/mecha/medical/odysseus.dm | 62 +- code/game/mecha/working/ripley.dm | 396 +- code/game/objects/effects/bump_teleporter.dm | 74 +- code/game/objects/effects/decals/cleanable.dm | 192 +- .../effects/decals/cleanable/aliens.dm | 138 +- .../effects/decals/cleanable/humans.dm | 384 +- .../objects/effects/decals/cleanable/misc.dm | 470 +- .../effects/decals/cleanable/robots.dm | 130 +- code/game/objects/effects/decals/crayon.dm | 62 +- code/game/objects/effects/decals/decal.dm | 96 +- code/game/objects/effects/decals/misc.dm | 62 +- code/game/objects/effects/decals/remains.dm | 66 +- .../effects/effect_system/effects_foam.dm | 694 +- .../effects/effect_system/effects_smoke.dm | 656 +- code/game/objects/effects/forcefields.dm | 74 +- code/game/objects/effects/landmarks.dm | 966 +-- code/game/objects/effects/mines.dm | 352 +- code/game/objects/effects/misc.dm | 186 +- code/game/objects/effects/portals.dm | 370 +- code/game/objects/effects/proximity.dm | 224 +- .../objects/effects/spawners/bombspawner.dm | 130 +- .../objects/effects/spawners/gibspawner.dm | 480 +- .../game/objects/effects/spawners/lootdrop.dm | 760 +-- code/game/objects/effects/spiders.dm | 474 +- code/game/objects/effects/step_triggers.dm | 398 +- code/game/objects/empulse.dm | 62 +- code/game/objects/items.dm | 1702 ++--- code/game/objects/items/AI_modules.dm | 1230 ++-- code/game/objects/items/airlock_painter.dm | 254 +- code/game/objects/items/bodybag.dm | 166 +- code/game/objects/items/candle.dm | 160 +- code/game/objects/items/cards_ids.dm | 1086 ++-- code/game/objects/items/cigs_lighters.dm | 2132 +++--- code/game/objects/items/clown_items.dm | 364 +- code/game/objects/items/cosmetics.dm | 380 +- code/game/objects/items/devices/PDA/PDA.dm | 2348 +++---- code/game/objects/items/devices/PDA/cart.dm | 1554 ++--- code/game/objects/items/devices/PDA/radio.dm | 76 +- code/game/objects/items/devices/aicard.dm | 208 +- code/game/objects/items/devices/camera_bug.dm | 616 +- code/game/objects/items/devices/flashlight.dm | 1092 ++-- code/game/objects/items/devices/gps.dm | 456 +- .../game/objects/items/devices/instruments.dm | 554 +- .../objects/items/devices/laserpointer.dm | 378 +- .../objects/items/devices/lightreplacer.dm | 544 +- code/game/objects/items/devices/multitool.dm | 532 +- code/game/objects/items/devices/paicard.dm | 338 +- code/game/objects/items/devices/powersink.dm | 304 +- .../items/devices/radio/electropack.dm | 292 +- .../objects/items/devices/radio/headset.dm | 674 +- .../objects/items/devices/radio/intercom.dm | 300 +- .../game/objects/items/devices/radio/radio.dm | 858 +-- code/game/objects/items/devices/scanners.dm | 1558 ++--- .../objects/items/devices/taperecorder.dm | 582 +- .../objects/items/devices/transfer_valve.dm | 474 +- code/game/objects/items/dice.dm | 394 +- code/game/objects/items/dna_injector.dm | 738 +-- code/game/objects/items/extinguisher.dm | 514 +- .../objects/items/grenades/chem_grenade.dm | 1204 ++-- code/game/objects/items/grenades/flashbang.dm | 88 +- .../game/objects/items/grenades/ghettobomb.dm | 120 +- code/game/objects/items/grenades/grenade.dm | 248 +- code/game/objects/items/grenades/smokebomb.dm | 62 +- .../objects/items/grenades/syndieminibomb.dm | 100 +- code/game/objects/items/handcuffs.dm | 752 +-- code/game/objects/items/hot_potato.dm | 342 +- code/game/objects/items/implants/implant.dm | 228 +- .../objects/items/implants/implantcase.dm | 166 +- .../objects/items/implants/implantchair.dm | 384 +- code/game/objects/items/implants/implanter.dm | 152 +- code/game/objects/items/kitchen.dm | 366 +- code/game/objects/items/manuals.dm | 1012 +-- code/game/objects/items/melee/energy.dm | 772 +-- code/game/objects/items/paiwire.dm | 26 +- code/game/objects/items/robot/robot_items.dm | 1822 +++--- code/game/objects/items/robot/robot_parts.dm | 826 +-- .../objects/items/robot/robot_upgrades.dm | 1452 ++--- code/game/objects/items/scrolls.dm | 146 +- code/game/objects/items/shields.dm | 366 +- code/game/objects/items/shooting_range.dm | 192 +- code/game/objects/items/singularityhammer.dm | 230 +- code/game/objects/items/stacks/bscrystal.dm | 178 +- code/game/objects/items/stacks/medical.dm | 310 +- code/game/objects/items/stacks/rods.dm | 174 +- .../game/objects/items/stacks/sheets/glass.dm | 688 +- .../objects/items/stacks/sheets/leather.dm | 496 +- .../game/objects/items/stacks/sheets/light.dm | 70 +- .../objects/items/stacks/sheets/sheets.dm | 34 +- code/game/objects/items/storage/backpack.dm | 1240 ++-- code/game/objects/items/storage/bags.dm | 836 +-- code/game/objects/items/storage/belt.dm | 1586 ++--- code/game/objects/items/storage/boxes.dm | 2538 ++++---- code/game/objects/items/storage/briefcase.dm | 230 +- code/game/objects/items/storage/fancy.dm | 708 +- code/game/objects/items/storage/lockbox.dm | 400 +- code/game/objects/items/storage/secure.dm | 376 +- code/game/objects/items/storage/storage.dm | 56 +- code/game/objects/items/storage/toolbox.dm | 664 +- .../game/objects/items/storage/uplink_kits.dm | 798 +-- code/game/objects/items/stunbaton.dm | 506 +- code/game/objects/items/tanks/tank_types.dm | 350 +- code/game/objects/items/teleportation.dm | 480 +- code/game/objects/items/tools/crowbar.dm | 204 +- code/game/objects/items/tools/screwdriver.dm | 314 +- code/game/objects/items/tools/wirecutters.dm | 292 +- code/game/objects/items/tools/wrench.dm | 248 +- code/game/objects/items/trash.dm | 162 +- code/game/objects/items/vending_items.dm | 102 +- code/game/objects/items/weaponry.dm | 1376 ++-- code/game/objects/objs.dm | 498 +- code/game/objects/structures.dm | 222 +- code/game/objects/structures/ai_core.dm | 658 +- code/game/objects/structures/bedsheet_bin.dm | 796 +-- .../structures/crates_lockers/closets.dm | 1232 ++-- .../crates_lockers/closets/gimmick.dm | 218 +- .../crates_lockers/closets/job_closets.dm | 732 +-- .../crates_lockers/closets/secure/bar.dm | 26 +- .../crates_lockers/closets/secure/cargo.dm | 52 +- .../closets/secure/engineering.dm | 258 +- .../crates_lockers/closets/secure/freezer.dm | 212 +- .../closets/secure/hydroponics.dm | 24 +- .../crates_lockers/closets/secure/medical.dm | 214 +- .../crates_lockers/closets/secure/personal.dm | 150 +- .../closets/secure/scientist.dm | 68 +- .../closets/secure/secure_closets.dm | 24 +- .../crates_lockers/closets/secure/security.dm | 586 +- .../crates_lockers/closets/syndicate.dm | 240 +- .../crates_lockers/closets/utility_closets.dm | 398 +- .../structures/crates_lockers/crates.dm | 446 +- .../structures/crates_lockers/crates/bins.dm | 88 +- .../crates_lockers/crates/critter.dm | 74 +- .../structures/crates_lockers/crates/large.dm | 84 +- .../crates_lockers/crates/secure.dm | 144 +- code/game/objects/structures/displaycase.dm | 698 +- code/game/objects/structures/dresser.dm | 164 +- code/game/objects/structures/electricchair.dm | 92 +- code/game/objects/structures/extinguisher.dm | 312 +- code/game/objects/structures/flora.dm | 854 +-- code/game/objects/structures/hivebot.dm | 72 +- code/game/objects/structures/kitchen_spike.dm | 312 +- code/game/objects/structures/ladders.dm | 462 +- code/game/objects/structures/loom.dm | 86 +- code/game/objects/structures/manned_turret.dm | 432 +- code/game/objects/structures/mineral_doors.dm | 516 +- code/game/objects/structures/mirror.dm | 478 +- code/game/objects/structures/mop_bucket.dm | 56 +- code/game/objects/structures/morgue.dm | 772 +-- code/game/objects/structures/musician.dm | 762 +-- code/game/objects/structures/noticeboard.dm | 264 +- code/game/objects/structures/safe.dm | 422 +- code/game/objects/structures/tables_racks.dm | 1400 ++-- .../game/objects/structures/tank_dispenser.dm | 222 +- code/game/objects/structures/target_stake.dm | 152 +- .../transit_tube_construction.dm | 266 +- .../objects/structures/windoor_assembly.dm | 714 +-- code/game/shuttle_engines.dm | 312 +- code/game/world.dm | 638 +- code/modules/NTNet/services/_service.dm | 76 +- code/modules/admin/DB_ban/functions.dm | 1122 ++-- code/modules/admin/IsBanned.dm | 416 +- code/modules/admin/NewBan.dm | 476 +- code/modules/admin/admin.dm | 2022 +++--- code/modules/admin/admin_investigate.dm | 44 +- code/modules/admin/admin_ranks.dm | 612 +- code/modules/admin/banjob.dm | 80 +- code/modules/admin/chat_commands.dm | 286 +- code/modules/admin/create_mob.dm | 92 +- code/modules/admin/create_object.dm | 64 +- code/modules/admin/create_turf.dm | 20 +- code/modules/admin/holder2.dm | 420 +- code/modules/admin/player_panel.dm | 626 +- code/modules/admin/topic.dm | 5696 ++++++++--------- code/modules/admin/verbs/adminhelp.dm | 1398 ++-- code/modules/admin/verbs/adminjump.dm | 314 +- code/modules/admin/verbs/adminpm.dm | 650 +- code/modules/admin/verbs/adminsay.dm | 44 +- code/modules/admin/verbs/atmosdebug.dm | 82 +- code/modules/admin/verbs/cinematic.dm | 20 +- code/modules/admin/verbs/deadsay.dm | 72 +- code/modules/admin/verbs/fps.dm | 52 +- code/modules/admin/verbs/getlogs.dm | 68 +- code/modules/admin/verbs/mapping.dm | 754 +-- code/modules/admin/verbs/massmodvar.dm | 530 +- code/modules/admin/verbs/modifyvariables.dm | 1286 ++-- code/modules/admin/verbs/onlyone.dm | 60 +- code/modules/admin/verbs/playsound.dm | 406 +- code/modules/admin/verbs/possess.dm | 106 +- code/modules/admin/verbs/pray.dm | 150 +- code/modules/admin/verbs/randomverbs.dm | 2786 ++++---- code/modules/admin/whitelist.dm | 46 +- .../antagonists/_common/antag_spawner.dm | 564 +- .../antagonists/blob/blob/blobs/shield.dm | 126 +- .../changeling/changeling_power.dm | 168 +- .../antagonists/changeling/powers/absorb.dm | 234 +- .../changeling/powers/fakedeath.dm | 86 +- .../antagonists/changeling/powers/revive.dm | 88 +- .../antagonists/changeling/powers/spiders.dm | 32 +- .../changeling/powers/tiny_prick.dm | 532 +- code/modules/antagonists/revenant/revenant.dm | 2 +- .../antagonists/wizard/equipment/artefact.dm | 890 +-- .../antagonists/wizard/equipment/spellbook.dm | 1570 ++--- code/modules/assembly/assembly.dm | 254 +- code/modules/assembly/bomb.dm | 404 +- code/modules/assembly/flash.dm | 730 +-- code/modules/assembly/helpers.dm | 30 +- code/modules/assembly/holder.dm | 278 +- code/modules/assembly/igniter.dm | 82 +- code/modules/assembly/infrared.dm | 478 +- code/modules/assembly/mousetrap.dm | 284 +- code/modules/assembly/proximity.dm | 320 +- code/modules/assembly/shock_kit.dm | 78 +- code/modules/assembly/signaler.dm | 416 +- code/modules/assembly/timer.dm | 270 +- code/modules/assembly/voice.dm | 208 +- .../atmospherics/gasmixtures/gas_mixture.dm | 808 +-- .../gasmixtures/immutable_mixtures.dm | 148 +- .../atmospherics/machinery/atmosmachinery.dm | 714 +-- .../binary_devices/binary_devices.dm | 62 +- .../components/binary_devices/circulator.dm | 380 +- .../components/binary_devices/dp_vent_pump.dm | 506 +- .../trinary_devices/trinary_devices.dm | 96 +- .../components/unary_devices/cryo.dm | 892 +-- .../components/unary_devices/vent_scrubber.dm | 656 +- .../atmospherics/machinery/other/meter.dm | 296 +- .../machinery/pipes/layermanifold.dm | 254 +- .../portable/portable_atmospherics.dm | 312 +- .../atmospherics/machinery/portable/pump.dm | 312 +- .../machinery/portable/scrubber.dm | 288 +- .../awaymissions/bluespaceartillery.dm | 110 +- code/modules/awaymissions/exile.dm | 24 +- code/modules/awaymissions/gateway.dm | 510 +- .../awaymissions/mission_code/Academy.dm | 696 +- .../awaymissions/mission_code/centcomAway.dm | 124 +- .../awaymissions/mission_code/wildwest.dm | 340 +- code/modules/awaymissions/pamphlet.dm | 78 +- code/modules/awaymissions/zlevel.dm | 122 +- code/modules/cargo/console.dm | 456 +- code/modules/cargo/expressconsole.dm | 412 +- code/modules/cargo/order.dm | 220 +- code/modules/client/asset_cache.dm | 1362 ++-- code/modules/client/client_defines.dm | 164 +- code/modules/client/preferences_toggles.dm | 834 +-- code/modules/client/verbs/etips.dm | 40 +- code/modules/clothing/clothing.dm | 912 +-- code/modules/clothing/glasses/_glasses.dm | 922 +-- code/modules/clothing/glasses/hud.dm | 454 +- code/modules/clothing/gloves/_gloves.dm | 84 +- code/modules/clothing/gloves/boxing.dm | 38 +- code/modules/clothing/gloves/color.dm | 440 +- code/modules/clothing/gloves/miscellaneous.dm | 210 +- code/modules/clothing/head/_head.dm | 124 +- code/modules/clothing/head/collectable.dm | 308 +- code/modules/clothing/head/hardhat.dm | 320 +- code/modules/clothing/head/helmet.dm | 728 +-- code/modules/clothing/head/jobs.dm | 746 +-- code/modules/clothing/head/misc.dm | 846 +-- code/modules/clothing/head/misc_special.dm | 624 +- code/modules/clothing/head/soft_caps.dm | 284 +- code/modules/clothing/masks/_masks.dm | 144 +- code/modules/clothing/masks/breath.dm | 84 +- code/modules/clothing/masks/gasmask.dm | 406 +- code/modules/clothing/masks/miscellaneous.dm | 642 +- code/modules/clothing/shoes/_shoes.dm | 202 +- code/modules/clothing/shoes/magboots.dm | 118 +- .../clothing/spacesuits/_spacesuits.dm | 98 +- .../clothing/spacesuits/miscellaneous.dm | 888 +-- code/modules/clothing/spacesuits/syndi.dm | 298 +- code/modules/clothing/suits/_suits.dm | 68 +- code/modules/clothing/suits/bio.dm | 180 +- code/modules/clothing/suits/jobs.dm | 438 +- code/modules/clothing/suits/labcoat.dm | 140 +- code/modules/clothing/suits/miscellaneous.dm | 1816 +++--- code/modules/clothing/suits/utility.dm | 314 +- code/modules/clothing/suits/wiz_robe.dm | 456 +- code/modules/clothing/under/_under.dm | 294 +- code/modules/clothing/under/color.dm | 534 +- code/modules/clothing/under/jobs/civilian.dm | 848 +-- .../clothing/under/jobs/engineering.dm | 162 +- code/modules/clothing/under/jobs/medsci.dm | 414 +- code/modules/clothing/under/jobs/security.dm | 400 +- code/modules/clothing/under/pants.dm | 216 +- code/modules/clothing/under/shorts.dm | 72 +- code/modules/clothing/under/syndicate.dm | 178 +- code/modules/detectivework/detective_work.dm | 212 +- code/modules/detectivework/evidence.dm | 190 +- code/modules/detectivework/scanner.dm | 436 +- code/modules/events/anomaly.dm | 96 +- code/modules/events/anomaly_bluespace.dm | 44 +- code/modules/events/anomaly_flux.dm | 46 +- code/modules/events/anomaly_grav.dm | 44 +- code/modules/events/anomaly_vortex.dm | 46 +- code/modules/events/blob.dm | 68 +- code/modules/events/brand_intelligence.dm | 178 +- code/modules/events/carp_migration.dm | 62 +- .../modules/events/communications_blackout.dm | 54 +- code/modules/events/disease_outbreak.dm | 154 +- code/modules/events/dust.dm | 62 +- code/modules/events/electrical_storm.dm | 72 +- code/modules/events/false_alarm.dm | 124 +- code/modules/events/holiday/halloween.dm | 124 +- code/modules/events/immovable_rod.dm | 328 +- code/modules/events/ion_storm.dm | 1186 ++-- code/modules/events/mass_hallucination.dm | 78 +- code/modules/events/meateor_wave.dm | 22 +- code/modules/events/meteor_wave.dm | 182 +- code/modules/events/prison_break.dm | 126 +- code/modules/events/processor_overload.dm | 78 +- code/modules/events/radiation_storm.dm | 40 +- code/modules/events/spacevine.dm | 1096 ++-- code/modules/events/spider_infestation.dm | 80 +- .../events/spontaneous_appendicitis.dm | 64 +- code/modules/events/vent_clog.dm | 424 +- code/modules/fields/timestop.dm | 324 +- code/modules/flufftext/Dreaming.dm | 138 +- code/modules/food_and_drinks/pizzabox.dm | 692 +- code/modules/holodeck/items.dm | 456 +- code/modules/hydroponics/biogenerator.dm | 654 +- code/modules/hydroponics/grown.dm | 338 +- code/modules/hydroponics/growninedible.dm | 124 +- code/modules/hydroponics/hydroitemdefines.dm | 388 +- code/modules/hydroponics/hydroponics.dm | 1960 +++--- code/modules/hydroponics/seed_extractor.dm | 384 +- code/modules/hydroponics/seeds.dm | 936 +-- .../integrated_electronics/core/debugger.dm | 168 +- .../integrated_electronics/core/wirer.dm | 202 +- .../subtypes/atmospherics.dm | 1520 ++--- code/modules/jobs/job_types/assistant.dm | 86 +- code/modules/jobs/jobs.dm | 252 +- code/modules/jobs/map_changes/map_changes.dm | 6 +- code/modules/language/common.dm | 144 +- code/modules/language/language.dm | 240 +- code/modules/language/machine.dm | 38 +- code/modules/language/monkey.dm | 24 +- code/modules/language/xenocommon.dm | 22 +- code/modules/library/lib_items.dm | 704 +- code/modules/library/lib_machines.dm | 1214 ++-- code/modules/library/random_books.dm | 174 +- code/modules/lighting/lighting_source.dm | 622 +- code/modules/mapping/ruins.dm | 342 +- .../space_management/space_reservation.dm | 170 +- code/modules/mining/equipment/mining_tools.dm | 308 +- .../mining/equipment/regenerative_core.dm | 294 +- code/modules/mining/laborcamp/laborshuttle.dm | 52 +- code/modules/mining/laborcamp/laborstacker.dm | 314 +- code/modules/mining/machine_processing.dm | 422 +- code/modules/mining/machine_stacking.dm | 242 +- code/modules/mining/machine_unloading.dm | 60 +- code/modules/mining/mint.dm | 210 +- code/modules/mining/ores_coins.dm | 974 +-- code/modules/mining/satchel_ore_boxdm.dm | 178 +- code/modules/mob/camera/camera.dm | 74 +- code/modules/mob/dead/dead.dm | 258 +- code/modules/mob/dead/new_player/login.dm | 68 +- .../modules/mob/dead/new_player/new_player.dm | 1260 ++-- code/modules/mob/dead/new_player/poll.dm | 1238 ++-- .../mob/dead/new_player/preferences_setup.dm | 124 +- code/modules/mob/dead/observer/say.dm | 80 +- code/modules/mob/inventory.dm | 946 +-- code/modules/mob/living/carbon/alien/alien.dm | 290 +- .../mob/living/carbon/alien/alien_defense.dm | 256 +- code/modules/mob/living/carbon/alien/death.dm | 30 +- .../carbon/alien/humanoid/caste/hunter.dm | 180 +- .../mob/living/carbon/alien/humanoid/death.dm | 44 +- .../living/carbon/alien/humanoid/humanoid.dm | 238 +- .../mob/living/carbon/alien/humanoid/queen.dm | 278 +- .../carbon/alien/humanoid/update_icons.dm | 194 +- .../mob/living/carbon/alien/larva/death.dm | 46 +- .../mob/living/carbon/alien/larva/powers.dm | 126 +- code/modules/mob/living/carbon/alien/life.dm | 104 +- code/modules/mob/living/carbon/alien/say.dm | 46 +- .../modules/mob/living/carbon/alien/screen.dm | 64 +- .../carbon/alien/special/alien_embryo.dm | 278 +- .../living/carbon/alien/special/facehugger.dm | 542 +- code/modules/mob/living/carbon/carbon.dm | 1980 +++--- .../mob/living/carbon/carbon_defense.dm | 912 +-- .../mob/living/carbon/carbon_defines.dm | 132 +- code/modules/mob/living/carbon/death.dm | 144 +- code/modules/mob/living/carbon/emote.dm | 200 +- code/modules/mob/living/carbon/human/death.dm | 136 +- code/modules/mob/living/carbon/human/dummy.dm | 96 +- code/modules/mob/living/carbon/human/emote.dm | 378 +- .../mob/living/carbon/human/examine.dm | 830 +-- code/modules/mob/living/carbon/human/human.dm | 2280 +++---- .../mob/living/carbon/human/human_defense.dm | 1638 ++--- .../mob/living/carbon/human/human_defines.dm | 140 +- .../mob/living/carbon/human/human_helpers.dm | 284 +- .../mob/living/carbon/human/human_movement.dm | 156 +- .../mob/living/carbon/human/inventory.dm | 546 +- code/modules/mob/living/carbon/human/say.dm | 232 +- .../carbon/human/species_types/abductors.dm | 36 +- .../carbon/human/species_types/android.dm | 48 +- .../carbon/human/species_types/angel.dm | 288 +- .../carbon/human/species_types/flypeople.dm | 72 +- .../carbon/human/species_types/golems.dm | 2050 +++--- .../carbon/human/species_types/jellypeople.dm | 1968 +++--- .../human/species_types/lizardpeople.dm | 186 +- .../carbon/human/species_types/plasmamen.dm | 310 +- .../human/species_types/shadowpeople.dm | 444 +- .../carbon/human/species_types/skeletons.dm | 58 +- .../carbon/human/species_types/synths.dm | 252 +- .../carbon/human/species_types/zombies.dm | 196 +- code/modules/mob/living/carbon/inventory.dm | 284 +- code/modules/mob/living/carbon/life.dm | 1518 ++--- .../modules/mob/living/carbon/monkey/death.dm | 18 +- code/modules/mob/living/carbon/monkey/life.dm | 344 +- .../mob/living/carbon/monkey/monkey.dm | 348 +- .../mob/living/carbon/monkey/update_icons.dm | 158 +- .../modules/mob/living/carbon/update_icons.dm | 562 +- code/modules/mob/living/damage_procs.dm | 560 +- code/modules/mob/living/death.dm | 214 +- code/modules/mob/living/emote.dm | 1048 +-- code/modules/mob/living/inhand_holder.dm | 260 +- code/modules/mob/living/living_defense.dm | 1046 +-- code/modules/mob/living/living_defines.dm | 230 +- code/modules/mob/living/login.dm | 54 +- code/modules/mob/living/logout.dm | 8 +- code/modules/mob/living/say.dm | 838 +-- code/modules/mob/living/silicon/ai/ai.dm | 1992 +++--- code/modules/mob/living/silicon/ai/death.dm | 112 +- code/modules/mob/living/silicon/ai/examine.dm | 42 +- .../living/silicon/ai/freelook/cameranet.dm | 408 +- .../mob/living/silicon/ai/freelook/chunk.dm | 284 +- .../mob/living/silicon/ai/freelook/eye.dm | 412 +- code/modules/mob/living/silicon/ai/login.dm | 24 +- code/modules/mob/living/silicon/ai/logout.dm | 16 +- code/modules/mob/living/silicon/ai/say.dm | 358 +- .../mob/living/silicon/ai/vox_sounds.dm | 3216 +++++----- code/modules/mob/living/silicon/death.dm | 24 +- code/modules/mob/living/silicon/laws.dm | 186 +- code/modules/mob/living/silicon/login.dm | 20 +- code/modules/mob/living/silicon/pai/death.dm | 24 +- code/modules/mob/living/silicon/pai/pai.dm | 858 +-- .../mob/living/silicon/pai/personality.dm | 122 +- .../mob/living/silicon/pai/software.dm | 1264 ++-- .../modules/mob/living/silicon/robot/death.dm | 70 +- .../mob/living/silicon/robot/examine.dm | 106 +- .../mob/living/silicon/robot/inventory.dm | 470 +- code/modules/mob/living/silicon/robot/laws.dm | 164 +- code/modules/mob/living/silicon/robot/life.dm | 204 +- .../modules/mob/living/silicon/robot/login.dm | 10 +- .../mob/living/silicon/robot/robot_modules.dm | 2050 +++--- code/modules/mob/living/silicon/say.dm | 108 +- code/modules/mob/living/silicon/silicon.dm | 840 +-- .../mob/living/simple_animal/bot/bot.dm | 2060 +++--- .../mob/living/simple_animal/bot/ed209bot.dm | 1146 ++-- .../mob/living/simple_animal/bot/medbot.dm | 1134 ++-- .../mob/living/simple_animal/bot/secbot.dm | 888 +-- .../mob/living/simple_animal/constructs.dm | 924 +-- .../mob/living/simple_animal/corpse.dm | 442 +- .../mob/living/simple_animal/friendly/cat.dm | 626 +- .../mob/living/simple_animal/friendly/crab.dm | 158 +- .../simple_animal/friendly/farm_animals.dm | 948 +-- .../living/simple_animal/friendly/lizard.dm | 92 +- .../mob/living/simple_animal/hostile/carp.dm | 214 +- .../living/simple_animal/hostile/faithless.dm | 92 +- .../simple_animal/hostile/giant_spider.dm | 1088 ++-- .../living/simple_animal/hostile/hivebot.dm | 160 +- .../mob/living/simple_animal/hostile/mimic.dm | 548 +- .../living/simple_animal/hostile/mushroom.dm | 384 +- .../simple_animal/hostile/retaliate/bat.dm | 102 +- .../simple_animal/hostile/retaliate/clown.dm | 92 +- .../hostile/retaliate/retaliate.dm | 94 +- .../living/simple_animal/hostile/syndicate.dm | 626 +- .../mob/living/simple_animal/hostile/tree.dm | 142 +- .../mob/living/simple_animal/parrot.dm | 2048 +++--- .../modules/mob/living/simple_animal/shade.dm | 130 +- .../mob/living/simple_animal/simple_animal.dm | 1178 ++-- code/modules/mob/login.dm | 110 +- code/modules/mob/logout.dm | 34 +- code/modules/mob/mob_helpers.dm | 1076 ++-- code/modules/mob/mob_movement.dm | 814 +-- code/modules/mob/say.dm | 208 +- code/modules/mob/transform_procs.dm | 1172 ++-- code/modules/paperwork/clipboard.dm | 252 +- code/modules/paperwork/filingcabinet.dm | 450 +- code/modules/paperwork/folders.dm | 234 +- code/modules/paperwork/paperbin.dm | 348 +- code/modules/paperwork/pen.dm | 440 +- code/modules/paperwork/photocopier.dm | 680 +- code/modules/paperwork/stamps.dm | 142 +- code/modules/photography/_pictures.dm | 342 +- code/modules/photography/camera/camera.dm | 428 +- .../camera/camera_image_capturing.dm | 178 +- code/modules/photography/camera/film.dm | 28 +- code/modules/photography/camera/other.dm | 42 +- .../photography/camera/silicon_camera.dm | 198 +- code/modules/photography/photos/album.dm | 150 +- code/modules/photography/photos/frame.dm | 326 +- code/modules/photography/photos/photo.dm | 184 +- .../power/antimatter/containment_jar.dm | 78 +- code/modules/power/antimatter/control.dm | 714 +-- code/modules/power/antimatter/shielding.dm | 506 +- code/modules/power/cable.dm | 1700 ++--- code/modules/power/cell.dm | 732 +-- code/modules/power/generator.dm | 468 +- code/modules/power/gravitygenerator.dm | 834 +-- code/modules/power/monitor.dm | 242 +- code/modules/power/port_gen.dm | 574 +- code/modules/power/singularity/collector.dm | 464 +- .../power/singularity/containment_field.dm | 268 +- code/modules/power/singularity/emitter.dm | 1008 +-- .../power/singularity/field_generator.dm | 706 +- code/modules/power/singularity/generator.dm | 70 +- code/modules/power/singularity/investigate.dm | 6 +- .../particle_accelerator/particle.dm | 136 +- .../particle_accelerator.dm | 344 +- .../particle_accelerator/particle_control.dm | 660 +- code/modules/power/tracker.dm | 186 +- .../mapGenerators/lavaland.dm | 66 +- .../mapGenerators/repair.dm | 222 +- .../mapGenerators/syndicate.dm | 114 +- .../projectiles/ammunition/_ammunition.dm | 170 +- .../modules/projectiles/ammunition/_firing.dm | 126 +- .../projectiles/ammunition/ballistic/lmg.dm | 46 +- .../ammunition/ballistic/pistol.dm | 100 +- .../ammunition/ballistic/revolver.dm | 98 +- .../projectiles/ammunition/ballistic/rifle.dm | 56 +- .../ammunition/ballistic/shotgun.dm | 282 +- .../projectiles/ammunition/ballistic/smg.dm | 64 +- .../ammunition/ballistic/sniper.dm | 40 +- .../ammunition/caseless/_caseless.dm | 32 +- .../projectiles/ammunition/caseless/foam.dm | 130 +- .../projectiles/ammunition/caseless/misc.dm | 44 +- .../projectiles/ammunition/caseless/rocket.dm | 38 +- .../projectiles/ammunition/energy/_energy.dm | 20 +- .../projectiles/ammunition/energy/ebow.dm | 24 +- .../projectiles/ammunition/energy/gravity.dm | 58 +- .../projectiles/ammunition/energy/laser.dm | 146 +- .../projectiles/ammunition/energy/lmg.dm | 12 +- .../projectiles/ammunition/energy/plasma.dm | 28 +- .../projectiles/ammunition/energy/portal.dm | 40 +- .../projectiles/ammunition/energy/special.dm | 146 +- .../projectiles/ammunition/energy/stun.dm | 58 +- .../projectiles/ammunition/special/magic.dm | 90 +- .../projectiles/ammunition/special/syringe.dm | 156 +- .../boxes_magazines/_box_magazine.dm | 276 +- .../boxes_magazines/external/grenade.dm | 16 +- .../boxes_magazines/external/lmg.dm | 44 +- .../boxes_magazines/external/pistol.dm | 122 +- .../boxes_magazines/external/rechargable.dm | 28 +- .../boxes_magazines/external/rifle.dm | 42 +- .../boxes_magazines/external/shotgun.dm | 82 +- .../boxes_magazines/external/smg.dm | 152 +- .../boxes_magazines/external/sniper.dm | 52 +- .../boxes_magazines/external/toy.dm | 118 +- .../boxes_magazines/internal/_cylinder.dm | 94 +- .../boxes_magazines/internal/_internal.dm | 16 +- .../boxes_magazines/internal/grenade.dm | 34 +- .../boxes_magazines/internal/misc.dm | 22 +- .../boxes_magazines/internal/revolver.dm | 44 +- .../boxes_magazines/internal/rifle.dm | 34 +- .../boxes_magazines/internal/shotgun.dm | 96 +- .../boxes_magazines/internal/toy.dm | 14 +- code/modules/projectiles/guns/energy.dm | 472 +- code/modules/projectiles/guns/energy/laser.dm | 450 +- .../projectiles/guns/energy/mounted.dm | 40 +- code/modules/projectiles/guns/energy/pulse.dm | 158 +- .../projectiles/guns/energy/special.dm | 650 +- code/modules/projectiles/guns/energy/stun.dm | 128 +- code/modules/projectiles/guns/magic.dm | 182 +- code/modules/projectiles/guns/magic/wand.dm | 354 +- .../projectiles/guns/misc/beam_rifle.dm | 1144 ++-- .../modules/projectiles/guns/misc/chem_gun.dm | 90 +- .../projectiles/guns/misc/grenade_launcher.dm | 92 +- code/modules/projectiles/guns/misc/medbeam.dm | 270 +- .../projectiles/guns/misc/syringe_gun.dm | 334 +- code/modules/projectiles/projectile.dm | 1296 ++-- code/modules/projectiles/projectile/beams.dm | 418 +- .../modules/projectiles/projectile/bullets.dm | 20 +- .../projectile/bullets/_incendiary.dm | 34 +- .../projectile/bullets/dart_syringe.dm | 160 +- .../projectile/bullets/dnainjector.dm | 48 +- .../projectiles/projectile/bullets/grenade.dm | 24 +- .../projectiles/projectile/bullets/lmg.dm | 88 +- .../projectiles/projectile/bullets/pistol.dm | 72 +- .../projectile/bullets/revolver.dm | 140 +- .../projectiles/projectile/bullets/rifle.dm | 32 +- .../projectiles/projectile/bullets/shotgun.dm | 200 +- .../projectiles/projectile/bullets/sniper.dm | 92 +- .../projectiles/projectile/bullets/special.dm | 54 +- .../projectiles/projectile/energy/_energy.dm | 16 +- .../projectiles/projectile/energy/ebow.dm | 32 +- .../projectiles/projectile/energy/misc.dm | 30 +- .../projectiles/projectile/energy/stun.dm | 70 +- .../projectiles/projectile/energy/tesla.dm | 58 +- .../projectile/reusable/_reusable.dm | 40 +- .../projectile/reusable/foam_dart.dm | 82 +- .../projectile/reusable/magspear.dm | 12 +- .../projectiles/projectile/special/curse.dm | 104 +- .../projectiles/projectile/special/floral.dm | 50 +- .../projectiles/projectile/special/gravity.dm | 180 +- .../projectile/special/hallucination.dm | 460 +- .../projectiles/projectile/special/ion.dm | 40 +- .../projectiles/projectile/special/meteor.dm | 38 +- .../projectile/special/mindflayer.dm | 18 +- .../projectile/special/neurotoxin.dm | 28 +- .../projectiles/projectile/special/plasma.dm | 108 +- .../projectiles/projectile/special/rocket.dm | 90 +- .../projectile/special/temperature.dm | 36 +- .../projectile/special/wormhole.dm | 58 +- code/modules/reagents/reagent_containers.dm | 494 +- .../reagents/reagent_containers/borghydro.dm | 528 +- .../reagents/reagent_containers/dropper.dm | 204 +- .../reagents/reagent_containers/glass.dm | 736 +-- .../reagents/reagent_containers/hypospray.dm | 1024 +-- .../reagents/reagent_containers/spray.dm | 648 +- .../reagents/reagent_containers/syringes.dm | 702 +- code/modules/reagents/reagent_dispenser.dm | 504 +- code/modules/recycling/sortingmachinery.dm | 392 +- code/modules/research/designs.dm | 176 +- .../research/designs/bluespace_designs.dm | 172 +- ..._cargo .dm => comp_board_designs_cargo.dm} | 2 +- .../research/designs/electronics_designs.dm | 320 +- .../research/designs/equipment_designs.dm | 108 +- .../research/designs/mining_designs.dm | 266 +- code/modules/research/destructive_analyzer.dm | 308 +- code/modules/research/experimentor.dm | 1334 ++-- .../modules/research/machinery/_production.dm | 730 +-- .../research/machinery/circuit_imprinter.dm | 64 +- .../departmental_circuit_imprinter.dm | 24 +- .../machinery/departmental_protolathe.dm | 84 +- .../machinery/departmental_techfab.dm | 80 +- code/modules/research/machinery/protolathe.dm | 46 +- code/modules/research/machinery/techfab.dm | 66 +- code/modules/research/rdconsole.dm | 2270 +++---- code/modules/research/rdmachines.dm | 212 +- code/modules/research/research_disk.dm | 80 +- .../research/techweb/__techweb_helpers.dm | 68 +- code/modules/research/techweb/_techweb.dm | 776 +-- .../modules/research/techweb/_techweb_node.dm | 194 +- .../security_levels/keycard_authentication.dm | 286 +- .../security_levels/security_levels.dm | 312 +- code/modules/shuttle/arrivals.dm | 412 +- code/modules/shuttle/computer.dm | 150 +- code/modules/shuttle/ferry.dm | 80 +- code/modules/shuttle/syndicate.dm | 132 +- code/modules/shuttle/white_ship.dm | 112 +- .../spells/spell_types/area_teleport.dm | 184 +- code/modules/spells/spell_types/conjure.dm | 200 +- code/modules/spells/spell_types/dumbfire.dm | 228 +- code/modules/spells/spell_types/emplosion.dm | 34 +- .../spells/spell_types/ethereal_jaunt.dm | 204 +- code/modules/spells/spell_types/explosion.dm | 30 +- code/modules/spells/spell_types/genetic.dm | 86 +- .../spells/spell_types/inflict_handler.dm | 112 +- code/modules/spells/spell_types/knock.dm | 62 +- code/modules/spells/spell_types/mime.dm | 310 +- .../spells/spell_types/mind_transfer.dm | 176 +- code/modules/spells/spell_types/projectile.dm | 192 +- .../spells/spell_types/rightandwrong.dm | 352 +- code/modules/spells/spell_types/trigger.dm | 58 +- code/modules/spells/spell_types/wizard.dm | 756 +-- code/modules/surgery/core_removal.dm | 82 +- code/modules/surgery/eye_surgery.dm | 92 +- code/modules/surgery/helpers.dm | 350 +- code/modules/surgery/implant_removal.dm | 120 +- code/modules/surgery/limb_augmentation.dm | 100 +- code/modules/surgery/lipoplasty.dm | 112 +- code/modules/surgery/organs/helpers.dm | 58 +- code/modules/surgery/organs/liver.dm | 242 +- code/modules/surgery/organs/stomach.dm | 196 +- code/modules/surgery/plastic_surgery.dm | 102 +- code/modules/surgery/surgery_step.dm | 260 +- code/modules/surgery/tools.dm | 720 +-- code/modules/tgs/core/_definitions.dm | 4 +- code/modules/tgs/core/core.dm | 288 +- code/modules/tgs/core/datum.dm | 148 +- .../modules/tgs/core/default_event_handler.dm | 60 +- code/modules/tgs/includes.dm | 12 +- code/modules/tgs/v3210/api.dm | 496 +- code/modules/tgs/v3210/commands.dm | 156 +- code/modules/tgui/tgui.dm | 774 +-- code/modules/unit_tests/_unit_tests.dm | 24 +- code/modules/uplink/uplink_devices.dm | 118 +- code/modules/vehicles/lavaboat.dm | 138 +- code/modules/vehicles/ridden.dm | 158 +- code/modules/vehicles/vehicle_actions.dm | 332 +- interface/interface.dm | 454 +- .../living/silicon/robot/dogborg_equipment.dm | 898 +-- tools/Redirector/Configurations.dm | 106 +- tools/Redirector/textprocs.dm | 304 +- 942 files changed, 189318 insertions(+), 189318 deletions(-) rename code/modules/research/designs/comp_board_designs/{comp_board_designs_cargo .dm => comp_board_designs_cargo.dm} (97%) diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm index bded562a3c..3acd1443af 100644 --- a/code/__DEFINES/admin.dm +++ b/code/__DEFINES/admin.dm @@ -1,91 +1,91 @@ -//A set of constants used to determine which type of mute an admin wishes to apply: -//Please read and understand the muting/automuting stuff before changing these. MUTE_IC_AUTO etc = (MUTE_IC << 1) -//Therefore there needs to be a gap between the flags for the automute flags -#define MUTE_IC (1<<0) -#define MUTE_OOC (1<<1) -#define MUTE_PRAY (1<<2) -#define MUTE_ADMINHELP (1<<3) -#define MUTE_DEADCHAT (1<<4) -#define MUTE_ALL (~0) - -//Some constants for DB_Ban -#define BANTYPE_PERMA 1 -#define BANTYPE_TEMP 2 -#define BANTYPE_JOB_PERMA 3 -#define BANTYPE_JOB_TEMP 4 -#define BANTYPE_ANY_FULLBAN 5 //used to locate stuff to unban. - -#define BANTYPE_ADMIN_PERMA 7 -#define BANTYPE_ADMIN_TEMP 8 -#define BANTYPE_ANY_JOB 9 //used to remove jobbans - -//Admin Permissions -#define R_BUILDMODE (1<<0) -#define R_ADMIN (1<<1) -#define R_BAN (1<<2) -#define R_FUN (1<<3) -#define R_SERVER (1<<4) -#define R_DEBUG (1<<5) -#define R_POSSESS (1<<6) -#define R_PERMISSIONS (1<<7) -#define R_STEALTH (1<<8) -#define R_POLL (1<<9) -#define R_VAREDIT (1<<10) -#define R_SOUNDS (1<<11) -#define R_SPAWN (1<<12) -#define R_AUTOLOGIN (1<<13) -#define R_DBRANKS (1<<14) - -#define R_DEFAULT R_AUTOLOGIN - -#define R_EVERYTHING ALL //the sum of all other rank permissions, used for +EVERYTHING - -#define ADMIN_QUE(user) "(?)" -#define ADMIN_FLW(user) "(FLW)" -#define ADMIN_PP(user) "(PP)" -#define ADMIN_VV(atom) "(VV)" -#define ADMIN_SM(user) "(SM)" -#define ADMIN_TP(user) "(TP)" -#define ADMIN_KICK(user) "(KICK)" -#define ADMIN_CENTCOM_REPLY(user) "(RPLY)" -#define ADMIN_SYNDICATE_REPLY(user) "(RPLY)" -#define ADMIN_SC(user) "(SC)" -#define ADMIN_SMITE(user) "(SMITE)" -#define ADMIN_LOOKUP(user) "[key_name_admin(user)][ADMIN_QUE(user)]" -#define ADMIN_LOOKUPFLW(user) "[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]" -#define ADMIN_SET_SD_CODE "(SETCODE)" -#define ADMIN_FULLMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)] [ADMIN_INDIVIDUALLOG(user)] [ADMIN_SMITE(user)]" -#define ADMIN_FULLMONTY(user) "[key_name_admin(user)] [ADMIN_FULLMONTY_NONAME(user)]" -#define ADMIN_JMP(src) "(JMP)" -#define COORD(src) "[src ? "([src.x],[src.y],[src.z])" : "nonexistent location"]" -#define AREACOORD(src) "[src ? "[get_area_name(src, TRUE)] ([src.x], [src.y], [src.z])" : "nonexistent location"]" -#define ADMIN_COORDJMP(src) "[src ? "[COORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]" -#define ADMIN_VERBOSEJMP(src) "[src ? "[AREACOORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]" -#define ADMIN_INDIVIDUALLOG(user) "(LOGS)" - -#define ADMIN_PUNISHMENT_LIGHTNING "Lightning bolt" -#define ADMIN_PUNISHMENT_BRAINDAMAGE "Brain damage" -#define ADMIN_PUNISHMENT_GIB "Gib" -#define ADMIN_PUNISHMENT_BSA "Bluespace Artillery Device" -#define ADMIN_PUNISHMENT_FIREBALL "Fireball" -#define ADMIN_PUNISHMENT_ROD "Immovable Rod" -#define ADMIN_PUNISHMENT_SUPPLYPOD_QUICK "Supply Pod (Quick)" -#define ADMIN_PUNISHMENT_SUPPLYPOD "Supply Pod" -#define ADMIN_PUNISHMENT_MAZING "Puzzle" -#define ADMIN_PUNISHMENT_PIE "Cream Pie" - -#define AHELP_ACTIVE 1 -#define AHELP_CLOSED 2 -#define AHELP_RESOLVED 3 - -#define ROUNDSTART_LOGOUT_REPORT_TIME 6000 //Amount of time (in deciseconds) after the rounds starts, that the player disconnect report is issued. - -#define SPAM_TRIGGER_WARNING 5 //Number of identical messages required before the spam-prevention will warn you to stfu -#define SPAM_TRIGGER_AUTOMUTE 10 //Number of identical messages required before the spam-prevention will automute you - -///Max length of a keypress command before it's considered to be a forged packet/bogus command -#define MAX_KEYPRESS_COMMANDLENGTH 16 -///Max amount of keypress messages per second over two seconds before client is autokicked -#define MAX_KEYPRESS_AUTOKICK 100 -///Length of held key rolling buffer -#define HELD_KEY_BUFFER_LENGTH 15 +//A set of constants used to determine which type of mute an admin wishes to apply: +//Please read and understand the muting/automuting stuff before changing these. MUTE_IC_AUTO etc = (MUTE_IC << 1) +//Therefore there needs to be a gap between the flags for the automute flags +#define MUTE_IC (1<<0) +#define MUTE_OOC (1<<1) +#define MUTE_PRAY (1<<2) +#define MUTE_ADMINHELP (1<<3) +#define MUTE_DEADCHAT (1<<4) +#define MUTE_ALL (~0) + +//Some constants for DB_Ban +#define BANTYPE_PERMA 1 +#define BANTYPE_TEMP 2 +#define BANTYPE_JOB_PERMA 3 +#define BANTYPE_JOB_TEMP 4 +#define BANTYPE_ANY_FULLBAN 5 //used to locate stuff to unban. + +#define BANTYPE_ADMIN_PERMA 7 +#define BANTYPE_ADMIN_TEMP 8 +#define BANTYPE_ANY_JOB 9 //used to remove jobbans + +//Admin Permissions +#define R_BUILDMODE (1<<0) +#define R_ADMIN (1<<1) +#define R_BAN (1<<2) +#define R_FUN (1<<3) +#define R_SERVER (1<<4) +#define R_DEBUG (1<<5) +#define R_POSSESS (1<<6) +#define R_PERMISSIONS (1<<7) +#define R_STEALTH (1<<8) +#define R_POLL (1<<9) +#define R_VAREDIT (1<<10) +#define R_SOUNDS (1<<11) +#define R_SPAWN (1<<12) +#define R_AUTOLOGIN (1<<13) +#define R_DBRANKS (1<<14) + +#define R_DEFAULT R_AUTOLOGIN + +#define R_EVERYTHING ALL //the sum of all other rank permissions, used for +EVERYTHING + +#define ADMIN_QUE(user) "(?)" +#define ADMIN_FLW(user) "(FLW)" +#define ADMIN_PP(user) "(PP)" +#define ADMIN_VV(atom) "(VV)" +#define ADMIN_SM(user) "(SM)" +#define ADMIN_TP(user) "(TP)" +#define ADMIN_KICK(user) "(KICK)" +#define ADMIN_CENTCOM_REPLY(user) "(RPLY)" +#define ADMIN_SYNDICATE_REPLY(user) "(RPLY)" +#define ADMIN_SC(user) "(SC)" +#define ADMIN_SMITE(user) "(SMITE)" +#define ADMIN_LOOKUP(user) "[key_name_admin(user)][ADMIN_QUE(user)]" +#define ADMIN_LOOKUPFLW(user) "[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]" +#define ADMIN_SET_SD_CODE "(SETCODE)" +#define ADMIN_FULLMONTY_NONAME(user) "[ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)] [ADMIN_INDIVIDUALLOG(user)] [ADMIN_SMITE(user)]" +#define ADMIN_FULLMONTY(user) "[key_name_admin(user)] [ADMIN_FULLMONTY_NONAME(user)]" +#define ADMIN_JMP(src) "(JMP)" +#define COORD(src) "[src ? "([src.x],[src.y],[src.z])" : "nonexistent location"]" +#define AREACOORD(src) "[src ? "[get_area_name(src, TRUE)] ([src.x], [src.y], [src.z])" : "nonexistent location"]" +#define ADMIN_COORDJMP(src) "[src ? "[COORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]" +#define ADMIN_VERBOSEJMP(src) "[src ? "[AREACOORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]" +#define ADMIN_INDIVIDUALLOG(user) "(LOGS)" + +#define ADMIN_PUNISHMENT_LIGHTNING "Lightning bolt" +#define ADMIN_PUNISHMENT_BRAINDAMAGE "Brain damage" +#define ADMIN_PUNISHMENT_GIB "Gib" +#define ADMIN_PUNISHMENT_BSA "Bluespace Artillery Device" +#define ADMIN_PUNISHMENT_FIREBALL "Fireball" +#define ADMIN_PUNISHMENT_ROD "Immovable Rod" +#define ADMIN_PUNISHMENT_SUPPLYPOD_QUICK "Supply Pod (Quick)" +#define ADMIN_PUNISHMENT_SUPPLYPOD "Supply Pod" +#define ADMIN_PUNISHMENT_MAZING "Puzzle" +#define ADMIN_PUNISHMENT_PIE "Cream Pie" + +#define AHELP_ACTIVE 1 +#define AHELP_CLOSED 2 +#define AHELP_RESOLVED 3 + +#define ROUNDSTART_LOGOUT_REPORT_TIME 6000 //Amount of time (in deciseconds) after the rounds starts, that the player disconnect report is issued. + +#define SPAM_TRIGGER_WARNING 5 //Number of identical messages required before the spam-prevention will warn you to stfu +#define SPAM_TRIGGER_AUTOMUTE 10 //Number of identical messages required before the spam-prevention will automute you + +///Max length of a keypress command before it's considered to be a forged packet/bogus command +#define MAX_KEYPRESS_COMMANDLENGTH 16 +///Max amount of keypress messages per second over two seconds before client is autokicked +#define MAX_KEYPRESS_AUTOKICK 100 +///Length of held key rolling buffer +#define HELD_KEY_BUFFER_LENGTH 15 diff --git a/code/__DEFINES/atmospherics.dm b/code/__DEFINES/atmospherics.dm index 41b5deb302..456582c6a5 100644 --- a/code/__DEFINES/atmospherics.dm +++ b/code/__DEFINES/atmospherics.dm @@ -1,298 +1,298 @@ -//LISTMOS -//indices of values in gas lists. -#define META_GAS_SPECIFIC_HEAT 1 -#define META_GAS_NAME 2 -#define META_GAS_MOLES_VISIBLE 3 -#define META_GAS_OVERLAY 4 -#define META_GAS_DANGER 5 -#define META_GAS_ID 6 -#define META_GAS_FUSION_POWER 7 -//ATMOS -//stuff you should probably leave well alone! -#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol) -#define ONE_ATMOSPHERE 101.325 //kPa -#define TCMB 2.7 // -270.3degC -#define TCRYO 225 // -48.15degC -#define T0C 273.15 // 0degC -#define T20C 293.15 // 20degC - -#define MOLES_CELLSTANDARD (ONE_ATMOSPHERE*CELL_VOLUME/(T20C*R_IDEAL_GAS_EQUATION)) //moles in a 2.5 m^3 cell at 101.325 Pa and 20 degC -#define M_CELL_WITH_RATIO (MOLES_CELLSTANDARD * 0.005) //compared against for superconductivity -#define O2STANDARD 0.21 //percentage of oxygen in a normal mixture of air -#define N2STANDARD 0.79 //same but for nitrogen -#define MOLES_O2STANDARD (MOLES_CELLSTANDARD*O2STANDARD) // O2 standard value (21%) -#define MOLES_N2STANDARD (MOLES_CELLSTANDARD*N2STANDARD) // N2 standard value (79%) -#define CELL_VOLUME 2500 //liters in a cell -#define BREATH_VOLUME 0.5 //liters in a normal breath -#define BREATH_PERCENTAGE (BREATH_VOLUME/CELL_VOLUME) //Amount of air to take a from a tile - -//EXCITED GROUPS -#define EXCITED_GROUP_BREAKDOWN_CYCLES 4 //number of FULL air controller ticks before an excited group breaks down (averages gas contents across turfs) -#define EXCITED_GROUP_DISMANTLE_CYCLES 16 //number of FULL air controller ticks before an excited group dismantles and removes its turfs from active -#define MINIMUM_AIR_RATIO_TO_SUSPEND 0.1 //Ratio of air that must move to/from a tile to reset group processing -#define MINIMUM_AIR_RATIO_TO_MOVE 0.001 //Minimum ratio of air that must move to/from a tile -#define MINIMUM_AIR_TO_SUSPEND (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_SUSPEND) //Minimum amount of air that has to move before a group processing can be suspended -#define MINIMUM_MOLES_DELTA_TO_MOVE (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_MOVE) //Either this must be active -#define MINIMUM_TEMPERATURE_TO_MOVE (T20C+100) //or this (or both, obviously) -#define MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND 4 //Minimum temperature difference before group processing is suspended -#define MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER 0.5 //Minimum temperature difference before the gas temperatures are just set to be equal -#define MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION (T20C+10) -#define MINIMUM_TEMPERATURE_START_SUPERCONDUCTION (T20C+200) - -//HEAT TRANSFER COEFFICIENTS -//Must be between 0 and 1. Values closer to 1 equalize temperature faster -//Should not exceed 0.4 else strange heat flow occur -#define WALL_HEAT_TRANSFER_COEFFICIENT 0.0 -#define OPEN_HEAT_TRANSFER_COEFFICIENT 0.4 -#define WINDOW_HEAT_TRANSFER_COEFFICIENT 0.1 //a hack for now -#define HEAT_CAPACITY_VACUUM 7000 //a hack to help make vacuums "cold", sacrificing realism for gameplay - -//FIRE -#define FIRE_MINIMUM_TEMPERATURE_TO_SPREAD (150+T0C) -#define FIRE_MINIMUM_TEMPERATURE_TO_EXIST (100+T0C) -#define FIRE_SPREAD_RADIOSITY_SCALE 0.85 -#define FIRE_GROWTH_RATE 40000 //For small fires -#define PLASMA_MINIMUM_BURN_TEMPERATURE (100+T0C) -#define PLASMA_UPPER_TEMPERATURE (1370+T0C) -#define PLASMA_OXYGEN_FULLBURN 10 - -//GASES -#define MIN_TOXIC_GAS_DAMAGE 1 -#define MAX_TOXIC_GAS_DAMAGE 10 -#define MOLES_GAS_VISIBLE 0.25 //Moles in a standard cell after which gases are visible -#define FACTOR_GAS_VISIBLE_MAX 20 //moles_visible * FACTOR_GAS_VISIBLE_MAX = Moles after which gas is at maximum visibility -#define MOLES_GAS_VISIBLE_STEP 0.25 //Mole step for alpha updates. This means alpha can update at 0.25, 0.5, 0.75 and so on - -//REACTIONS -//return values for reactions (bitflags) -#define NO_REACTION 0 -#define REACTING 1 -#define STOP_REACTIONS 2 - -// Pressure limits. -#define HAZARD_HIGH_PRESSURE 550 //This determins at what pressure the ultra-high pressure red icon is displayed. (This one is set as a constant) -#define WARNING_HIGH_PRESSURE 325 //This determins when the orange pressure icon is displayed (it is 0.7 * HAZARD_HIGH_PRESSURE) -#define WARNING_LOW_PRESSURE 50 //This is when the gray low pressure icon is displayed. (it is 2.5 * HAZARD_LOW_PRESSURE) -#define HAZARD_LOW_PRESSURE 20 //This is when the black ultra-low pressure icon is displayed. (This one is set as a constant) - -#define TEMPERATURE_DAMAGE_COEFFICIENT 1.5 //This is used in handle_temperature_damage() for humans, and in reagents that affect body temperature. Temperature damage is multiplied by this amount. - -#define BODYTEMP_NORMAL 310.15 //The natural temperature for a body -#define BODYTEMP_AUTORECOVERY_DIVISOR 11 //This is the divisor which handles how much of the temperature difference between the current body temperature and 310.15K (optimal temperature) humans auto-regenerate each tick. The higher the number, the slower the recovery. This is applied each tick, so long as the mob is alive. -#define BODYTEMP_AUTORECOVERY_MINIMUM 12 //Minimum amount of kelvin moved toward 310K per tick. So long as abs(310.15 - bodytemp) is more than 50. -#define BODYTEMP_COLD_DIVISOR 6 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is lower than their body temperature. Make it lower to lose bodytemp faster. -#define BODYTEMP_HEAT_DIVISOR 15 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is higher than their body temperature. Make it lower to gain bodytemp faster. -#define BODYTEMP_COOLING_MAX -100 //The maximum number of degrees that your body can cool in 1 tick, due to the environment, when in a cold area. -#define BODYTEMP_HEATING_MAX 30 //The maximum number of degrees that your body can heat up in 1 tick, due to the environment, when in a hot area. - -#define BODYTEMP_HEAT_DAMAGE_LIMIT (BODYTEMP_NORMAL + 20) // The limit the human body can take before it starts taking damage from heat. //CITADEL EDIT to 20 -#define BODYTEMP_COLD_DAMAGE_LIMIT (BODYTEMP_NORMAL - 50) // The limit the human body can take before it starts taking damage from coldness. - - -#define SPACE_HELM_MIN_TEMP_PROTECT 2.0 //what min_cold_protection_temperature is set to for space-helmet quality headwear. MUST NOT BE 0. -#define SPACE_HELM_MAX_TEMP_PROTECT 1500 //Thermal insulation works both ways /Malkevin -#define SPACE_SUIT_MIN_TEMP_PROTECT 2.0 //what min_cold_protection_temperature is set to for space-suit quality jumpsuits or suits. MUST NOT BE 0. -#define SPACE_SUIT_MAX_TEMP_PROTECT 1500 - -#define FIRE_SUIT_MIN_TEMP_PROTECT 60 //Cold protection for firesuits -#define FIRE_SUIT_MAX_TEMP_PROTECT 30000 //what max_heat_protection_temperature is set to for firesuit quality suits. MUST NOT BE 0. -#define FIRE_HELM_MIN_TEMP_PROTECT 60 //Cold protection for fire helmets -#define FIRE_HELM_MAX_TEMP_PROTECT 30000 //for fire helmet quality items (red and white hardhats) - -#define FIRE_IMMUNITY_MAX_TEMP_PROTECT 35000 //what max_heat_protection_temperature is set to for firesuit quality suits and helmets. MUST NOT BE 0. - -#define HELMET_MIN_TEMP_PROTECT 160 //For normal helmets -#define HELMET_MAX_TEMP_PROTECT 600 //For normal helmets -#define ARMOR_MIN_TEMP_PROTECT 160 //For armor -#define ARMOR_MAX_TEMP_PROTECT 600 //For armor - -#define GLOVES_MIN_TEMP_PROTECT 2.0 //For some gloves (black and) -#define GLOVES_MAX_TEMP_PROTECT 1500 //For some gloves -#define SHOES_MIN_TEMP_PROTECT 2.0 //For gloves -#define SHOES_MAX_TEMP_PROTECT 1500 //For gloves - -#define PRESSURE_DAMAGE_COEFFICIENT 4 //The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE -#define MAX_HIGH_PRESSURE_DAMAGE 16 // CITADEL CHANGES Max to 16, low to 8. -#define LOW_PRESSURE_DAMAGE 8 //The amount of damage someone takes when in a low pressure area (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value). - -#define COLD_SLOWDOWN_FACTOR 20 //Humans are slowed by the difference between bodytemp and BODYTEMP_COLD_DAMAGE_LIMIT divided by this - -//PIPES -//Atmos pipe limits -#define MAX_OUTPUT_PRESSURE 4500 // (kPa) What pressure pumps and powered equipment max out at. -#define MAX_TRANSFER_RATE 200 // (L/s) Maximum speed powered equipment can work at. - -//used for device_type vars -#define UNARY 1 -#define BINARY 2 -#define TRINARY 3 -#define QUATERNARY 4 - -//TANKS -#define TANK_MELT_TEMPERATURE 1000000 //temperature in kelvins at which a tank will start to melt -#define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE) //Tank starts leaking -#define TANK_RUPTURE_PRESSURE (35.*ONE_ATMOSPHERE) //Tank spills all contents into atmosphere -#define TANK_FRAGMENT_PRESSURE (40.*ONE_ATMOSPHERE) //Boom 3x3 base explosion -#define TANK_FRAGMENT_SCALE (6.*ONE_ATMOSPHERE) //+1 for each SCALE kPa aboe threshold -#define TANK_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE*3) -#define TANK_MIN_RELEASE_PRESSURE 0 -#define TANK_DEFAULT_RELEASE_PRESSURE 16 - -//CANATMOSPASS -#define ATMOS_PASS_YES 1 -#define ATMOS_PASS_NO 0 -#define ATMOS_PASS_PROC -1 //ask CanAtmosPass() -#define ATMOS_PASS_DENSITY -2 //just check density - -#define CANATMOSPASS(A, O) ( A.CanAtmosPass == ATMOS_PASS_PROC ? A.CanAtmosPass(O) : ( A.CanAtmosPass == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPass ) ) -#define CANVERTICALATMOSPASS(A, O) ( A.CanAtmosPassVertical == ATMOS_PASS_PROC ? A.CanAtmosPass(O, TRUE) : ( A.CanAtmosPassVertical == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPassVertical ) ) - -//OPEN TURF ATMOS -#define OPENTURF_DEFAULT_ATMOS "o2=22;n2=82;TEMP=293.15" //the default air mix that open turfs spawn -#define TCOMMS_ATMOS "n2=100;TEMP=80" //-193,15°C telecommunications. also used for xenobiology slime killrooms -#define AIRLESS_ATMOS "TEMP=2.7" //space -#define FROZEN_ATMOS "o2=22;n2=82;TEMP=180" //-93.15°C snow and ice turfs -#define BURNMIX_ATMOS "o2=2500;plasma=5000;TEMP=370" //used in the holodeck burn test program - -//ATMOSPHERICS DEPARTMENT GAS TANK TURFS -#define ATMOS_TANK_N2O "n2o=6000;TEMP=293.15" -#define ATMOS_TANK_CO2 "co2=50000;TEMP=293.15" -#define ATMOS_TANK_PLASMA "plasma=70000;TEMP=293.15" -#define ATMOS_TANK_O2 "o2=100000;TEMP=293.15" -#define ATMOS_TANK_N2 "n2=100000;TEMP=293.15" -#define ATMOS_TANK_AIRMIX "o2=2644;n2=10580;TEMP=293.15" -//LAVALAND -#define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland -#define LAVALAND_DEFAULT_ATMOS "o2=14;n2=23;TEMP=300" - -//ATMOSIA GAS MONITOR TAGS -#define ATMOS_GAS_MONITOR_INPUT_O2 "o2_in" -#define ATMOS_GAS_MONITOR_OUTPUT_O2 "o2_out" -#define ATMOS_GAS_MONITOR_SENSOR_O2 "o2_sensor" - -#define ATMOS_GAS_MONITOR_INPUT_TOX "tox_in" -#define ATMOS_GAS_MONITOR_OUTPUT_TOX "tox_out" -#define ATMOS_GAS_MONITOR_SENSOR_TOX "tox_sensor" - -#define ATMOS_GAS_MONITOR_INPUT_AIR "air_in" -#define ATMOS_GAS_MONITOR_OUTPUT_AIR "air_out" -#define ATMOS_GAS_MONITOR_SENSOR_AIR "air_sensor" - -#define ATMOS_GAS_MONITOR_INPUT_MIX "mix_in" -#define ATMOS_GAS_MONITOR_OUTPUT_MIX "mix_out" -#define ATMOS_GAS_MONITOR_SENSOR_MIX "mix_sensor" - -#define ATMOS_GAS_MONITOR_INPUT_N2O "n2o_in" -#define ATMOS_GAS_MONITOR_OUTPUT_N2O "n2o_out" -#define ATMOS_GAS_MONITOR_SENSOR_N2O "n2o_sensor" - -#define ATMOS_GAS_MONITOR_INPUT_N2 "n2_in" -#define ATMOS_GAS_MONITOR_OUTPUT_N2 "n2_out" -#define ATMOS_GAS_MONITOR_SENSOR_N2 "n2_sensor" - -#define ATMOS_GAS_MONITOR_INPUT_CO2 "co2_in" -#define ATMOS_GAS_MONITOR_OUTPUT_CO2 "co2_out" -#define ATMOS_GAS_MONITOR_SENSOR_CO2 "co2_sensor" - -#define ATMOS_GAS_MONITOR_INPUT_INCINERATOR "incinerator_in" -#define ATMOS_GAS_MONITOR_OUTPUT_INCINERATOR "incinerator_out" -#define ATMOS_GAS_MONITOR_SENSOR_INCINERATOR "incinerator_sensor" - -#define ATMOS_GAS_MONITOR_INPUT_TOXINS_LAB "toxinslab_in" -#define ATMOS_GAS_MONITOR_OUTPUT_TOXINS_LAB "toxinslab_out" -#define ATMOS_GAS_MONITOR_SENSOR_TOXINS_LAB "toxinslab_sensor" - -#define ATMOS_GAS_MONITOR_LOOP_DISTRIBUTION "distro-loop_meter" -#define ATMOS_GAS_MONITOR_LOOP_ATMOS_WASTE "atmos-waste_loop_meter" - -#define ATMOS_GAS_MONITOR_WASTE_ENGINE "engine-waste_out" -#define ATMOS_GAS_MONITOR_WASTE_ATMOS "atmos-waste_out" - -//AIRLOCK CONTROLLER TAGS - -//RnD toxins burn chamber -#define INCINERATOR_TOXMIX_IGNITER "toxmix_igniter" -#define INCINERATOR_TOXMIX_VENT "toxmix_vent" -#define INCINERATOR_TOXMIX_DP_VENTPUMP "toxmix_airlock_pump" -#define INCINERATOR_TOXMIX_AIRLOCK_SENSOR "toxmix_airlock_sensor" -#define INCINERATOR_TOXMIX_AIRLOCK_CONTROLLER "toxmix_airlock_controller" -#define INCINERATOR_TOXMIX_AIRLOCK_INTERIOR "toxmix_airlock_interior" -#define INCINERATOR_TOXMIX_AIRLOCK_EXTERIOR "toxmix_airlock_exterior" - -//Atmospherics/maintenance incinerator -#define INCINERATOR_ATMOS_IGNITER "atmos_incinerator_igniter" -#define INCINERATOR_ATMOS_MAINVENT "atmos_incinerator_mainvent" -#define INCINERATOR_ATMOS_AUXVENT "atmos_incinerator_auxvent" -#define INCINERATOR_ATMOS_DP_VENTPUMP "atmos_incinerator_airlock_pump" -#define INCINERATOR_ATMOS_AIRLOCK_SENSOR "atmos_incinerator_airlock_sensor" -#define INCINERATOR_ATMOS_AIRLOCK_CONTROLLER "atmos_incinerator_airlock_controller" -#define INCINERATOR_ATMOS_AIRLOCK_INTERIOR "atmos_incinerator_airlock_interior" -#define INCINERATOR_ATMOS_AIRLOCK_EXTERIOR "atmos_incinerator_airlock_exterior" - -//Syndicate lavaland base incinerator (lavaland_surface_syndicate_base1.dmm) -#define INCINERATOR_SYNDICATELAVA_IGNITER "syndicatelava_igniter" -#define INCINERATOR_SYNDICATELAVA_MAINVENT "syndicatelava_mainvent" -#define INCINERATOR_SYNDICATELAVA_AUXVENT "syndicatelava_auxvent" -#define INCINERATOR_SYNDICATELAVA_DP_VENTPUMP "syndicatelava_airlock_pump" -#define INCINERATOR_SYNDICATELAVA_AIRLOCK_SENSOR "syndicatelava_airlock_sensor" -#define INCINERATOR_SYNDICATELAVA_AIRLOCK_CONTROLLER "syndicatelava_airlock_controller" -#define INCINERATOR_SYNDICATELAVA_AIRLOCK_INTERIOR "syndicatelava_airlock_interior" -#define INCINERATOR_SYNDICATELAVA_AIRLOCK_EXTERIOR "syndicatelava_airlock_exterior" - -//MULTIPIPES -//IF YOU EVER CHANGE THESE CHANGE SPRITES TO MATCH. -#define PIPING_LAYER_MIN 1 -#define PIPING_LAYER_MAX 3 -#define PIPING_LAYER_DEFAULT 2 -#define PIPING_LAYER_P_X 5 -#define PIPING_LAYER_P_Y 5 -#define PIPING_LAYER_LCHANGE 0.05 - -#define PIPING_ALL_LAYER (1<<0) //intended to connect with all layers, check for all instead of just one. -#define PIPING_ONE_PER_TURF (1<<1) //can only be built if nothing else with this flag is on the tile already. -#define PIPING_DEFAULT_LAYER_ONLY (1<<2) //can only exist at PIPING_LAYER_DEFAULT -#define PIPING_CARDINAL_AUTONORMALIZE (1<<3) //north/south east/west doesn't matter, auto normalize on build. - -//HELPERS -#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity()) -#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that - once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */ - -//prefer this to gas_mixture/total_moles in performance critical areas -#define TOTAL_MOLES(cached_gases, out_var)\ - out_var = 0;\ - for(var/total_moles_id in cached_gases){\ - out_var += cached_gases[total_moles_id];\ - } - -#ifdef TESTING -GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0)) -#define CALCULATE_ADJACENT_TURFS(T) if (SSadjacent_air.queue[T]) { GLOB.atmos_adjacent_savings[1] += 1 } else { GLOB.atmos_adjacent_savings[2] += 1; SSadjacent_air.queue[T] = 1 } -#else -#define CALCULATE_ADJACENT_TURFS(T) SSadjacent_air.queue[T] = 1 -#endif - -//Unomos - So for whatever reason, garbage collection actually drastically decreases the cost of atmos later in the round. Turning this into a define yields massively improved performance. -#define GAS_GARBAGE_COLLECT(GASGASGAS)\ - var/list/CACHE_GAS = GASGASGAS;\ - for(var/id in CACHE_GAS){\ - if(QUANTIZE(CACHE_GAS[id]) <= 0)\ - CACHE_GAS -= id;\ - } - -#define ARCHIVE_TEMPERATURE(gas) gas.temperature_archived = gas.temperature - -GLOBAL_LIST_INIT(pipe_paint_colors, list( - "amethyst" = rgb(130,43,255), //supplymain - "blue" = rgb(0,0,255), - "brown" = rgb(178,100,56), - "cyan" = rgb(0,255,249), - "dark" = rgb(69,69,69), - "green" = rgb(30,255,0), - "grey" = rgb(255,255,255), - "orange" = rgb(255,129,25), - "purple" = rgb(128,0,182), - "red" = rgb(255,0,0), - "violet" = rgb(64,0,128), - "yellow" = rgb(255,198,0) -)) +//LISTMOS +//indices of values in gas lists. +#define META_GAS_SPECIFIC_HEAT 1 +#define META_GAS_NAME 2 +#define META_GAS_MOLES_VISIBLE 3 +#define META_GAS_OVERLAY 4 +#define META_GAS_DANGER 5 +#define META_GAS_ID 6 +#define META_GAS_FUSION_POWER 7 +//ATMOS +//stuff you should probably leave well alone! +#define R_IDEAL_GAS_EQUATION 8.31 //kPa*L/(K*mol) +#define ONE_ATMOSPHERE 101.325 //kPa +#define TCMB 2.7 // -270.3degC +#define TCRYO 225 // -48.15degC +#define T0C 273.15 // 0degC +#define T20C 293.15 // 20degC + +#define MOLES_CELLSTANDARD (ONE_ATMOSPHERE*CELL_VOLUME/(T20C*R_IDEAL_GAS_EQUATION)) //moles in a 2.5 m^3 cell at 101.325 Pa and 20 degC +#define M_CELL_WITH_RATIO (MOLES_CELLSTANDARD * 0.005) //compared against for superconductivity +#define O2STANDARD 0.21 //percentage of oxygen in a normal mixture of air +#define N2STANDARD 0.79 //same but for nitrogen +#define MOLES_O2STANDARD (MOLES_CELLSTANDARD*O2STANDARD) // O2 standard value (21%) +#define MOLES_N2STANDARD (MOLES_CELLSTANDARD*N2STANDARD) // N2 standard value (79%) +#define CELL_VOLUME 2500 //liters in a cell +#define BREATH_VOLUME 0.5 //liters in a normal breath +#define BREATH_PERCENTAGE (BREATH_VOLUME/CELL_VOLUME) //Amount of air to take a from a tile + +//EXCITED GROUPS +#define EXCITED_GROUP_BREAKDOWN_CYCLES 4 //number of FULL air controller ticks before an excited group breaks down (averages gas contents across turfs) +#define EXCITED_GROUP_DISMANTLE_CYCLES 16 //number of FULL air controller ticks before an excited group dismantles and removes its turfs from active +#define MINIMUM_AIR_RATIO_TO_SUSPEND 0.1 //Ratio of air that must move to/from a tile to reset group processing +#define MINIMUM_AIR_RATIO_TO_MOVE 0.001 //Minimum ratio of air that must move to/from a tile +#define MINIMUM_AIR_TO_SUSPEND (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_SUSPEND) //Minimum amount of air that has to move before a group processing can be suspended +#define MINIMUM_MOLES_DELTA_TO_MOVE (MOLES_CELLSTANDARD*MINIMUM_AIR_RATIO_TO_MOVE) //Either this must be active +#define MINIMUM_TEMPERATURE_TO_MOVE (T20C+100) //or this (or both, obviously) +#define MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND 4 //Minimum temperature difference before group processing is suspended +#define MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER 0.5 //Minimum temperature difference before the gas temperatures are just set to be equal +#define MINIMUM_TEMPERATURE_FOR_SUPERCONDUCTION (T20C+10) +#define MINIMUM_TEMPERATURE_START_SUPERCONDUCTION (T20C+200) + +//HEAT TRANSFER COEFFICIENTS +//Must be between 0 and 1. Values closer to 1 equalize temperature faster +//Should not exceed 0.4 else strange heat flow occur +#define WALL_HEAT_TRANSFER_COEFFICIENT 0.0 +#define OPEN_HEAT_TRANSFER_COEFFICIENT 0.4 +#define WINDOW_HEAT_TRANSFER_COEFFICIENT 0.1 //a hack for now +#define HEAT_CAPACITY_VACUUM 7000 //a hack to help make vacuums "cold", sacrificing realism for gameplay + +//FIRE +#define FIRE_MINIMUM_TEMPERATURE_TO_SPREAD (150+T0C) +#define FIRE_MINIMUM_TEMPERATURE_TO_EXIST (100+T0C) +#define FIRE_SPREAD_RADIOSITY_SCALE 0.85 +#define FIRE_GROWTH_RATE 40000 //For small fires +#define PLASMA_MINIMUM_BURN_TEMPERATURE (100+T0C) +#define PLASMA_UPPER_TEMPERATURE (1370+T0C) +#define PLASMA_OXYGEN_FULLBURN 10 + +//GASES +#define MIN_TOXIC_GAS_DAMAGE 1 +#define MAX_TOXIC_GAS_DAMAGE 10 +#define MOLES_GAS_VISIBLE 0.25 //Moles in a standard cell after which gases are visible +#define FACTOR_GAS_VISIBLE_MAX 20 //moles_visible * FACTOR_GAS_VISIBLE_MAX = Moles after which gas is at maximum visibility +#define MOLES_GAS_VISIBLE_STEP 0.25 //Mole step for alpha updates. This means alpha can update at 0.25, 0.5, 0.75 and so on + +//REACTIONS +//return values for reactions (bitflags) +#define NO_REACTION 0 +#define REACTING 1 +#define STOP_REACTIONS 2 + +// Pressure limits. +#define HAZARD_HIGH_PRESSURE 550 //This determins at what pressure the ultra-high pressure red icon is displayed. (This one is set as a constant) +#define WARNING_HIGH_PRESSURE 325 //This determins when the orange pressure icon is displayed (it is 0.7 * HAZARD_HIGH_PRESSURE) +#define WARNING_LOW_PRESSURE 50 //This is when the gray low pressure icon is displayed. (it is 2.5 * HAZARD_LOW_PRESSURE) +#define HAZARD_LOW_PRESSURE 20 //This is when the black ultra-low pressure icon is displayed. (This one is set as a constant) + +#define TEMPERATURE_DAMAGE_COEFFICIENT 1.5 //This is used in handle_temperature_damage() for humans, and in reagents that affect body temperature. Temperature damage is multiplied by this amount. + +#define BODYTEMP_NORMAL 310.15 //The natural temperature for a body +#define BODYTEMP_AUTORECOVERY_DIVISOR 11 //This is the divisor which handles how much of the temperature difference between the current body temperature and 310.15K (optimal temperature) humans auto-regenerate each tick. The higher the number, the slower the recovery. This is applied each tick, so long as the mob is alive. +#define BODYTEMP_AUTORECOVERY_MINIMUM 12 //Minimum amount of kelvin moved toward 310K per tick. So long as abs(310.15 - bodytemp) is more than 50. +#define BODYTEMP_COLD_DIVISOR 6 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is lower than their body temperature. Make it lower to lose bodytemp faster. +#define BODYTEMP_HEAT_DIVISOR 15 //Similar to the BODYTEMP_AUTORECOVERY_DIVISOR, but this is the divisor which is applied at the stage that follows autorecovery. This is the divisor which comes into play when the human's loc temperature is higher than their body temperature. Make it lower to gain bodytemp faster. +#define BODYTEMP_COOLING_MAX -100 //The maximum number of degrees that your body can cool in 1 tick, due to the environment, when in a cold area. +#define BODYTEMP_HEATING_MAX 30 //The maximum number of degrees that your body can heat up in 1 tick, due to the environment, when in a hot area. + +#define BODYTEMP_HEAT_DAMAGE_LIMIT (BODYTEMP_NORMAL + 20) // The limit the human body can take before it starts taking damage from heat. //CITADEL EDIT to 20 +#define BODYTEMP_COLD_DAMAGE_LIMIT (BODYTEMP_NORMAL - 50) // The limit the human body can take before it starts taking damage from coldness. + + +#define SPACE_HELM_MIN_TEMP_PROTECT 2.0 //what min_cold_protection_temperature is set to for space-helmet quality headwear. MUST NOT BE 0. +#define SPACE_HELM_MAX_TEMP_PROTECT 1500 //Thermal insulation works both ways /Malkevin +#define SPACE_SUIT_MIN_TEMP_PROTECT 2.0 //what min_cold_protection_temperature is set to for space-suit quality jumpsuits or suits. MUST NOT BE 0. +#define SPACE_SUIT_MAX_TEMP_PROTECT 1500 + +#define FIRE_SUIT_MIN_TEMP_PROTECT 60 //Cold protection for firesuits +#define FIRE_SUIT_MAX_TEMP_PROTECT 30000 //what max_heat_protection_temperature is set to for firesuit quality suits. MUST NOT BE 0. +#define FIRE_HELM_MIN_TEMP_PROTECT 60 //Cold protection for fire helmets +#define FIRE_HELM_MAX_TEMP_PROTECT 30000 //for fire helmet quality items (red and white hardhats) + +#define FIRE_IMMUNITY_MAX_TEMP_PROTECT 35000 //what max_heat_protection_temperature is set to for firesuit quality suits and helmets. MUST NOT BE 0. + +#define HELMET_MIN_TEMP_PROTECT 160 //For normal helmets +#define HELMET_MAX_TEMP_PROTECT 600 //For normal helmets +#define ARMOR_MIN_TEMP_PROTECT 160 //For armor +#define ARMOR_MAX_TEMP_PROTECT 600 //For armor + +#define GLOVES_MIN_TEMP_PROTECT 2.0 //For some gloves (black and) +#define GLOVES_MAX_TEMP_PROTECT 1500 //For some gloves +#define SHOES_MIN_TEMP_PROTECT 2.0 //For gloves +#define SHOES_MAX_TEMP_PROTECT 1500 //For gloves + +#define PRESSURE_DAMAGE_COEFFICIENT 4 //The amount of pressure damage someone takes is equal to (pressure / HAZARD_HIGH_PRESSURE)*PRESSURE_DAMAGE_COEFFICIENT, with the maximum of MAX_PRESSURE_DAMAGE +#define MAX_HIGH_PRESSURE_DAMAGE 16 // CITADEL CHANGES Max to 16, low to 8. +#define LOW_PRESSURE_DAMAGE 8 //The amount of damage someone takes when in a low pressure area (The pressure threshold is so low that it doesn't make sense to do any calculations, so it just applies this flat value). + +#define COLD_SLOWDOWN_FACTOR 20 //Humans are slowed by the difference between bodytemp and BODYTEMP_COLD_DAMAGE_LIMIT divided by this + +//PIPES +//Atmos pipe limits +#define MAX_OUTPUT_PRESSURE 4500 // (kPa) What pressure pumps and powered equipment max out at. +#define MAX_TRANSFER_RATE 200 // (L/s) Maximum speed powered equipment can work at. + +//used for device_type vars +#define UNARY 1 +#define BINARY 2 +#define TRINARY 3 +#define QUATERNARY 4 + +//TANKS +#define TANK_MELT_TEMPERATURE 1000000 //temperature in kelvins at which a tank will start to melt +#define TANK_LEAK_PRESSURE (30.*ONE_ATMOSPHERE) //Tank starts leaking +#define TANK_RUPTURE_PRESSURE (35.*ONE_ATMOSPHERE) //Tank spills all contents into atmosphere +#define TANK_FRAGMENT_PRESSURE (40.*ONE_ATMOSPHERE) //Boom 3x3 base explosion +#define TANK_FRAGMENT_SCALE (6.*ONE_ATMOSPHERE) //+1 for each SCALE kPa aboe threshold +#define TANK_MAX_RELEASE_PRESSURE (ONE_ATMOSPHERE*3) +#define TANK_MIN_RELEASE_PRESSURE 0 +#define TANK_DEFAULT_RELEASE_PRESSURE 16 + +//CANATMOSPASS +#define ATMOS_PASS_YES 1 +#define ATMOS_PASS_NO 0 +#define ATMOS_PASS_PROC -1 //ask CanAtmosPass() +#define ATMOS_PASS_DENSITY -2 //just check density + +#define CANATMOSPASS(A, O) ( A.CanAtmosPass == ATMOS_PASS_PROC ? A.CanAtmosPass(O) : ( A.CanAtmosPass == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPass ) ) +#define CANVERTICALATMOSPASS(A, O) ( A.CanAtmosPassVertical == ATMOS_PASS_PROC ? A.CanAtmosPass(O, TRUE) : ( A.CanAtmosPassVertical == ATMOS_PASS_DENSITY ? !A.density : A.CanAtmosPassVertical ) ) + +//OPEN TURF ATMOS +#define OPENTURF_DEFAULT_ATMOS "o2=22;n2=82;TEMP=293.15" //the default air mix that open turfs spawn +#define TCOMMS_ATMOS "n2=100;TEMP=80" //-193,15°C telecommunications. also used for xenobiology slime killrooms +#define AIRLESS_ATMOS "TEMP=2.7" //space +#define FROZEN_ATMOS "o2=22;n2=82;TEMP=180" //-93.15°C snow and ice turfs +#define BURNMIX_ATMOS "o2=2500;plasma=5000;TEMP=370" //used in the holodeck burn test program + +//ATMOSPHERICS DEPARTMENT GAS TANK TURFS +#define ATMOS_TANK_N2O "n2o=6000;TEMP=293.15" +#define ATMOS_TANK_CO2 "co2=50000;TEMP=293.15" +#define ATMOS_TANK_PLASMA "plasma=70000;TEMP=293.15" +#define ATMOS_TANK_O2 "o2=100000;TEMP=293.15" +#define ATMOS_TANK_N2 "n2=100000;TEMP=293.15" +#define ATMOS_TANK_AIRMIX "o2=2644;n2=10580;TEMP=293.15" +//LAVALAND +#define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland +#define LAVALAND_DEFAULT_ATMOS "o2=14;n2=23;TEMP=300" + +//ATMOSIA GAS MONITOR TAGS +#define ATMOS_GAS_MONITOR_INPUT_O2 "o2_in" +#define ATMOS_GAS_MONITOR_OUTPUT_O2 "o2_out" +#define ATMOS_GAS_MONITOR_SENSOR_O2 "o2_sensor" + +#define ATMOS_GAS_MONITOR_INPUT_TOX "tox_in" +#define ATMOS_GAS_MONITOR_OUTPUT_TOX "tox_out" +#define ATMOS_GAS_MONITOR_SENSOR_TOX "tox_sensor" + +#define ATMOS_GAS_MONITOR_INPUT_AIR "air_in" +#define ATMOS_GAS_MONITOR_OUTPUT_AIR "air_out" +#define ATMOS_GAS_MONITOR_SENSOR_AIR "air_sensor" + +#define ATMOS_GAS_MONITOR_INPUT_MIX "mix_in" +#define ATMOS_GAS_MONITOR_OUTPUT_MIX "mix_out" +#define ATMOS_GAS_MONITOR_SENSOR_MIX "mix_sensor" + +#define ATMOS_GAS_MONITOR_INPUT_N2O "n2o_in" +#define ATMOS_GAS_MONITOR_OUTPUT_N2O "n2o_out" +#define ATMOS_GAS_MONITOR_SENSOR_N2O "n2o_sensor" + +#define ATMOS_GAS_MONITOR_INPUT_N2 "n2_in" +#define ATMOS_GAS_MONITOR_OUTPUT_N2 "n2_out" +#define ATMOS_GAS_MONITOR_SENSOR_N2 "n2_sensor" + +#define ATMOS_GAS_MONITOR_INPUT_CO2 "co2_in" +#define ATMOS_GAS_MONITOR_OUTPUT_CO2 "co2_out" +#define ATMOS_GAS_MONITOR_SENSOR_CO2 "co2_sensor" + +#define ATMOS_GAS_MONITOR_INPUT_INCINERATOR "incinerator_in" +#define ATMOS_GAS_MONITOR_OUTPUT_INCINERATOR "incinerator_out" +#define ATMOS_GAS_MONITOR_SENSOR_INCINERATOR "incinerator_sensor" + +#define ATMOS_GAS_MONITOR_INPUT_TOXINS_LAB "toxinslab_in" +#define ATMOS_GAS_MONITOR_OUTPUT_TOXINS_LAB "toxinslab_out" +#define ATMOS_GAS_MONITOR_SENSOR_TOXINS_LAB "toxinslab_sensor" + +#define ATMOS_GAS_MONITOR_LOOP_DISTRIBUTION "distro-loop_meter" +#define ATMOS_GAS_MONITOR_LOOP_ATMOS_WASTE "atmos-waste_loop_meter" + +#define ATMOS_GAS_MONITOR_WASTE_ENGINE "engine-waste_out" +#define ATMOS_GAS_MONITOR_WASTE_ATMOS "atmos-waste_out" + +//AIRLOCK CONTROLLER TAGS + +//RnD toxins burn chamber +#define INCINERATOR_TOXMIX_IGNITER "toxmix_igniter" +#define INCINERATOR_TOXMIX_VENT "toxmix_vent" +#define INCINERATOR_TOXMIX_DP_VENTPUMP "toxmix_airlock_pump" +#define INCINERATOR_TOXMIX_AIRLOCK_SENSOR "toxmix_airlock_sensor" +#define INCINERATOR_TOXMIX_AIRLOCK_CONTROLLER "toxmix_airlock_controller" +#define INCINERATOR_TOXMIX_AIRLOCK_INTERIOR "toxmix_airlock_interior" +#define INCINERATOR_TOXMIX_AIRLOCK_EXTERIOR "toxmix_airlock_exterior" + +//Atmospherics/maintenance incinerator +#define INCINERATOR_ATMOS_IGNITER "atmos_incinerator_igniter" +#define INCINERATOR_ATMOS_MAINVENT "atmos_incinerator_mainvent" +#define INCINERATOR_ATMOS_AUXVENT "atmos_incinerator_auxvent" +#define INCINERATOR_ATMOS_DP_VENTPUMP "atmos_incinerator_airlock_pump" +#define INCINERATOR_ATMOS_AIRLOCK_SENSOR "atmos_incinerator_airlock_sensor" +#define INCINERATOR_ATMOS_AIRLOCK_CONTROLLER "atmos_incinerator_airlock_controller" +#define INCINERATOR_ATMOS_AIRLOCK_INTERIOR "atmos_incinerator_airlock_interior" +#define INCINERATOR_ATMOS_AIRLOCK_EXTERIOR "atmos_incinerator_airlock_exterior" + +//Syndicate lavaland base incinerator (lavaland_surface_syndicate_base1.dmm) +#define INCINERATOR_SYNDICATELAVA_IGNITER "syndicatelava_igniter" +#define INCINERATOR_SYNDICATELAVA_MAINVENT "syndicatelava_mainvent" +#define INCINERATOR_SYNDICATELAVA_AUXVENT "syndicatelava_auxvent" +#define INCINERATOR_SYNDICATELAVA_DP_VENTPUMP "syndicatelava_airlock_pump" +#define INCINERATOR_SYNDICATELAVA_AIRLOCK_SENSOR "syndicatelava_airlock_sensor" +#define INCINERATOR_SYNDICATELAVA_AIRLOCK_CONTROLLER "syndicatelava_airlock_controller" +#define INCINERATOR_SYNDICATELAVA_AIRLOCK_INTERIOR "syndicatelava_airlock_interior" +#define INCINERATOR_SYNDICATELAVA_AIRLOCK_EXTERIOR "syndicatelava_airlock_exterior" + +//MULTIPIPES +//IF YOU EVER CHANGE THESE CHANGE SPRITES TO MATCH. +#define PIPING_LAYER_MIN 1 +#define PIPING_LAYER_MAX 3 +#define PIPING_LAYER_DEFAULT 2 +#define PIPING_LAYER_P_X 5 +#define PIPING_LAYER_P_Y 5 +#define PIPING_LAYER_LCHANGE 0.05 + +#define PIPING_ALL_LAYER (1<<0) //intended to connect with all layers, check for all instead of just one. +#define PIPING_ONE_PER_TURF (1<<1) //can only be built if nothing else with this flag is on the tile already. +#define PIPING_DEFAULT_LAYER_ONLY (1<<2) //can only exist at PIPING_LAYER_DEFAULT +#define PIPING_CARDINAL_AUTONORMALIZE (1<<3) //north/south east/west doesn't matter, auto normalize on build. + +//HELPERS +#define THERMAL_ENERGY(gas) (gas.temperature * gas.heat_capacity()) +#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that + once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */ + +//prefer this to gas_mixture/total_moles in performance critical areas +#define TOTAL_MOLES(cached_gases, out_var)\ + out_var = 0;\ + for(var/total_moles_id in cached_gases){\ + out_var += cached_gases[total_moles_id];\ + } + +#ifdef TESTING +GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0)) +#define CALCULATE_ADJACENT_TURFS(T) if (SSadjacent_air.queue[T]) { GLOB.atmos_adjacent_savings[1] += 1 } else { GLOB.atmos_adjacent_savings[2] += 1; SSadjacent_air.queue[T] = 1 } +#else +#define CALCULATE_ADJACENT_TURFS(T) SSadjacent_air.queue[T] = 1 +#endif + +//Unomos - So for whatever reason, garbage collection actually drastically decreases the cost of atmos later in the round. Turning this into a define yields massively improved performance. +#define GAS_GARBAGE_COLLECT(GASGASGAS)\ + var/list/CACHE_GAS = GASGASGAS;\ + for(var/id in CACHE_GAS){\ + if(QUANTIZE(CACHE_GAS[id]) <= 0)\ + CACHE_GAS -= id;\ + } + +#define ARCHIVE_TEMPERATURE(gas) gas.temperature_archived = gas.temperature + +GLOBAL_LIST_INIT(pipe_paint_colors, list( + "amethyst" = rgb(130,43,255), //supplymain + "blue" = rgb(0,0,255), + "brown" = rgb(178,100,56), + "cyan" = rgb(0,255,249), + "dark" = rgb(69,69,69), + "green" = rgb(30,255,0), + "grey" = rgb(255,255,255), + "orange" = rgb(255,129,25), + "purple" = rgb(128,0,182), + "red" = rgb(255,0,0), + "violet" = rgb(64,0,128), + "yellow" = rgb(255,198,0) +)) diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 7b8c5ff6ae..bf2646d03e 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -1,199 +1,199 @@ -/*ALL DEFINES RELATED TO COMBAT GO HERE*/ - -//Damage and status effect defines - -//Damage defines //TODO: merge these down to reduce on defines -#define BRUTE "brute" -#define BURN "fire" -#define TOX "tox" -#define OXY "oxy" -#define CLONE "clone" -#define STAMINA "stamina" -#define BRAIN "brain" - -//bitflag damage defines used for suicide_act -#define BRUTELOSS (1<<0) -#define FIRELOSS (1<<1) -#define TOXLOSS (1<<2) -#define OXYLOSS (1<<3) -#define SHAME (1<<4) -#define MANUAL_SUICIDE (1<<5) //suicide_act will do the actual killing. - -#define EFFECT_STUN "stun" -#define EFFECT_KNOCKDOWN "knockdown" -#define EFFECT_UNCONSCIOUS "unconscious" -#define EFFECT_IRRADIATE "irradiate" -#define EFFECT_STUTTER "stutter" -#define EFFECT_SLUR "slur" -#define EFFECT_EYE_BLUR "eye_blur" -#define EFFECT_DROWSY "drowsy" -#define EFFECT_JITTER "jitter" - -//Bitflags defining which status effects could be or are inflicted on a mob -#define CANSTUN (1<<0) -#define CANKNOCKDOWN (1<<1) -#define CANUNCONSCIOUS (1<<2) -#define CANPUSH (1<<3) -#define GODMODE (1<<4) - -//Health Defines -#define HEALTH_THRESHOLD_CRIT 0 -#define HEALTH_THRESHOLD_FULLCRIT -30 -#define HEALTH_THRESHOLD_DEAD -100 - -//Actual combat defines - -//click cooldowns, in tenths of a second, used for various combat actions -#define CLICK_CD_MELEE 8 -#define CLICK_CD_RANGE 4 -#define CLICK_CD_RAPID 2 -#define CLICK_CD_CLICK_ABILITY 6 -#define CLICK_CD_BREAKOUT 100 -#define CLICK_CD_HANDCUFFED 10 -#define CLICK_CD_RESIST 20 -#define CLICK_CD_GRABBING 10 - -//Cuff resist speeds -#define FAST_CUFFBREAK 1 -#define INSTANT_CUFFBREAK 2 - -//Grab levels -#define GRAB_PASSIVE 0 -#define GRAB_AGGRESSIVE 1 -#define GRAB_NECK 2 -#define GRAB_KILL 3 - -//slowdown when in softcrit -#define SOFTCRIT_ADD_SLOWDOWN 6 - -//Attack types for checking shields/hit reactions -#define MELEE_ATTACK 1 -#define UNARMED_ATTACK 2 -#define PROJECTILE_ATTACK 3 -#define THROWN_PROJECTILE_ATTACK 4 -#define LEAP_ATTACK 5 - -//attack visual effects -#define ATTACK_EFFECT_PUNCH "punch" -#define ATTACK_EFFECT_KICK "kick" -#define ATTACK_EFFECT_SMASH "smash" -#define ATTACK_EFFECT_CLAW "claw" -#define ATTACK_EFFECT_DISARM "disarm" -#define ATTACK_EFFECT_ASS_SLAP "ass_slap" -#define ATTACK_EFFECT_FACE_SLAP "face_slap" -#define ATTACK_EFFECT_BITE "bite" -#define ATTACK_EFFECT_MECHFIRE "mech_fire" -#define ATTACK_EFFECT_MECHTOXIN "mech_toxin" -#define ATTACK_EFFECT_BOOP "boop" //Honk - -//intent defines -#define INTENT_HELP "help" -#define INTENT_GRAB "grab" -#define INTENT_DISARM "disarm" -#define INTENT_HARM "harm" -//NOTE: INTENT_HOTKEY_* defines are not actual intents! -//they are here to support hotkeys -#define INTENT_HOTKEY_LEFT "left" -#define INTENT_HOTKEY_RIGHT "right" - -//the define for visible message range in combat -#define COMBAT_MESSAGE_RANGE 3 -#define DEFAULT_MESSAGE_RANGE 7 - -//Shove knockdown lengths (deciseconds) -#define SHOVE_KNOCKDOWN_SOLID 30 -#define SHOVE_KNOCKDOWN_HUMAN 30 -#define SHOVE_KNOCKDOWN_TABLE 30 -#define SHOVE_KNOCKDOWN_COLLATERAL 10 -//for the shove slowdown, see __DEFINES/movespeed_modification.dm -#define SHOVE_SLOWDOWN_LENGTH 30 -#define SHOVE_SLOWDOWN_STRENGTH 0.85 //multiplier -//Shove disarming item list -GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( - /obj/item/gun))) - - -//Combat object defines - -//Embedded objects -#define EMBEDDED_PAIN_CHANCE 15 //Chance for embedded objects to cause pain (damage user) -#define EMBEDDED_ITEM_FALLOUT 5 //Chance for embedded object to fall out (causing pain but removing the object) -#define EMBED_CHANCE 45 //Chance for an object to embed into somebody when thrown (if it's sharp) -#define EMBEDDED_PAIN_MULTIPLIER 2 //Coefficient of multiplication for the damage the item does while embedded (this*item.w_class) -#define EMBEDDED_FALL_PAIN_MULTIPLIER 5 //Coefficient of multiplication for the damage the item does when it falls out (this*item.w_class) -#define EMBEDDED_IMPACT_PAIN_MULTIPLIER 4 //Coefficient of multiplication for the damage the item does when it first embeds (this*item.w_class) -#define EMBED_THROWSPEED_THRESHOLD 4 //The minimum value of an item's throw_speed for it to embed (Unless it has embedded_ignore_throwspeed_threshold set to 1) -#define EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER 8 //Coefficient of multiplication for the damage the item does when removed without a surgery (this*item.w_class) -#define EMBEDDED_UNSAFE_REMOVAL_TIME 150 //A Time in ticks, total removal time = (this/item.w_class) - -//Gun weapon weight -#define WEAPON_LIGHT 1 -#define WEAPON_MEDIUM 2 -#define WEAPON_HEAVY 3 -//Gun trigger guards -#define TRIGGER_GUARD_ALLOW_ALL -1 -#define TRIGGER_GUARD_NONE 0 -#define TRIGGER_GUARD_NORMAL 1 -//E-gun self-recharge values -#define EGUN_NO_SELFCHARGE 0 -#define EGUN_SELFCHARGE 1 -#define EGUN_SELFCHARGE_BORG 2 - -//Object/Item sharpness -#define IS_BLUNT 0 -#define IS_SHARP 1 -#define IS_SHARP_ACCURATE 2 - -//His Grace. -#define HIS_GRACE_SATIATED 0 //He hungers not. If bloodthirst is set to this, His Grace is asleep. -#define HIS_GRACE_PECKISH 20 //Slightly hungry. -#define HIS_GRACE_HUNGRY 60 //Getting closer. Increases damage up to a minimum of 20. -#define HIS_GRACE_FAMISHED 100 //Dangerous. Increases damage up to a minimum of 25 and cannot be dropped. -#define HIS_GRACE_STARVING 120 //Incredibly close to breaking loose. Increases damage up to a minimum of 30. -#define HIS_GRACE_CONSUME_OWNER 140 //His Grace consumes His owner at this point and becomes aggressive. -#define HIS_GRACE_FALL_ASLEEP 160 //If it reaches this point, He falls asleep and resets. - -#define HIS_GRACE_FORCE_BONUS 4 //How much force is gained per kill. - -#define EXPLODE_NONE 0 //Don't even ask me why we need this. -#define EXPLODE_DEVASTATE 1 -#define EXPLODE_HEAVY 2 -#define EXPLODE_LIGHT 3 -#define EXPLODE_GIB_THRESHOLD 50 - -#define EMP_HEAVY 1 -#define EMP_LIGHT 2 - -#define GRENADE_CLUMSY_FUMBLE 1 -#define GRENADE_NONCLUMSY_FUMBLE 2 -#define GRENADE_NO_FUMBLE 3 - -#define BODY_ZONE_HEAD "head" -#define BODY_ZONE_CHEST "chest" -#define BODY_ZONE_L_ARM "l_arm" -#define BODY_ZONE_R_ARM "r_arm" -#define BODY_ZONE_L_LEG "l_leg" -#define BODY_ZONE_R_LEG "r_leg" - -#define BODY_ZONE_PRECISE_EYES "eyes" -#define BODY_ZONE_PRECISE_MOUTH "mouth" -#define BODY_ZONE_PRECISE_GROIN "groin" -#define BODY_ZONE_PRECISE_L_HAND "l_hand" -#define BODY_ZONE_PRECISE_R_HAND "r_hand" -#define BODY_ZONE_PRECISE_L_FOOT "l_foot" -#define BODY_ZONE_PRECISE_R_FOOT "r_foot" - -//We will round to this value in damage calculations. -#define DAMAGE_PRECISION 0.1 - -//items total mass, used to calculate their attacks' stamina costs. If not defined, the cost will be (w_class * 1.25) -#define TOTAL_MASS_TINY_ITEM 1.25 -#define TOTAL_MASS_SMALL_ITEM 2.5 -#define TOTAL_MASS_NORMAL_ITEM 3.75 -#define TOTAL_MASS_BULKY_ITEM 5 -#define TOTAL_MASS_HUGE_ITEM 6.25 -#define TOTAL_MASS_GIGANTIC_ITEM 7.5 - -#define TOTAL_MASS_HAND_REPLACEMENT 5 //standard punching stamina cost. most hand replacements are huge items anyway. -#define TOTAL_MASS_MEDIEVAL_WEAPON 3.6 //very, very generic average sword/warpick/etc. weight in pounds. -#define TOTAL_MASS_TOY_SWORD 1.5 +/*ALL DEFINES RELATED TO COMBAT GO HERE*/ + +//Damage and status effect defines + +//Damage defines //TODO: merge these down to reduce on defines +#define BRUTE "brute" +#define BURN "fire" +#define TOX "tox" +#define OXY "oxy" +#define CLONE "clone" +#define STAMINA "stamina" +#define BRAIN "brain" + +//bitflag damage defines used for suicide_act +#define BRUTELOSS (1<<0) +#define FIRELOSS (1<<1) +#define TOXLOSS (1<<2) +#define OXYLOSS (1<<3) +#define SHAME (1<<4) +#define MANUAL_SUICIDE (1<<5) //suicide_act will do the actual killing. + +#define EFFECT_STUN "stun" +#define EFFECT_KNOCKDOWN "knockdown" +#define EFFECT_UNCONSCIOUS "unconscious" +#define EFFECT_IRRADIATE "irradiate" +#define EFFECT_STUTTER "stutter" +#define EFFECT_SLUR "slur" +#define EFFECT_EYE_BLUR "eye_blur" +#define EFFECT_DROWSY "drowsy" +#define EFFECT_JITTER "jitter" + +//Bitflags defining which status effects could be or are inflicted on a mob +#define CANSTUN (1<<0) +#define CANKNOCKDOWN (1<<1) +#define CANUNCONSCIOUS (1<<2) +#define CANPUSH (1<<3) +#define GODMODE (1<<4) + +//Health Defines +#define HEALTH_THRESHOLD_CRIT 0 +#define HEALTH_THRESHOLD_FULLCRIT -30 +#define HEALTH_THRESHOLD_DEAD -100 + +//Actual combat defines + +//click cooldowns, in tenths of a second, used for various combat actions +#define CLICK_CD_MELEE 8 +#define CLICK_CD_RANGE 4 +#define CLICK_CD_RAPID 2 +#define CLICK_CD_CLICK_ABILITY 6 +#define CLICK_CD_BREAKOUT 100 +#define CLICK_CD_HANDCUFFED 10 +#define CLICK_CD_RESIST 20 +#define CLICK_CD_GRABBING 10 + +//Cuff resist speeds +#define FAST_CUFFBREAK 1 +#define INSTANT_CUFFBREAK 2 + +//Grab levels +#define GRAB_PASSIVE 0 +#define GRAB_AGGRESSIVE 1 +#define GRAB_NECK 2 +#define GRAB_KILL 3 + +//slowdown when in softcrit +#define SOFTCRIT_ADD_SLOWDOWN 6 + +//Attack types for checking shields/hit reactions +#define MELEE_ATTACK 1 +#define UNARMED_ATTACK 2 +#define PROJECTILE_ATTACK 3 +#define THROWN_PROJECTILE_ATTACK 4 +#define LEAP_ATTACK 5 + +//attack visual effects +#define ATTACK_EFFECT_PUNCH "punch" +#define ATTACK_EFFECT_KICK "kick" +#define ATTACK_EFFECT_SMASH "smash" +#define ATTACK_EFFECT_CLAW "claw" +#define ATTACK_EFFECT_DISARM "disarm" +#define ATTACK_EFFECT_ASS_SLAP "ass_slap" +#define ATTACK_EFFECT_FACE_SLAP "face_slap" +#define ATTACK_EFFECT_BITE "bite" +#define ATTACK_EFFECT_MECHFIRE "mech_fire" +#define ATTACK_EFFECT_MECHTOXIN "mech_toxin" +#define ATTACK_EFFECT_BOOP "boop" //Honk + +//intent defines +#define INTENT_HELP "help" +#define INTENT_GRAB "grab" +#define INTENT_DISARM "disarm" +#define INTENT_HARM "harm" +//NOTE: INTENT_HOTKEY_* defines are not actual intents! +//they are here to support hotkeys +#define INTENT_HOTKEY_LEFT "left" +#define INTENT_HOTKEY_RIGHT "right" + +//the define for visible message range in combat +#define COMBAT_MESSAGE_RANGE 3 +#define DEFAULT_MESSAGE_RANGE 7 + +//Shove knockdown lengths (deciseconds) +#define SHOVE_KNOCKDOWN_SOLID 30 +#define SHOVE_KNOCKDOWN_HUMAN 30 +#define SHOVE_KNOCKDOWN_TABLE 30 +#define SHOVE_KNOCKDOWN_COLLATERAL 10 +//for the shove slowdown, see __DEFINES/movespeed_modification.dm +#define SHOVE_SLOWDOWN_LENGTH 30 +#define SHOVE_SLOWDOWN_STRENGTH 0.85 //multiplier +//Shove disarming item list +GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( + /obj/item/gun))) + + +//Combat object defines + +//Embedded objects +#define EMBEDDED_PAIN_CHANCE 15 //Chance for embedded objects to cause pain (damage user) +#define EMBEDDED_ITEM_FALLOUT 5 //Chance for embedded object to fall out (causing pain but removing the object) +#define EMBED_CHANCE 45 //Chance for an object to embed into somebody when thrown (if it's sharp) +#define EMBEDDED_PAIN_MULTIPLIER 2 //Coefficient of multiplication for the damage the item does while embedded (this*item.w_class) +#define EMBEDDED_FALL_PAIN_MULTIPLIER 5 //Coefficient of multiplication for the damage the item does when it falls out (this*item.w_class) +#define EMBEDDED_IMPACT_PAIN_MULTIPLIER 4 //Coefficient of multiplication for the damage the item does when it first embeds (this*item.w_class) +#define EMBED_THROWSPEED_THRESHOLD 4 //The minimum value of an item's throw_speed for it to embed (Unless it has embedded_ignore_throwspeed_threshold set to 1) +#define EMBEDDED_UNSAFE_REMOVAL_PAIN_MULTIPLIER 8 //Coefficient of multiplication for the damage the item does when removed without a surgery (this*item.w_class) +#define EMBEDDED_UNSAFE_REMOVAL_TIME 150 //A Time in ticks, total removal time = (this/item.w_class) + +//Gun weapon weight +#define WEAPON_LIGHT 1 +#define WEAPON_MEDIUM 2 +#define WEAPON_HEAVY 3 +//Gun trigger guards +#define TRIGGER_GUARD_ALLOW_ALL -1 +#define TRIGGER_GUARD_NONE 0 +#define TRIGGER_GUARD_NORMAL 1 +//E-gun self-recharge values +#define EGUN_NO_SELFCHARGE 0 +#define EGUN_SELFCHARGE 1 +#define EGUN_SELFCHARGE_BORG 2 + +//Object/Item sharpness +#define IS_BLUNT 0 +#define IS_SHARP 1 +#define IS_SHARP_ACCURATE 2 + +//His Grace. +#define HIS_GRACE_SATIATED 0 //He hungers not. If bloodthirst is set to this, His Grace is asleep. +#define HIS_GRACE_PECKISH 20 //Slightly hungry. +#define HIS_GRACE_HUNGRY 60 //Getting closer. Increases damage up to a minimum of 20. +#define HIS_GRACE_FAMISHED 100 //Dangerous. Increases damage up to a minimum of 25 and cannot be dropped. +#define HIS_GRACE_STARVING 120 //Incredibly close to breaking loose. Increases damage up to a minimum of 30. +#define HIS_GRACE_CONSUME_OWNER 140 //His Grace consumes His owner at this point and becomes aggressive. +#define HIS_GRACE_FALL_ASLEEP 160 //If it reaches this point, He falls asleep and resets. + +#define HIS_GRACE_FORCE_BONUS 4 //How much force is gained per kill. + +#define EXPLODE_NONE 0 //Don't even ask me why we need this. +#define EXPLODE_DEVASTATE 1 +#define EXPLODE_HEAVY 2 +#define EXPLODE_LIGHT 3 +#define EXPLODE_GIB_THRESHOLD 50 + +#define EMP_HEAVY 1 +#define EMP_LIGHT 2 + +#define GRENADE_CLUMSY_FUMBLE 1 +#define GRENADE_NONCLUMSY_FUMBLE 2 +#define GRENADE_NO_FUMBLE 3 + +#define BODY_ZONE_HEAD "head" +#define BODY_ZONE_CHEST "chest" +#define BODY_ZONE_L_ARM "l_arm" +#define BODY_ZONE_R_ARM "r_arm" +#define BODY_ZONE_L_LEG "l_leg" +#define BODY_ZONE_R_LEG "r_leg" + +#define BODY_ZONE_PRECISE_EYES "eyes" +#define BODY_ZONE_PRECISE_MOUTH "mouth" +#define BODY_ZONE_PRECISE_GROIN "groin" +#define BODY_ZONE_PRECISE_L_HAND "l_hand" +#define BODY_ZONE_PRECISE_R_HAND "r_hand" +#define BODY_ZONE_PRECISE_L_FOOT "l_foot" +#define BODY_ZONE_PRECISE_R_FOOT "r_foot" + +//We will round to this value in damage calculations. +#define DAMAGE_PRECISION 0.1 + +//items total mass, used to calculate their attacks' stamina costs. If not defined, the cost will be (w_class * 1.25) +#define TOTAL_MASS_TINY_ITEM 1.25 +#define TOTAL_MASS_SMALL_ITEM 2.5 +#define TOTAL_MASS_NORMAL_ITEM 3.75 +#define TOTAL_MASS_BULKY_ITEM 5 +#define TOTAL_MASS_HUGE_ITEM 6.25 +#define TOTAL_MASS_GIGANTIC_ITEM 7.5 + +#define TOTAL_MASS_HAND_REPLACEMENT 5 //standard punching stamina cost. most hand replacements are huge items anyway. +#define TOTAL_MASS_MEDIEVAL_WEAPON 3.6 //very, very generic average sword/warpick/etc. weight in pounds. +#define TOTAL_MASS_TOY_SWORD 1.5 diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm index b0cc9030cb..3c72454af6 100644 --- a/code/__DEFINES/components.dm +++ b/code/__DEFINES/components.dm @@ -1,348 +1,348 @@ -#define SEND_SIGNAL(target, sigtype, arguments...) ( !target.comp_lookup || !target.comp_lookup[sigtype] ? NONE : target._SendSignal(sigtype, list(target, ##arguments)) ) - -#define SEND_GLOBAL_SIGNAL(sigtype, arguments...) ( SEND_SIGNAL(SSdcs, sigtype, ##arguments) ) - -#define COMPONENT_INCOMPATIBLE 1 -#define COMPONENT_NOTRANSFER 2 - -#define ELEMENT_INCOMPATIBLE 1 // Return value to cancel attaching - -// /datum/element flags -/// Causes the detach proc to be called when the host object is being deleted -#define ELEMENT_DETACH (1 << 0) -/** - * Only elements created with the same arguments given after `id_arg_index` share an element instance - * The arguments are the same when the text and number values are the same and all other values have the same ref - */ -#define ELEMENT_BESPOKE (1 << 1) - -// 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_UNIQUE 2 //new component is deleted -#define COMPONENT_DUPE_UNIQUE_PASSARGS 4 //old component is given the initialization args of the new - -// All signals. Format: -// When the signal is called: (signal arguments) -// All signals send the source datum of the signal as the first argument - -// global signals -// These are signals which can be listened to by any component on any parent -// start global signals with "!", this used to be necessary but now it's just a formatting choice -#define COMSIG_GLOB_NEW_Z "!new_z" //from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args) -#define COMSIG_GLOB_VAR_EDIT "!var_edit" //called after a successful var edit somewhere in the world: (list/args) -#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special" //global living say plug - use sparingly: (mob/speaker , message) -////////////////////////////////////////////////////////////////// - -// /datum signals -#define COMSIG_COMPONENT_ADDED "component_added" //sent to the new datum parent when a component is added to them: (/datum/component) -#define COMSIG_COMPONENT_REMOVING "component_removing" //sent to the datum parent before a component is removed from them because of RemoveComponent: (/datum/component) -#define COMSIG_COMPONENT_UNREGISTER_PARENT "component_unregister_parent" //sent to the component itself when unregistered from a parent -#define COMSIG_COMPONENT_REGISTER_PARENT "component_register_parent" //sent to the component itself when registered to a parent -#define COMSIG_PARENT_PREQDELETED "parent_preqdeleted" //before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation -#define COMSIG_PARENT_QDELETING "parent_qdeleting" //just before a datum's Destroy() is called: (force), at this point none of the other components chose to interrupt qdel and Destroy will be called - -// /atom signals -#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params) - #define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called -#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human) -#define COMSIG_PARENT_EXAMINE "atom_examine" //from base of atom/examine(): (/mob) -#define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name" //from base of atom/get_examine_name(): (/mob, list/overrides) - //Positions for overrides list - #define EXAMINE_POSITION_ARTICLE 1 - #define EXAMINE_POSITION_BEFORE 2 - //End positions - #define COMPONENT_EXNAME_CHANGED 1 -#define COMSIG_ATOM_UPDATE_ICON "atom_update_icon" //from base of atom/update_icon(): () - #define COMSIG_ATOM_NO_UPDATE_ICON_STATE 1 - #define COMSIG_ATOM_NO_UPDATE_OVERLAYS 2 -#define COMSIG_ATOM_UPDATE_OVERLAYS "atom_update_overlays" //from base of atom/update_overlays(): (list/new_overlays) -#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable/entering, /atom) -#define COMSIG_ATOM_EXIT "atom_exit" //from base of atom/Exit(): (/atom/movable/exiting, /atom/newloc) - #define COMPONENT_ATOM_BLOCK_EXIT 1 -#define COMSIG_ATOM_EXITED "atom_exited" //from base of atom/Exited(): (atom/movable/exiting, atom/newloc) -#define COMSIG_ATOM_EX_ACT "atom_ex_act" //from base of atom/ex_act(): (severity, target) -#define COMSIG_ATOM_EMP_ACT "atom_emp_act" //from base of atom/emp_act(): (severity) -#define COMSIG_ATOM_FIRE_ACT "atom_fire_act" //from base of atom/fire_act(): (exposed_temperature, exposed_volume) -#define COMSIG_ATOM_BULLET_ACT "atom_bullet_act" //from base of atom/bullet_act(): (/obj/item/projectile, def_zone) -#define COMSIG_ATOM_BLOB_ACT "atom_blob_act" //from base of atom/blob_act(): (/obj/structure/blob) -#define COMSIG_ATOM_ACID_ACT "atom_acid_act" //from base of atom/acid_act(): (acidpwr, acid_volume) -#define COMSIG_ATOM_EMAG_ACT "atom_emag_act" //from base of atom/emag_act(): () -#define COMSIG_ATOM_RAD_ACT "atom_rad_act" //from base of atom/rad_act(intensity) -#define COMSIG_ATOM_NARSIE_ACT "atom_narsie_act" //from base of atom/narsie_act(): () -#define COMSIG_ATOM_RATVAR_ACT "atom_ratvar_act" //from base of atom/ratvar_act(): () -#define COMSIG_ATOM_RCD_ACT "atom_rcd_act" //from base of atom/rcd_act(): (/mob, /obj/item/construction/rcd, passed_mode) -#define COMSIG_ATOM_SING_PULL "atom_sing_pull" //from base of atom/singularity_pull(): (S, current_size) -#define COMSIG_ATOM_SET_LIGHT "atom_set_light" //from base of atom/set_light(): (l_range, l_power, l_color) -#define COMSIG_ATOM_DIR_CHANGE "atom_dir_change" //from base of atom/setDir(): (old_dir, new_dir) -#define COMSIG_ATOM_CONTENTS_DEL "atom_contents_del" //from base of atom/handle_atom_del(): (atom/deleted) -#define COMSIG_ATOM_HAS_GRAVITY "atom_has_gravity" //from base of atom/has_gravity(): (turf/location, list/forced_gravities) -#define COMSIG_ATOM_RAD_PROBE "atom_rad_probe" //from proc/get_rad_contents(): () - #define COMPONENT_BLOCK_RADIATION 1 -#define COMSIG_ATOM_RAD_CONTAMINATING "atom_rad_contam" //from base of datum/radiation_wave/radiate(): (strength) - #define COMPONENT_BLOCK_CONTAMINATION 1 -#define COMSIG_ATOM_RAD_WAVE_PASSING "atom_rad_wave_pass" //from base of datum/radiation_wave/check_obstructions(): (datum/radiation_wave, width) - #define COMPONENT_RAD_WAVE_HANDLED 1 -#define COMSIG_ATOM_CANREACH "atom_can_reach" //from internal loop in atom/movable/proc/CanReach(): (list/next) - #define COMPONENT_BLOCK_REACH 1 -#define COMSIG_ATOM_SCREWDRIVER_ACT "atom_screwdriver_act" //from base of atom/screwdriver_act(): (mob/living/user, obj/item/I) -#define COMSIG_ATOM_INTERCEPT_TELEPORT "intercept_teleport" //called when teleporting into a protected turf: (channel, turf/origin, turf/destination) - #define COMPONENT_BLOCK_TELEPORT 1 -#define COMSIG_ATOM_HEARER_IN_VIEW "atom_hearer_in_view" //called when an atom with HEAR_1 is added to the hearers on /proc/get_hearers_in_view(): (list/processing_list, list/hearers) -///////////////// -#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost" //from base of atom/attack_ghost(): (mob/dead/observer/ghost) -#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand" //from base of atom/attack_hand(): (mob/user) -#define COMSIG_ATOM_ATTACK_PAW "atom_attack_paw" //from base of atom/attack_paw(): (mob/user) - #define COMPONENT_NO_ATTACK_HAND 1 //works on all 3. -//This signal return value bitflags can be found in __DEFINES/misc.dm -#define COMSIG_ATOM_INTERCEPT_Z_FALL "movable_intercept_z_impact" //called for each movable in a turf contents on /turf/zImpact(): (atom/movable/A, levels) - - -///////////////// - -#define COMSIG_ENTER_AREA "enter_area" //from base of area/Entered(): (/area) -#define COMSIG_EXIT_AREA "exit_area" //from base of area/Exited(): (/area) - -#define COMSIG_CLICK "atom_click" //from base of atom/Click(): (location, control, params, mob/user) -#define COMSIG_CLICK_SHIFT "shift_click" //from base of atom/ShiftClick(): (/mob) -#define COMSIG_CLICK_CTRL "ctrl_click" //from base of atom/CtrlClickOn(): (/mob) -#define COMSIG_CLICK_ALT "alt_click" //from base of atom/AltClick(): (/mob) -#define COMSIG_CLICK_CTRL_SHIFT "ctrl_shift_click" //from base of atom/CtrlShiftClick(/mob) -#define COMSIG_MOUSEDROP_ONTO "mousedrop_onto" //from base of atom/MouseDrop(): (/atom/over, /mob/user) - #define COMPONENT_NO_MOUSEDROP 1 -#define COMSIG_MOUSEDROPPED_ONTO "mousedropped_onto" //from base of atom/MouseDrop_T: (/atom/from, /mob/user) - -// /area signals -#define COMSIG_AREA_ENTERED "area_entered" //from base of area/Entered(): (atom/movable/M) -#define COMSIG_AREA_EXITED "area_exited" //from base of area/Exited(): (atom/movable/M) - -// /turf signals -#define COMSIG_TURF_CHANGE "turf_change" //from base of turf/ChangeTurf(): (path, list/new_baseturfs, flags, list/transferring_comps) -#define COMSIG_TURF_HAS_GRAVITY "turf_has_gravity" //from base of atom/has_gravity(): (atom/asker, list/forced_gravities) -#define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new" //from base of turf/New(): (turf/source, direction) - -// /atom/movable signals -#define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (/atom, dir) -#define COMSIG_MOVABLE_CROSS "movable_cross" //from base of atom/movable/Cross(): (/atom/movable) -#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (/atom/movable) -#define COMSIG_MOVABLE_UNCROSS "movable_uncross" //from base of atom/movable/Uncross(): (/atom/movable) - #define COMPONENT_MOVABLE_BLOCK_UNCROSS 1 -#define COMSIG_MOVABLE_UNCROSSED "movable_uncrossed" //from base of atom/movable/Uncrossed(): (/atom/movable) -#define COMSIG_MOVABLE_BUMP "movable_bump" //from base of atom/movable/Bump(): (/atom) -#define COMSIG_MOVABLE_IMPACT "movable_impact" //from base of atom/movable/throw_impact(): (/atom/hit_atom, /datum/thrownthing/throwingdatum) -#define COMSIG_MOVABLE_IMPACT_ZONE "item_impact_zone" //from base of mob/living/hitby(): (mob/living/target, hit_zone) -#define COMSIG_MOVABLE_BUCKLE "buckle" //from base of atom/movable/buckle_mob(): (mob, force) -#define COMSIG_MOVABLE_UNBUCKLE "unbuckle" //from base of atom/movable/unbuckle_mob(): (mob, force) -#define COMSIG_MOVABLE_PRE_THROW "movable_pre_throw" //from base of atom/movable/throw_at(): (list/args) - #define COMPONENT_CANCEL_THROW 1 -#define COMSIG_MOVABLE_POST_THROW "movable_post_throw" //from base of atom/movable/throw_at(): (datum/thrownthing, spin) -#define COMSIG_MOVABLE_Z_CHANGED "movable_ztransit" //from base of atom/movable/onTransitZ(): (old_z, new_z) -#define COMSIG_MOVABLE_SECLUDED_LOCATION "movable_secluded" //called when the movable is placed in an unaccessible area, used for stationloving: () -#define COMSIG_MOVABLE_HEAR "movable_hear" //from base of atom/movable/Hear(): (message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source) - #define HEARING_MESSAGE 1 - #define HEARING_SPEAKER 2 -// #define HEARING_LANGUAGE 3 - #define HEARING_RAW_MESSAGE 4 - /* #define HEARING_RADIO_FREQ 5 - #define HEARING_SPANS 6 - #define HEARING_MESSAGE_MODE 7 - #define HEARING_SOURCE 8*/ -#define COMSIG_MOVABLE_DISPOSING "movable_disposing" //called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source) -#define COMSIG_MOVABLE_TELEPORTED "movable_teleported" //from base of do_teleport(): (channel, turf/origin, turf/destination) - -// /mind signals -#define COMSIG_PRE_MIND_TRANSFER "pre_mind_transfer" //from base of mind/transfer_to() before it's done: (new_character, old_character) - #define COMPONENT_STOP_MIND_TRANSFER 1 //stops the mind transfer from happening. -#define COMSIG_MIND_TRANSFER "mind_transfer" //from base of mind/transfer_to() when it's done: (new_character, old_character) - -// /mob signals -#define COMSIG_MOB_EXAMINATE "mob_examinate" //from base of /mob/verb/examinate(): (atom/A) - #define COMPONENT_ALLOW_EXAMINE 1 -#define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed) - #define COMPONENT_BLOCK_DEATH_BROADCAST 1 //stops the death from being broadcasted in deadchat. -#define COMSIG_MOB_GHOSTIZE "mob_ghostize" //from base of mob/Ghostize(): (can_reenter_corpse, special, penalize) - #define COMPONENT_BLOCK_GHOSTING 1 -#define COMSIG_MOB_ALLOWED "mob_allowed" //from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj -#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" //from base of mob/anti_magic_check(): (mob/user, magic, holy, tinfoil, chargecost, self, protection_sources) - #define COMPONENT_BLOCK_MAGIC 1 -#define COMSIG_MOB_HUD_CREATED "mob_hud_created" //from base of mob/create_mob_hud(): () -#define COMSIG_MOB_ATTACK_HAND "mob_attack_hand" //from base of -#define COMSIG_MOB_ITEM_ATTACK "mob_item_attack" //from base of /obj/item/attack(): (mob/M, mob/user) - #define COMPONENT_ITEM_NO_ATTACK 1 -#define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters) -#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //from base of mob/RangedAttack(): (atom/A, params) -#define COMSIG_MOB_THROW "mob_throw" //from base of /mob/throw_item(): (atom/target) -#define COMSIG_MOB_KEY_CHANGE "mob_key_change" //from base of /mob/transfer_ckey(): (new_character, old_character) -#define COMSIG_MOB_PRE_PLAYER_CHANGE "mob_pre_player_change" //sent to the target mob from base of /mob/transfer_ckey() and /mind/transfer_to(): (our_character, their_character) -// #define COMPONENT_STOP_MIND_TRANSFER 1 -#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): () -#define COMSIG_MOB_ON_NEW_MIND "mob_on_new_mind" //called when a new mind is assigned to a mob: () -#define COMSIG_MOB_SAY "mob_say" // from /mob/living/say(): (proc args list) - #define COMPONENT_UPPERCASE_SPEECH 1 - // used to access COMSIG_MOB_SAY argslist - #define SPEECH_MESSAGE 1 - // #define SPEECH_BUBBLE_TYPE 2 - #define SPEECH_SPANS 3 - /* #define SPEECH_SANITIZE 4 - #define SPEECH_LANGUAGE 5 - #define SPEECH_IGNORE_SPAM 6 - #define SPEECH_FORCED 7 */ - -// /mob/living signals -#define COMSIG_LIVING_FULLY_HEAL "living_fully_healed" //from base of /mob/living/fully_heal(): (admin_revive) -#define COMSIG_LIVING_REGENERATE_LIMBS "living_regenerate_limbs" //from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs) -#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living) -#define COMSIG_LIVING_IGNITED "living_ignite" //from base of mob/living/IgniteMob() (/mob/living) -#define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //from base of mob/living/ExtinguishMob() (/mob/living) -#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage) -#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: () -#define COMSIG_LIVING_GUN_PROCESS_FIRE "living_gun_process_fire" //from base of /obj/item/gun/proc/process_fire(): (atom/target, params, zone_override) - -// /mob/living/carbon signals -#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity)) - -// /mob/living/simple_animal/hostile signals -#define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget" - #define COMPONENT_HOSTILE_NO_ATTACK 1 - -// /obj signals -#define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct" //from base of obj/deconstruct(): (disassembled) -#define COMSIG_OBJ_BREAK "obj_break" //from base of /obj/obj_break(): (damage_flag) -#define COMSIG_OBJ_SETANCHORED "obj_setanchored" //called in /obj/structure/setAnchored(): (value) - -// /machinery signals -#define COMSIG_MACHINE_EJECT_OCCUPANT "eject_occupant" //from base of obj/machinery/dropContents() (occupant) - -// /obj/item signals -#define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user) -#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob) - #define COMPONENT_NO_INTERACT 1 -#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //from base of obj/item/attack_obj(): (/obj, /mob) - #define COMPONENT_NO_ATTACK_OBJ 1 -#define COMSIG_ITEM_PRE_ATTACK "item_pre_attack" //from base of obj/item/pre_attack(): (atom/target, mob/user, params) - #define COMPONENT_NO_ATTACK 1 -#define COMSIG_ITEM_AFTERATTACK "item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, params) -#define COMSIG_ITEM_EQUIPPED "item_equip" //from base of obj/item/equipped(): (/mob/equipper, slot) -#define COMSIG_ITEM_DROPPED "item_drop" //from base of obj/item/dropped(): (mob/user) -#define COMSIG_ITEM_PICKUP "item_pickup" //from base of obj/item/pickup(): (/mob/taker) -#define COMSIG_ITEM_ATTACK_ZONE "item_attack_zone" //from base of mob/living/carbon/attacked_by(): (mob/living/carbon/target, mob/living/user, hit_zone) -#define COMSIG_ITEM_IMBUE_SOUL "item_imbue_soul" //return a truthy value to prevent ensouling, checked in /obj/effect/proc_holder/spell/targeted/lichdom/cast(): (mob/user) -#define COMSIG_ITEM_HIT_REACT "item_hit_react" //from base of obj/item/hit_reaction(): (list/args) - -// /obj/item/clothing signals -#define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): () - -// /obj/item/implant signals -#define COMSIG_IMPLANT_ACTIVATED "implant_activated" //from base of /obj/item/implant/proc/activate(): () -#define COMSIG_IMPLANT_IMPLANTING "implant_implanting" //from base of /obj/item/implant/proc/implant(): (list/args) - #define COMPONENT_STOP_IMPLANTING 1 -#define COMSIG_IMPLANT_OTHER "implant_other" //called on already installed implants when a new one is being added in /obj/item/implant/proc/implant(): (list/args, obj/item/implant/new_implant) - //#define COMPONENT_STOP_IMPLANTING 1 //The name makes sense for both - #define COMPONENT_DELETE_NEW_IMPLANT 2 - #define COMPONENT_DELETE_OLD_IMPLANT 4 -#define COMSIG_IMPLANT_EXISTING_UPLINK "implant_uplink_exists" //called on implants being implanted into someone with an uplink implant: (datum/component/uplink) - //This uses all return values of COMSIG_IMPLANT_OTHER -#define COMSIG_IMPLANT_REMOVING "implant_removing" //from base of /obj/item/implant/proc/removed() (list/args) - -// /obj/item/pda signals -#define COMSIG_PDA_CHANGE_RINGTONE "pda_change_ringtone" //called on pda when the user changes the ringtone: (mob/living/user, new_ringtone) - #define COMPONENT_STOP_RINGTONE_CHANGE 1 - -// /obj/item/radio signals -#define COMSIG_RADIO_NEW_FREQUENCY "radio_new_frequency" //called from base of /obj/item/radio/proc/set_frequency(): (list/args) - -// /obj/item/pen signals -#define COMSIG_PEN_ROTATED "pen_rotated" //called after rotation in /obj/item/pen/attack_self(): (rotation, mob/living/carbon/user) - -// /obj/item/projectile signals (sent to the firer) -#define COMSIG_PROJECTILE_ON_HIT "projectile_on_hit" // from base of /obj/item/projectile/proc/on_hit(): (atom/movable/firer, atom/target, Angle) -#define COMSIG_PROJECTILE_BEFORE_FIRE "projectile_before_fire" // from base of /obj/item/projectile/proc/fire(): (obj/item/projectile, atom/original_target) - -// /mob/living/carbon/human signals -#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target) -#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker) -#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit" //Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted) - -// /datum/species signals -#define COMSIG_SPECIES_GAIN "species_gain" //from datum/species/on_species_gain(): (datum/species/new_species, datum/species/old_species) -#define COMSIG_SPECIES_LOSS "species_loss" //from datum/species/on_species_loss(): (datum/species/lost_species) - -/*******Component Specific Signals*******/ -//Janitor -#define COMSIG_TURF_IS_WET "check_turf_wet" //(): Returns bitflags of wet values. -#define COMSIG_TURF_MAKE_DRY "make_turf_try" //(max_strength, immediate, duration_decrease = INFINITY): Returns bool. -#define COMSIG_COMPONENT_CLEAN_ACT "clean_act" //called on an object to clean it of cleanables. Usualy with soap: (num/strength) - -//Blood color -#define COMSIG_BLOOD_COLOR "blood_DNA_to_color" //RGB blood stuff -//Food -#define COMSIG_FOOD_EATEN "food_eaten" //from base of obj/item/reagent_containers/food/snacks/attack(): (mob/living/eater, mob/feeder) - -//Gibs -#define COMSIG_GIBS_STREAK "gibs_streak" // from base of /obj/effect/decal/cleanable/blood/gibs/streak(): (list/directions, list/diseases) - -//Mood -#define COMSIG_ADD_MOOD_EVENT "add_mood" //Called when you send a mood event from anywhere in the code. -#define COMSIG_CLEAR_MOOD_EVENT "clear_mood" //Called when you clear a mood event from anywhere in the code. -#define COMSIG_MODIFY_SANITY "modify_sanity" //Called when you want to increase or decrease sanity from anywhere in the code. - -//NTnet -#define COMSIG_COMPONENT_NTNET_RECEIVE "ntnet_receive" //called on an object by its NTNET connection component on receive. (sending_id(number), sending_netname(text), data(datum/netdata)) - -//Nanites -#define COMSIG_HAS_NANITES "has_nanites" //() returns TRUE if nanites are found -#define COMSIG_NANITE_GET_PROGRAMS "nanite_get_programs" //(list/nanite_programs) - makes the input list a copy the nanites' program list -#define COMSIG_NANITE_SET_VOLUME "nanite_set_volume" //(amount) Sets current nanite volume to the given amount -#define COMSIG_NANITE_ADJUST_VOLUME "nanite_adjust" //(amount) Adjusts nanite volume by the given amount -#define COMSIG_NANITE_SET_MAX_VOLUME "nanite_set_max_volume" //(amount) Sets maximum nanite volume to the given amount -#define COMSIG_NANITE_SET_CLOUD "nanite_set_cloud" //(amount(0-100)) Sets cloud ID to the given amount -#define COMSIG_NANITE_SET_SAFETY "nanite_set_safety" //(amount) Sets safety threshold to the given amount -#define COMSIG_NANITE_SET_REGEN "nanite_set_regen" //(amount) Sets regeneration rate to the given amount -#define COMSIG_NANITE_SIGNAL "nanite_signal" //(code(1-9999)) Called when sending a nanite signal to a mob. -#define COMSIG_NANITE_SCAN "nanite_scan" //(mob/user, full_scan) - sends to chat a scan of the nanites to the user, returns TRUE if nanites are detected -#define COMSIG_NANITE_UI_DATA "nanite_ui_data" //(list/data, scan_level) - adds nanite data to the given data list - made for ui_data procs -#define COMSIG_NANITE_ADD_PROGRAM "nanite_add_program" //(datum/nanite_program/new_program, datum/nanite_program/source_program) Called when adding a program to a nanite component - #define COMPONENT_PROGRAM_INSTALLED 1 //Installation successful - #define COMPONENT_PROGRAM_NOT_INSTALLED 2 //Installation failed, but there are still nanites -#define COMSIG_NANITE_SYNC "nanite_sync" //(datum/component/nanites, full_overwrite, copy_activation) Called to sync the target's nanites to a given nanite component - -// /datum/component/storage signals -#define COMSIG_CONTAINS_STORAGE "is_storage" //() - returns bool. -#define COMSIG_TRY_STORAGE_INSERT "storage_try_insert" //(obj/item/inserting, mob/user, silent, force) - returns bool -#define COMSIG_TRY_STORAGE_SHOW "storage_show_to" //(mob/show_to, force) - returns bool. -#define COMSIG_TRY_STORAGE_HIDE_FROM "storage_hide_from" //(mob/hide_from) - returns bool -#define COMSIG_TRY_STORAGE_HIDE_ALL "storage_hide_all" //returns bool -#define COMSIG_TRY_STORAGE_SET_LOCKSTATE "storage_lock_set_state" //(newstate) -#define COMSIG_IS_STORAGE_LOCKED "storage_get_lockstate" //() - returns bool. MUST CHECK IF STORAGE IS THERE FIRST! -#define COMSIG_TRY_STORAGE_TAKE_TYPE "storage_take_type" //(type, atom/destination, amount = INFINITY, check_adjacent, force, mob/user, list/inserted) - returns bool - type can be a list of types. -#define COMSIG_TRY_STORAGE_FILL_TYPE "storage_fill_type" //(type, amount = INFINITY, force = FALSE) //don't fuck this up. Force will ignore max_items, and amount is normally clamped to max_items. -#define COMSIG_TRY_STORAGE_TAKE "storage_take_obj" //(obj, new_loc, force = FALSE) - returns bool -#define COMSIG_TRY_STORAGE_QUICK_EMPTY "storage_quick_empty" //(loc) - returns bool - if loc is null it will dump at parent location. -#define COMSIG_TRY_STORAGE_RETURN_INVENTORY "storage_return_inventory" //(list/list_to_inject_results_into, recursively_search_inside_storages = TRUE) -#define COMSIG_TRY_STORAGE_CAN_INSERT "storage_can_equip" //(obj/item/insertion_candidate, mob/user, silent) - returns bool - -// /datum/action signals -#define COMSIG_ACTION_TRIGGER "action_trigger" //from base of datum/action/proc/Trigger(): (datum/action) - #define COMPONENT_ACTION_BLOCK_TRIGGER 1 - -/*******Non-Signal Component Related Defines*******/ - -//Redirection component init flags -#define REDIRECT_TRANSFER_WITH_TURF 1 - -//Arch -#define ARCH_PROB "probability" //Probability for each item -#define ARCH_MAXDROP "max_drop_amount" //each item's max drop amount - -//Ouch my toes! -#define CALTROP_BYPASS_SHOES 1 -#define CALTROP_IGNORE_WALKERS 2 - -//Xenobio hotkeys -#define COMSIG_XENO_SLIME_CLICK_CTRL "xeno_slime_click_ctrl" //from slime CtrlClickOn(): (/mob) -#define COMSIG_XENO_SLIME_CLICK_ALT "xeno_slime_click_alt" //from slime AltClickOn(): (/mob) -#define COMSIG_XENO_SLIME_CLICK_SHIFT "xeno_slime_click_shift" //from slime ShiftClickOn(): (/mob) -#define COMSIG_XENO_TURF_CLICK_SHIFT "xeno_turf_click_shift" //from turf ShiftClickOn(): (/mob) -#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt" //from turf AltClickOn(): (/mob) -#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" //from monkey CtrlClickOn(): (/mob) +#define SEND_SIGNAL(target, sigtype, arguments...) ( !target.comp_lookup || !target.comp_lookup[sigtype] ? NONE : target._SendSignal(sigtype, list(target, ##arguments)) ) + +#define SEND_GLOBAL_SIGNAL(sigtype, arguments...) ( SEND_SIGNAL(SSdcs, sigtype, ##arguments) ) + +#define COMPONENT_INCOMPATIBLE 1 +#define COMPONENT_NOTRANSFER 2 + +#define ELEMENT_INCOMPATIBLE 1 // Return value to cancel attaching + +// /datum/element flags +/// Causes the detach proc to be called when the host object is being deleted +#define ELEMENT_DETACH (1 << 0) +/** + * Only elements created with the same arguments given after `id_arg_index` share an element instance + * The arguments are the same when the text and number values are the same and all other values have the same ref + */ +#define ELEMENT_BESPOKE (1 << 1) + +// 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_UNIQUE 2 //new component is deleted +#define COMPONENT_DUPE_UNIQUE_PASSARGS 4 //old component is given the initialization args of the new + +// All signals. Format: +// When the signal is called: (signal arguments) +// All signals send the source datum of the signal as the first argument + +// global signals +// These are signals which can be listened to by any component on any parent +// start global signals with "!", this used to be necessary but now it's just a formatting choice +#define COMSIG_GLOB_NEW_Z "!new_z" //from base of datum/controller/subsystem/mapping/proc/add_new_zlevel(): (list/args) +#define COMSIG_GLOB_VAR_EDIT "!var_edit" //called after a successful var edit somewhere in the world: (list/args) +#define COMSIG_GLOB_LIVING_SAY_SPECIAL "!say_special" //global living say plug - use sparingly: (mob/speaker , message) +////////////////////////////////////////////////////////////////// + +// /datum signals +#define COMSIG_COMPONENT_ADDED "component_added" //sent to the new datum parent when a component is added to them: (/datum/component) +#define COMSIG_COMPONENT_REMOVING "component_removing" //sent to the datum parent before a component is removed from them because of RemoveComponent: (/datum/component) +#define COMSIG_COMPONENT_UNREGISTER_PARENT "component_unregister_parent" //sent to the component itself when unregistered from a parent +#define COMSIG_COMPONENT_REGISTER_PARENT "component_register_parent" //sent to the component itself when registered to a parent +#define COMSIG_PARENT_PREQDELETED "parent_preqdeleted" //before a datum's Destroy() is called: (force), returning a nonzero value will cancel the qdel operation +#define COMSIG_PARENT_QDELETING "parent_qdeleting" //just before a datum's Destroy() is called: (force), at this point none of the other components chose to interrupt qdel and Destroy will be called + +// /atom signals +#define COMSIG_PARENT_ATTACKBY "atom_attackby" //from base of atom/attackby(): (/obj/item, /mob/living, params) + #define COMPONENT_NO_AFTERATTACK 1 //Return this in response if you don't want afterattack to be called +#define COMSIG_ATOM_HULK_ATTACK "hulk_attack" //from base of atom/attack_hulk(): (/mob/living/carbon/human) +#define COMSIG_PARENT_EXAMINE "atom_examine" //from base of atom/examine(): (/mob) +#define COMSIG_ATOM_GET_EXAMINE_NAME "atom_examine_name" //from base of atom/get_examine_name(): (/mob, list/overrides) + //Positions for overrides list + #define EXAMINE_POSITION_ARTICLE 1 + #define EXAMINE_POSITION_BEFORE 2 + //End positions + #define COMPONENT_EXNAME_CHANGED 1 +#define COMSIG_ATOM_UPDATE_ICON "atom_update_icon" //from base of atom/update_icon(): () + #define COMSIG_ATOM_NO_UPDATE_ICON_STATE 1 + #define COMSIG_ATOM_NO_UPDATE_OVERLAYS 2 +#define COMSIG_ATOM_UPDATE_OVERLAYS "atom_update_overlays" //from base of atom/update_overlays(): (list/new_overlays) +#define COMSIG_ATOM_ENTERED "atom_entered" //from base of atom/Entered(): (atom/movable/entering, /atom) +#define COMSIG_ATOM_EXIT "atom_exit" //from base of atom/Exit(): (/atom/movable/exiting, /atom/newloc) + #define COMPONENT_ATOM_BLOCK_EXIT 1 +#define COMSIG_ATOM_EXITED "atom_exited" //from base of atom/Exited(): (atom/movable/exiting, atom/newloc) +#define COMSIG_ATOM_EX_ACT "atom_ex_act" //from base of atom/ex_act(): (severity, target) +#define COMSIG_ATOM_EMP_ACT "atom_emp_act" //from base of atom/emp_act(): (severity) +#define COMSIG_ATOM_FIRE_ACT "atom_fire_act" //from base of atom/fire_act(): (exposed_temperature, exposed_volume) +#define COMSIG_ATOM_BULLET_ACT "atom_bullet_act" //from base of atom/bullet_act(): (/obj/item/projectile, def_zone) +#define COMSIG_ATOM_BLOB_ACT "atom_blob_act" //from base of atom/blob_act(): (/obj/structure/blob) +#define COMSIG_ATOM_ACID_ACT "atom_acid_act" //from base of atom/acid_act(): (acidpwr, acid_volume) +#define COMSIG_ATOM_EMAG_ACT "atom_emag_act" //from base of atom/emag_act(): () +#define COMSIG_ATOM_RAD_ACT "atom_rad_act" //from base of atom/rad_act(intensity) +#define COMSIG_ATOM_NARSIE_ACT "atom_narsie_act" //from base of atom/narsie_act(): () +#define COMSIG_ATOM_RATVAR_ACT "atom_ratvar_act" //from base of atom/ratvar_act(): () +#define COMSIG_ATOM_RCD_ACT "atom_rcd_act" //from base of atom/rcd_act(): (/mob, /obj/item/construction/rcd, passed_mode) +#define COMSIG_ATOM_SING_PULL "atom_sing_pull" //from base of atom/singularity_pull(): (S, current_size) +#define COMSIG_ATOM_SET_LIGHT "atom_set_light" //from base of atom/set_light(): (l_range, l_power, l_color) +#define COMSIG_ATOM_DIR_CHANGE "atom_dir_change" //from base of atom/setDir(): (old_dir, new_dir) +#define COMSIG_ATOM_CONTENTS_DEL "atom_contents_del" //from base of atom/handle_atom_del(): (atom/deleted) +#define COMSIG_ATOM_HAS_GRAVITY "atom_has_gravity" //from base of atom/has_gravity(): (turf/location, list/forced_gravities) +#define COMSIG_ATOM_RAD_PROBE "atom_rad_probe" //from proc/get_rad_contents(): () + #define COMPONENT_BLOCK_RADIATION 1 +#define COMSIG_ATOM_RAD_CONTAMINATING "atom_rad_contam" //from base of datum/radiation_wave/radiate(): (strength) + #define COMPONENT_BLOCK_CONTAMINATION 1 +#define COMSIG_ATOM_RAD_WAVE_PASSING "atom_rad_wave_pass" //from base of datum/radiation_wave/check_obstructions(): (datum/radiation_wave, width) + #define COMPONENT_RAD_WAVE_HANDLED 1 +#define COMSIG_ATOM_CANREACH "atom_can_reach" //from internal loop in atom/movable/proc/CanReach(): (list/next) + #define COMPONENT_BLOCK_REACH 1 +#define COMSIG_ATOM_SCREWDRIVER_ACT "atom_screwdriver_act" //from base of atom/screwdriver_act(): (mob/living/user, obj/item/I) +#define COMSIG_ATOM_INTERCEPT_TELEPORT "intercept_teleport" //called when teleporting into a protected turf: (channel, turf/origin, turf/destination) + #define COMPONENT_BLOCK_TELEPORT 1 +#define COMSIG_ATOM_HEARER_IN_VIEW "atom_hearer_in_view" //called when an atom with HEAR_1 is added to the hearers on /proc/get_hearers_in_view(): (list/processing_list, list/hearers) +///////////////// +#define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost" //from base of atom/attack_ghost(): (mob/dead/observer/ghost) +#define COMSIG_ATOM_ATTACK_HAND "atom_attack_hand" //from base of atom/attack_hand(): (mob/user) +#define COMSIG_ATOM_ATTACK_PAW "atom_attack_paw" //from base of atom/attack_paw(): (mob/user) + #define COMPONENT_NO_ATTACK_HAND 1 //works on all 3. +//This signal return value bitflags can be found in __DEFINES/misc.dm +#define COMSIG_ATOM_INTERCEPT_Z_FALL "movable_intercept_z_impact" //called for each movable in a turf contents on /turf/zImpact(): (atom/movable/A, levels) + + +///////////////// + +#define COMSIG_ENTER_AREA "enter_area" //from base of area/Entered(): (/area) +#define COMSIG_EXIT_AREA "exit_area" //from base of area/Exited(): (/area) + +#define COMSIG_CLICK "atom_click" //from base of atom/Click(): (location, control, params, mob/user) +#define COMSIG_CLICK_SHIFT "shift_click" //from base of atom/ShiftClick(): (/mob) +#define COMSIG_CLICK_CTRL "ctrl_click" //from base of atom/CtrlClickOn(): (/mob) +#define COMSIG_CLICK_ALT "alt_click" //from base of atom/AltClick(): (/mob) +#define COMSIG_CLICK_CTRL_SHIFT "ctrl_shift_click" //from base of atom/CtrlShiftClick(/mob) +#define COMSIG_MOUSEDROP_ONTO "mousedrop_onto" //from base of atom/MouseDrop(): (/atom/over, /mob/user) + #define COMPONENT_NO_MOUSEDROP 1 +#define COMSIG_MOUSEDROPPED_ONTO "mousedropped_onto" //from base of atom/MouseDrop_T: (/atom/from, /mob/user) + +// /area signals +#define COMSIG_AREA_ENTERED "area_entered" //from base of area/Entered(): (atom/movable/M) +#define COMSIG_AREA_EXITED "area_exited" //from base of area/Exited(): (atom/movable/M) + +// /turf signals +#define COMSIG_TURF_CHANGE "turf_change" //from base of turf/ChangeTurf(): (path, list/new_baseturfs, flags, list/transferring_comps) +#define COMSIG_TURF_HAS_GRAVITY "turf_has_gravity" //from base of atom/has_gravity(): (atom/asker, list/forced_gravities) +#define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new" //from base of turf/New(): (turf/source, direction) + +// /atom/movable signals +#define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (/atom, dir) +#define COMSIG_MOVABLE_CROSS "movable_cross" //from base of atom/movable/Cross(): (/atom/movable) +#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (/atom/movable) +#define COMSIG_MOVABLE_UNCROSS "movable_uncross" //from base of atom/movable/Uncross(): (/atom/movable) + #define COMPONENT_MOVABLE_BLOCK_UNCROSS 1 +#define COMSIG_MOVABLE_UNCROSSED "movable_uncrossed" //from base of atom/movable/Uncrossed(): (/atom/movable) +#define COMSIG_MOVABLE_BUMP "movable_bump" //from base of atom/movable/Bump(): (/atom) +#define COMSIG_MOVABLE_IMPACT "movable_impact" //from base of atom/movable/throw_impact(): (/atom/hit_atom, /datum/thrownthing/throwingdatum) +#define COMSIG_MOVABLE_IMPACT_ZONE "item_impact_zone" //from base of mob/living/hitby(): (mob/living/target, hit_zone) +#define COMSIG_MOVABLE_BUCKLE "buckle" //from base of atom/movable/buckle_mob(): (mob, force) +#define COMSIG_MOVABLE_UNBUCKLE "unbuckle" //from base of atom/movable/unbuckle_mob(): (mob, force) +#define COMSIG_MOVABLE_PRE_THROW "movable_pre_throw" //from base of atom/movable/throw_at(): (list/args) + #define COMPONENT_CANCEL_THROW 1 +#define COMSIG_MOVABLE_POST_THROW "movable_post_throw" //from base of atom/movable/throw_at(): (datum/thrownthing, spin) +#define COMSIG_MOVABLE_Z_CHANGED "movable_ztransit" //from base of atom/movable/onTransitZ(): (old_z, new_z) +#define COMSIG_MOVABLE_SECLUDED_LOCATION "movable_secluded" //called when the movable is placed in an unaccessible area, used for stationloving: () +#define COMSIG_MOVABLE_HEAR "movable_hear" //from base of atom/movable/Hear(): (message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source) + #define HEARING_MESSAGE 1 + #define HEARING_SPEAKER 2 +// #define HEARING_LANGUAGE 3 + #define HEARING_RAW_MESSAGE 4 + /* #define HEARING_RADIO_FREQ 5 + #define HEARING_SPANS 6 + #define HEARING_MESSAGE_MODE 7 + #define HEARING_SOURCE 8*/ +#define COMSIG_MOVABLE_DISPOSING "movable_disposing" //called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source) +#define COMSIG_MOVABLE_TELEPORTED "movable_teleported" //from base of do_teleport(): (channel, turf/origin, turf/destination) + +// /mind signals +#define COMSIG_PRE_MIND_TRANSFER "pre_mind_transfer" //from base of mind/transfer_to() before it's done: (new_character, old_character) + #define COMPONENT_STOP_MIND_TRANSFER 1 //stops the mind transfer from happening. +#define COMSIG_MIND_TRANSFER "mind_transfer" //from base of mind/transfer_to() when it's done: (new_character, old_character) + +// /mob signals +#define COMSIG_MOB_EXAMINATE "mob_examinate" //from base of /mob/verb/examinate(): (atom/A) + #define COMPONENT_ALLOW_EXAMINE 1 +#define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed) + #define COMPONENT_BLOCK_DEATH_BROADCAST 1 //stops the death from being broadcasted in deadchat. +#define COMSIG_MOB_GHOSTIZE "mob_ghostize" //from base of mob/Ghostize(): (can_reenter_corpse, special, penalize) + #define COMPONENT_BLOCK_GHOSTING 1 +#define COMSIG_MOB_ALLOWED "mob_allowed" //from base of obj/allowed(mob/M): (/obj) returns bool, if TRUE the mob has id access to the obj +#define COMSIG_MOB_RECEIVE_MAGIC "mob_receive_magic" //from base of mob/anti_magic_check(): (mob/user, magic, holy, tinfoil, chargecost, self, protection_sources) + #define COMPONENT_BLOCK_MAGIC 1 +#define COMSIG_MOB_HUD_CREATED "mob_hud_created" //from base of mob/create_mob_hud(): () +#define COMSIG_MOB_ATTACK_HAND "mob_attack_hand" //from base of +#define COMSIG_MOB_ITEM_ATTACK "mob_item_attack" //from base of /obj/item/attack(): (mob/M, mob/user) + #define COMPONENT_ITEM_NO_ATTACK 1 +#define COMSIG_MOB_ITEM_AFTERATTACK "mob_item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, proximity_flag, click_parameters) +#define COMSIG_MOB_ATTACK_RANGED "mob_attack_ranged" //from base of mob/RangedAttack(): (atom/A, params) +#define COMSIG_MOB_THROW "mob_throw" //from base of /mob/throw_item(): (atom/target) +#define COMSIG_MOB_KEY_CHANGE "mob_key_change" //from base of /mob/transfer_ckey(): (new_character, old_character) +#define COMSIG_MOB_PRE_PLAYER_CHANGE "mob_pre_player_change" //sent to the target mob from base of /mob/transfer_ckey() and /mind/transfer_to(): (our_character, their_character) +// #define COMPONENT_STOP_MIND_TRANSFER 1 +#define COMSIG_MOB_UPDATE_SIGHT "mob_update_sight" //from base of /mob/update_sight(): () +#define COMSIG_MOB_ON_NEW_MIND "mob_on_new_mind" //called when a new mind is assigned to a mob: () +#define COMSIG_MOB_SAY "mob_say" // from /mob/living/say(): (proc args list) + #define COMPONENT_UPPERCASE_SPEECH 1 + // used to access COMSIG_MOB_SAY argslist + #define SPEECH_MESSAGE 1 + // #define SPEECH_BUBBLE_TYPE 2 + #define SPEECH_SPANS 3 + /* #define SPEECH_SANITIZE 4 + #define SPEECH_LANGUAGE 5 + #define SPEECH_IGNORE_SPAM 6 + #define SPEECH_FORCED 7 */ + +// /mob/living signals +#define COMSIG_LIVING_FULLY_HEAL "living_fully_healed" //from base of /mob/living/fully_heal(): (admin_revive) +#define COMSIG_LIVING_REGENERATE_LIMBS "living_regenerate_limbs" //from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs) +#define COMSIG_LIVING_RESIST "living_resist" //from base of mob/living/resist() (/mob/living) +#define COMSIG_LIVING_IGNITED "living_ignite" //from base of mob/living/IgniteMob() (/mob/living) +#define COMSIG_LIVING_EXTINGUISHED "living_extinguished" //from base of mob/living/ExtinguishMob() (/mob/living) +#define COMSIG_LIVING_ELECTROCUTE_ACT "living_electrocute_act" //from base of mob/living/electrocute_act(): (shock_damage) +#define COMSIG_LIVING_MINOR_SHOCK "living_minor_shock" //sent by stuff like stunbatons and tasers: () +#define COMSIG_LIVING_GUN_PROCESS_FIRE "living_gun_process_fire" //from base of /obj/item/gun/proc/process_fire(): (atom/target, params, zone_override) + +// /mob/living/carbon signals +#define COMSIG_CARBON_SOUNDBANG "carbon_soundbang" //from base of mob/living/carbon/soundbang_act(): (list(intensity)) + +// /mob/living/simple_animal/hostile signals +#define COMSIG_HOSTILE_ATTACKINGTARGET "hostile_attackingtarget" + #define COMPONENT_HOSTILE_NO_ATTACK 1 + +// /obj signals +#define COMSIG_OBJ_DECONSTRUCT "obj_deconstruct" //from base of obj/deconstruct(): (disassembled) +#define COMSIG_OBJ_BREAK "obj_break" //from base of /obj/obj_break(): (damage_flag) +#define COMSIG_OBJ_SETANCHORED "obj_setanchored" //called in /obj/structure/setAnchored(): (value) + +// /machinery signals +#define COMSIG_MACHINE_EJECT_OCCUPANT "eject_occupant" //from base of obj/machinery/dropContents() (occupant) + +// /obj/item signals +#define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user) +#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob) + #define COMPONENT_NO_INTERACT 1 +#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //from base of obj/item/attack_obj(): (/obj, /mob) + #define COMPONENT_NO_ATTACK_OBJ 1 +#define COMSIG_ITEM_PRE_ATTACK "item_pre_attack" //from base of obj/item/pre_attack(): (atom/target, mob/user, params) + #define COMPONENT_NO_ATTACK 1 +#define COMSIG_ITEM_AFTERATTACK "item_afterattack" //from base of obj/item/afterattack(): (atom/target, mob/user, params) +#define COMSIG_ITEM_EQUIPPED "item_equip" //from base of obj/item/equipped(): (/mob/equipper, slot) +#define COMSIG_ITEM_DROPPED "item_drop" //from base of obj/item/dropped(): (mob/user) +#define COMSIG_ITEM_PICKUP "item_pickup" //from base of obj/item/pickup(): (/mob/taker) +#define COMSIG_ITEM_ATTACK_ZONE "item_attack_zone" //from base of mob/living/carbon/attacked_by(): (mob/living/carbon/target, mob/living/user, hit_zone) +#define COMSIG_ITEM_IMBUE_SOUL "item_imbue_soul" //return a truthy value to prevent ensouling, checked in /obj/effect/proc_holder/spell/targeted/lichdom/cast(): (mob/user) +#define COMSIG_ITEM_HIT_REACT "item_hit_react" //from base of obj/item/hit_reaction(): (list/args) + +// /obj/item/clothing signals +#define COMSIG_SHOES_STEP_ACTION "shoes_step_action" //from base of obj/item/clothing/shoes/proc/step_action(): () + +// /obj/item/implant signals +#define COMSIG_IMPLANT_ACTIVATED "implant_activated" //from base of /obj/item/implant/proc/activate(): () +#define COMSIG_IMPLANT_IMPLANTING "implant_implanting" //from base of /obj/item/implant/proc/implant(): (list/args) + #define COMPONENT_STOP_IMPLANTING 1 +#define COMSIG_IMPLANT_OTHER "implant_other" //called on already installed implants when a new one is being added in /obj/item/implant/proc/implant(): (list/args, obj/item/implant/new_implant) + //#define COMPONENT_STOP_IMPLANTING 1 //The name makes sense for both + #define COMPONENT_DELETE_NEW_IMPLANT 2 + #define COMPONENT_DELETE_OLD_IMPLANT 4 +#define COMSIG_IMPLANT_EXISTING_UPLINK "implant_uplink_exists" //called on implants being implanted into someone with an uplink implant: (datum/component/uplink) + //This uses all return values of COMSIG_IMPLANT_OTHER +#define COMSIG_IMPLANT_REMOVING "implant_removing" //from base of /obj/item/implant/proc/removed() (list/args) + +// /obj/item/pda signals +#define COMSIG_PDA_CHANGE_RINGTONE "pda_change_ringtone" //called on pda when the user changes the ringtone: (mob/living/user, new_ringtone) + #define COMPONENT_STOP_RINGTONE_CHANGE 1 + +// /obj/item/radio signals +#define COMSIG_RADIO_NEW_FREQUENCY "radio_new_frequency" //called from base of /obj/item/radio/proc/set_frequency(): (list/args) + +// /obj/item/pen signals +#define COMSIG_PEN_ROTATED "pen_rotated" //called after rotation in /obj/item/pen/attack_self(): (rotation, mob/living/carbon/user) + +// /obj/item/projectile signals (sent to the firer) +#define COMSIG_PROJECTILE_ON_HIT "projectile_on_hit" // from base of /obj/item/projectile/proc/on_hit(): (atom/movable/firer, atom/target, Angle) +#define COMSIG_PROJECTILE_BEFORE_FIRE "projectile_before_fire" // from base of /obj/item/projectile/proc/fire(): (obj/item/projectile, atom/original_target) + +// /mob/living/carbon/human signals +#define COMSIG_HUMAN_MELEE_UNARMED_ATTACK "human_melee_unarmed_attack" //from mob/living/carbon/human/UnarmedAttack(): (atom/target) +#define COMSIG_HUMAN_MELEE_UNARMED_ATTACKBY "human_melee_unarmed_attackby" //from mob/living/carbon/human/UnarmedAttack(): (mob/living/carbon/human/attacker) +#define COMSIG_HUMAN_DISARM_HIT "human_disarm_hit" //Hit by successful disarm attack (mob/living/carbon/human/attacker,zone_targeted) + +// /datum/species signals +#define COMSIG_SPECIES_GAIN "species_gain" //from datum/species/on_species_gain(): (datum/species/new_species, datum/species/old_species) +#define COMSIG_SPECIES_LOSS "species_loss" //from datum/species/on_species_loss(): (datum/species/lost_species) + +/*******Component Specific Signals*******/ +//Janitor +#define COMSIG_TURF_IS_WET "check_turf_wet" //(): Returns bitflags of wet values. +#define COMSIG_TURF_MAKE_DRY "make_turf_try" //(max_strength, immediate, duration_decrease = INFINITY): Returns bool. +#define COMSIG_COMPONENT_CLEAN_ACT "clean_act" //called on an object to clean it of cleanables. Usualy with soap: (num/strength) + +//Blood color +#define COMSIG_BLOOD_COLOR "blood_DNA_to_color" //RGB blood stuff +//Food +#define COMSIG_FOOD_EATEN "food_eaten" //from base of obj/item/reagent_containers/food/snacks/attack(): (mob/living/eater, mob/feeder) + +//Gibs +#define COMSIG_GIBS_STREAK "gibs_streak" // from base of /obj/effect/decal/cleanable/blood/gibs/streak(): (list/directions, list/diseases) + +//Mood +#define COMSIG_ADD_MOOD_EVENT "add_mood" //Called when you send a mood event from anywhere in the code. +#define COMSIG_CLEAR_MOOD_EVENT "clear_mood" //Called when you clear a mood event from anywhere in the code. +#define COMSIG_MODIFY_SANITY "modify_sanity" //Called when you want to increase or decrease sanity from anywhere in the code. + +//NTnet +#define COMSIG_COMPONENT_NTNET_RECEIVE "ntnet_receive" //called on an object by its NTNET connection component on receive. (sending_id(number), sending_netname(text), data(datum/netdata)) + +//Nanites +#define COMSIG_HAS_NANITES "has_nanites" //() returns TRUE if nanites are found +#define COMSIG_NANITE_GET_PROGRAMS "nanite_get_programs" //(list/nanite_programs) - makes the input list a copy the nanites' program list +#define COMSIG_NANITE_SET_VOLUME "nanite_set_volume" //(amount) Sets current nanite volume to the given amount +#define COMSIG_NANITE_ADJUST_VOLUME "nanite_adjust" //(amount) Adjusts nanite volume by the given amount +#define COMSIG_NANITE_SET_MAX_VOLUME "nanite_set_max_volume" //(amount) Sets maximum nanite volume to the given amount +#define COMSIG_NANITE_SET_CLOUD "nanite_set_cloud" //(amount(0-100)) Sets cloud ID to the given amount +#define COMSIG_NANITE_SET_SAFETY "nanite_set_safety" //(amount) Sets safety threshold to the given amount +#define COMSIG_NANITE_SET_REGEN "nanite_set_regen" //(amount) Sets regeneration rate to the given amount +#define COMSIG_NANITE_SIGNAL "nanite_signal" //(code(1-9999)) Called when sending a nanite signal to a mob. +#define COMSIG_NANITE_SCAN "nanite_scan" //(mob/user, full_scan) - sends to chat a scan of the nanites to the user, returns TRUE if nanites are detected +#define COMSIG_NANITE_UI_DATA "nanite_ui_data" //(list/data, scan_level) - adds nanite data to the given data list - made for ui_data procs +#define COMSIG_NANITE_ADD_PROGRAM "nanite_add_program" //(datum/nanite_program/new_program, datum/nanite_program/source_program) Called when adding a program to a nanite component + #define COMPONENT_PROGRAM_INSTALLED 1 //Installation successful + #define COMPONENT_PROGRAM_NOT_INSTALLED 2 //Installation failed, but there are still nanites +#define COMSIG_NANITE_SYNC "nanite_sync" //(datum/component/nanites, full_overwrite, copy_activation) Called to sync the target's nanites to a given nanite component + +// /datum/component/storage signals +#define COMSIG_CONTAINS_STORAGE "is_storage" //() - returns bool. +#define COMSIG_TRY_STORAGE_INSERT "storage_try_insert" //(obj/item/inserting, mob/user, silent, force) - returns bool +#define COMSIG_TRY_STORAGE_SHOW "storage_show_to" //(mob/show_to, force) - returns bool. +#define COMSIG_TRY_STORAGE_HIDE_FROM "storage_hide_from" //(mob/hide_from) - returns bool +#define COMSIG_TRY_STORAGE_HIDE_ALL "storage_hide_all" //returns bool +#define COMSIG_TRY_STORAGE_SET_LOCKSTATE "storage_lock_set_state" //(newstate) +#define COMSIG_IS_STORAGE_LOCKED "storage_get_lockstate" //() - returns bool. MUST CHECK IF STORAGE IS THERE FIRST! +#define COMSIG_TRY_STORAGE_TAKE_TYPE "storage_take_type" //(type, atom/destination, amount = INFINITY, check_adjacent, force, mob/user, list/inserted) - returns bool - type can be a list of types. +#define COMSIG_TRY_STORAGE_FILL_TYPE "storage_fill_type" //(type, amount = INFINITY, force = FALSE) //don't fuck this up. Force will ignore max_items, and amount is normally clamped to max_items. +#define COMSIG_TRY_STORAGE_TAKE "storage_take_obj" //(obj, new_loc, force = FALSE) - returns bool +#define COMSIG_TRY_STORAGE_QUICK_EMPTY "storage_quick_empty" //(loc) - returns bool - if loc is null it will dump at parent location. +#define COMSIG_TRY_STORAGE_RETURN_INVENTORY "storage_return_inventory" //(list/list_to_inject_results_into, recursively_search_inside_storages = TRUE) +#define COMSIG_TRY_STORAGE_CAN_INSERT "storage_can_equip" //(obj/item/insertion_candidate, mob/user, silent) - returns bool + +// /datum/action signals +#define COMSIG_ACTION_TRIGGER "action_trigger" //from base of datum/action/proc/Trigger(): (datum/action) + #define COMPONENT_ACTION_BLOCK_TRIGGER 1 + +/*******Non-Signal Component Related Defines*******/ + +//Redirection component init flags +#define REDIRECT_TRANSFER_WITH_TURF 1 + +//Arch +#define ARCH_PROB "probability" //Probability for each item +#define ARCH_MAXDROP "max_drop_amount" //each item's max drop amount + +//Ouch my toes! +#define CALTROP_BYPASS_SHOES 1 +#define CALTROP_IGNORE_WALKERS 2 + +//Xenobio hotkeys +#define COMSIG_XENO_SLIME_CLICK_CTRL "xeno_slime_click_ctrl" //from slime CtrlClickOn(): (/mob) +#define COMSIG_XENO_SLIME_CLICK_ALT "xeno_slime_click_alt" //from slime AltClickOn(): (/mob) +#define COMSIG_XENO_SLIME_CLICK_SHIFT "xeno_slime_click_shift" //from slime ShiftClickOn(): (/mob) +#define COMSIG_XENO_TURF_CLICK_SHIFT "xeno_turf_click_shift" //from turf ShiftClickOn(): (/mob) +#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt" //from turf AltClickOn(): (/mob) +#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" //from monkey CtrlClickOn(): (/mob) diff --git a/code/__DEFINES/configuration.dm b/code/__DEFINES/configuration.dm index c4ef8e6606..3034876e36 100644 --- a/code/__DEFINES/configuration.dm +++ b/code/__DEFINES/configuration.dm @@ -1,9 +1,9 @@ -//config files -#define CONFIG_GET(X) global.config.Get(/datum/config_entry/##X) -#define CONFIG_SET(X, Y) global.config.Set(/datum/config_entry/##X, ##Y) - -#define CONFIG_MAPS_FILE "maps.txt" - -//flags -#define CONFIG_ENTRY_LOCKED 1 //can't edit -#define CONFIG_ENTRY_HIDDEN 2 //can't see value +//config files +#define CONFIG_GET(X) global.config.Get(/datum/config_entry/##X) +#define CONFIG_SET(X, Y) global.config.Set(/datum/config_entry/##X, ##Y) + +#define CONFIG_MAPS_FILE "maps.txt" + +//flags +#define CONFIG_ENTRY_LOCKED 1 //can't edit +#define CONFIG_ENTRY_HIDDEN 2 //can't see value diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index 55962bf78c..839b690b37 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -1,93 +1,93 @@ -/* - These defines are specific to the atom/flags_1 bitmask -*/ -#define ALL (~0) //For convenience. -#define NONE 0 - -//for convenience -#define ENABLE_BITFIELD(variable, flag) (variable |= (flag)) -#define DISABLE_BITFIELD(variable, flag) (variable &= ~(flag)) -#define CHECK_BITFIELD(variable, flag) (variable & (flag)) -#define TOGGLE_BITFIELD(variable, flag) (variable ^= (flag)) - -#define CHECK_MULTIPLE_BITFIELDS(flagvar, flags) (((flagvar) & (flags)) == (flags)) - -GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768)) - -// for /datum/var/datum_flags -#define DF_USE_TAG (1<<0) -#define DF_VAR_EDITED (1<<1) -#define DF_ISPROCESSING (1<<2) - -//FLAGS BITMASK - -#define HEAR_1 (1<<3) // This flag is what recursive_hear_check() uses to determine wether to add an item to the hearer list or not. -#define CHECK_RICOCHET_1 (1<<4) // Projectiels will check ricochet on things impacted that have this. -#define CONDUCT_1 (1<<5) // conducts electricity (metal etc.) -#define NODECONSTRUCT_1 (1<<7) // For machines and structures that should not break into parts, eg, holodeck stuff -#define OVERLAY_QUEUED_1 (1<<8) // atom queued to SSoverlay -#define ON_BORDER_1 (1<<9) // item has priority to check when entering or leaving -#define PREVENT_CLICK_UNDER_1 (1<<11) //Prevent clicking things below it on the same turf eg. doors/ fulltile windows -#define HOLOGRAM_1 (1<<12) -#define TESLA_IGNORE_1 (1<<13) // TESLA_IGNORE grants immunity from being targeted by tesla-style electricity -#define INITIALIZED_1 (1<<14) //Whether /atom/Initialize() has already run for the object -#define ADMIN_SPAWNED_1 (1<<15) //was this spawned by an admin? used for stat tracking stuff. -#define PREVENT_CONTENTS_EXPLOSION_1 (1<<16) /// should not get harmed if this gets caught by an explosion? - -//turf-only flags -#define NOJAUNT_1 (1<<0) -#define UNUSED_RESERVATION_TURF_1 (1<<1) -#define CAN_BE_DIRTY_1 (1<<2) // If a turf can be made dirty at roundstart. This is also used in areas. -#define NO_LAVA_GEN_1 (1<<6) //Blocks lava rivers being generated on the turf -#define NO_RUINS_1 (1<<10) //Blocks ruins spawning on the turf - -/* - These defines are used specifically with the atom/pass_flags bitmask - the atom/checkpass() proc uses them (tables will call movable atom checkpass(PASSTABLE) for example) -*/ -//flags for pass_flags -#define PASSTABLE (1<<0) -#define PASSGLASS (1<<1) -#define PASSGRILLE (1<<2) -#define PASSBLOB (1<<3) -#define PASSMOB (1<<4) -#define PASSCLOSEDTURF (1<<5) -#define LETPASSTHROW (1<<6) - - -//Movement Types -#define GROUND (1<<0) -#define FLYING (1<<1) -#define VENTCRAWLING (1<<2) -#define FLOATING (1<<3) - -//Fire and Acid stuff, for resistance_flags -#define LAVA_PROOF (1<<0) -#define FIRE_PROOF (1<<1) //100% immune to fire damage (but not necessarily to lava or heat) -#define FLAMMABLE (1<<2) -#define ON_FIRE (1<<3) -#define UNACIDABLE (1<<4) //acid can't even appear on it, let alone melt it. -#define ACID_PROOF (1<<5) //acid stuck on it doesn't melt it. -#define INDESTRUCTIBLE (1<<6) //doesn't take damage -#define FREEZE_PROOF (1<<7) //can't be frozen -#define GOLIATH_RESISTANCE (1<<8) //CIT CHANGE -#define GOLIATH_WEAKNESS (1<<9) //CIT CHANGE - -//tesla_zap -#define TESLA_MACHINE_EXPLOSIVE (1<<0) -#define TESLA_ALLOW_DUPLICATES (1<<1) -#define TESLA_OBJ_DAMAGE (1<<2) -#define TESLA_MOB_DAMAGE (1<<3) -#define TESLA_MOB_STUN (1<<4) - -#define TESLA_DEFAULT_FLAGS ALL -#define TESLA_FUSION_FLAGS TESLA_OBJ_DAMAGE | TESLA_MOB_DAMAGE | TESLA_MOB_STUN - -//EMP protection -#define EMP_PROTECT_SELF (1<<0) -#define EMP_PROTECT_CONTENTS (1<<1) -#define EMP_PROTECT_WIRES (1<<2) - -// radiation -#define RAD_PROTECT_CONTENTS (1<<0) -#define RAD_NO_CONTAMINATE (1<<1) +/* + These defines are specific to the atom/flags_1 bitmask +*/ +#define ALL (~0) //For convenience. +#define NONE 0 + +//for convenience +#define ENABLE_BITFIELD(variable, flag) (variable |= (flag)) +#define DISABLE_BITFIELD(variable, flag) (variable &= ~(flag)) +#define CHECK_BITFIELD(variable, flag) (variable & (flag)) +#define TOGGLE_BITFIELD(variable, flag) (variable ^= (flag)) + +#define CHECK_MULTIPLE_BITFIELDS(flagvar, flags) (((flagvar) & (flags)) == (flags)) + +GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768)) + +// for /datum/var/datum_flags +#define DF_USE_TAG (1<<0) +#define DF_VAR_EDITED (1<<1) +#define DF_ISPROCESSING (1<<2) + +//FLAGS BITMASK + +#define HEAR_1 (1<<3) // This flag is what recursive_hear_check() uses to determine wether to add an item to the hearer list or not. +#define CHECK_RICOCHET_1 (1<<4) // Projectiels will check ricochet on things impacted that have this. +#define CONDUCT_1 (1<<5) // conducts electricity (metal etc.) +#define NODECONSTRUCT_1 (1<<7) // For machines and structures that should not break into parts, eg, holodeck stuff +#define OVERLAY_QUEUED_1 (1<<8) // atom queued to SSoverlay +#define ON_BORDER_1 (1<<9) // item has priority to check when entering or leaving +#define PREVENT_CLICK_UNDER_1 (1<<11) //Prevent clicking things below it on the same turf eg. doors/ fulltile windows +#define HOLOGRAM_1 (1<<12) +#define TESLA_IGNORE_1 (1<<13) // TESLA_IGNORE grants immunity from being targeted by tesla-style electricity +#define INITIALIZED_1 (1<<14) //Whether /atom/Initialize() has already run for the object +#define ADMIN_SPAWNED_1 (1<<15) //was this spawned by an admin? used for stat tracking stuff. +#define PREVENT_CONTENTS_EXPLOSION_1 (1<<16) /// should not get harmed if this gets caught by an explosion? + +//turf-only flags +#define NOJAUNT_1 (1<<0) +#define UNUSED_RESERVATION_TURF_1 (1<<1) +#define CAN_BE_DIRTY_1 (1<<2) // If a turf can be made dirty at roundstart. This is also used in areas. +#define NO_LAVA_GEN_1 (1<<6) //Blocks lava rivers being generated on the turf +#define NO_RUINS_1 (1<<10) //Blocks ruins spawning on the turf + +/* + These defines are used specifically with the atom/pass_flags bitmask + the atom/checkpass() proc uses them (tables will call movable atom checkpass(PASSTABLE) for example) +*/ +//flags for pass_flags +#define PASSTABLE (1<<0) +#define PASSGLASS (1<<1) +#define PASSGRILLE (1<<2) +#define PASSBLOB (1<<3) +#define PASSMOB (1<<4) +#define PASSCLOSEDTURF (1<<5) +#define LETPASSTHROW (1<<6) + + +//Movement Types +#define GROUND (1<<0) +#define FLYING (1<<1) +#define VENTCRAWLING (1<<2) +#define FLOATING (1<<3) + +//Fire and Acid stuff, for resistance_flags +#define LAVA_PROOF (1<<0) +#define FIRE_PROOF (1<<1) //100% immune to fire damage (but not necessarily to lava or heat) +#define FLAMMABLE (1<<2) +#define ON_FIRE (1<<3) +#define UNACIDABLE (1<<4) //acid can't even appear on it, let alone melt it. +#define ACID_PROOF (1<<5) //acid stuck on it doesn't melt it. +#define INDESTRUCTIBLE (1<<6) //doesn't take damage +#define FREEZE_PROOF (1<<7) //can't be frozen +#define GOLIATH_RESISTANCE (1<<8) //CIT CHANGE +#define GOLIATH_WEAKNESS (1<<9) //CIT CHANGE + +//tesla_zap +#define TESLA_MACHINE_EXPLOSIVE (1<<0) +#define TESLA_ALLOW_DUPLICATES (1<<1) +#define TESLA_OBJ_DAMAGE (1<<2) +#define TESLA_MOB_DAMAGE (1<<3) +#define TESLA_MOB_STUN (1<<4) + +#define TESLA_DEFAULT_FLAGS ALL +#define TESLA_FUSION_FLAGS TESLA_OBJ_DAMAGE | TESLA_MOB_DAMAGE | TESLA_MOB_STUN + +//EMP protection +#define EMP_PROTECT_SELF (1<<0) +#define EMP_PROTECT_CONTENTS (1<<1) +#define EMP_PROTECT_WIRES (1<<2) + +// radiation +#define RAD_PROTECT_CONTENTS (1<<0) +#define RAD_NO_CONTAMINATE (1<<1) diff --git a/code/__DEFINES/jobs.dm b/code/__DEFINES/jobs.dm index ed45da9923..9bc8127c3d 100644 --- a/code/__DEFINES/jobs.dm +++ b/code/__DEFINES/jobs.dm @@ -1,89 +1,89 @@ - -#define ENGSEC (1<<0) - -#define CAPTAIN (1<<0) -#define HOS (1<<1) -#define WARDEN (1<<2) -#define DETECTIVE (1<<3) -#define OFFICER (1<<4) -#define CHIEF (1<<5) -#define ENGINEER (1<<6) -#define ATMOSTECH (1<<7) -#define ROBOTICIST (1<<8) -#define AI_JF (1<<9) -#define CYBORG (1<<10) - - -#define MEDSCI (1<<1) - -#define RD_JF (1<<0) -#define SCIENTIST (1<<1) -#define CHEMIST (1<<2) -#define CMO_JF (1<<3) -#define DOCTOR (1<<4) -#define GENETICIST (1<<5) -#define VIROLOGIST (1<<6) - - -#define CIVILIAN (1<<2) - -#define HOP (1<<0) -#define BARTENDER (1<<1) -#define BOTANIST (1<<2) -#define COOK (1<<3) -#define JANITOR (1<<4) -#define CURATOR (1<<5) -#define QUARTERMASTER (1<<6) -#define CARGOTECH (1<<7) -#define MINER (1<<8) -#define LAWYER (1<<9) -#define CHAPLAIN (1<<10) -#define CLOWN (1<<11) -#define MIME (1<<12) -#define ASSISTANT (1<<13) - -#define JOB_AVAILABLE 0 -#define JOB_UNAVAILABLE_GENERIC 1 -#define JOB_UNAVAILABLE_BANNED 2 -#define JOB_UNAVAILABLE_PLAYTIME 3 -#define JOB_UNAVAILABLE_ACCOUNTAGE 4 -#define JOB_UNAVAILABLE_SLOTFULL 5 -#define JOB_UNAVAILABLE_SPECIESLOCK 6 - -#define DEFAULT_RELIGION "Christianity" -#define DEFAULT_DEITY "Space Jesus" - -#define JOB_DISPLAY_ORDER_DEFAULT 0 - -#define JOB_DISPLAY_ORDER_ASSISTANT 1 -#define JOB_DISPLAY_ORDER_CAPTAIN 2 -#define JOB_DISPLAY_ORDER_HEAD_OF_PERSONNEL 3 -#define JOB_DISPLAY_ORDER_BARTENDER 4 -#define JOB_DISPLAY_ORDER_COOK 5 -#define JOB_DISPLAY_ORDER_BOTANIST 6 -#define JOB_DISPLAY_ORDER_JANITOR 7 -#define JOB_DISPLAY_ORDER_CLOWN 8 -#define JOB_DISPLAY_ORDER_MIME 9 -#define JOB_DISPLAY_ORDER_CURATOR 10 -#define JOB_DISPLAY_ORDER_LAWYER 11 -#define JOB_DISPLAY_ORDER_CHAPLAIN 12 -#define JOB_DISPLAY_ORDER_QUARTERMASTER 13 -#define JOB_DISPLAY_ORDER_CARGO_TECHNICIAN 14 -#define JOB_DISPLAY_ORDER_SHAFT_MINER 15 -#define JOB_DISPLAY_ORDER_CHIEF_ENGINEER 16 -#define JOB_DISPLAY_ORDER_STATION_ENGINEER 17 -#define JOB_DISPLAY_ORDER_ATMOSPHERIC_TECHNICIAN 18 -#define JOB_DISPLAY_ORDER_CHIEF_MEDICAL_OFFICER 19 -#define JOB_DISPLAY_ORDER_MEDICAL_DOCTOR 20 -#define JOB_DISPLAY_ORDER_CHEMIST 21 -#define JOB_DISPLAY_ORDER_GENETICIST 22 -#define JOB_DISPLAY_ORDER_VIROLOGIST 23 -#define JOB_DISPLAY_ORDER_RESEARCH_DIRECTOR 24 -#define JOB_DISPLAY_ORDER_SCIENTIST 25 -#define JOB_DISPLAY_ORDER_ROBOTICIST 26 -#define JOB_DISPLAY_ORDER_HEAD_OF_SECURITY 27 -#define JOB_DISPLAY_ORDER_WARDEN 28 -#define JOB_DISPLAY_ORDER_DETECTIVE 29 -#define JOB_DISPLAY_ORDER_SECURITY_OFFICER 30 -#define JOB_DISPLAY_ORDER_AI 31 -#define JOB_DISPLAY_ORDER_CYBORG 32 + +#define ENGSEC (1<<0) + +#define CAPTAIN (1<<0) +#define HOS (1<<1) +#define WARDEN (1<<2) +#define DETECTIVE (1<<3) +#define OFFICER (1<<4) +#define CHIEF (1<<5) +#define ENGINEER (1<<6) +#define ATMOSTECH (1<<7) +#define ROBOTICIST (1<<8) +#define AI_JF (1<<9) +#define CYBORG (1<<10) + + +#define MEDSCI (1<<1) + +#define RD_JF (1<<0) +#define SCIENTIST (1<<1) +#define CHEMIST (1<<2) +#define CMO_JF (1<<3) +#define DOCTOR (1<<4) +#define GENETICIST (1<<5) +#define VIROLOGIST (1<<6) + + +#define CIVILIAN (1<<2) + +#define HOP (1<<0) +#define BARTENDER (1<<1) +#define BOTANIST (1<<2) +#define COOK (1<<3) +#define JANITOR (1<<4) +#define CURATOR (1<<5) +#define QUARTERMASTER (1<<6) +#define CARGOTECH (1<<7) +#define MINER (1<<8) +#define LAWYER (1<<9) +#define CHAPLAIN (1<<10) +#define CLOWN (1<<11) +#define MIME (1<<12) +#define ASSISTANT (1<<13) + +#define JOB_AVAILABLE 0 +#define JOB_UNAVAILABLE_GENERIC 1 +#define JOB_UNAVAILABLE_BANNED 2 +#define JOB_UNAVAILABLE_PLAYTIME 3 +#define JOB_UNAVAILABLE_ACCOUNTAGE 4 +#define JOB_UNAVAILABLE_SLOTFULL 5 +#define JOB_UNAVAILABLE_SPECIESLOCK 6 + +#define DEFAULT_RELIGION "Christianity" +#define DEFAULT_DEITY "Space Jesus" + +#define JOB_DISPLAY_ORDER_DEFAULT 0 + +#define JOB_DISPLAY_ORDER_ASSISTANT 1 +#define JOB_DISPLAY_ORDER_CAPTAIN 2 +#define JOB_DISPLAY_ORDER_HEAD_OF_PERSONNEL 3 +#define JOB_DISPLAY_ORDER_BARTENDER 4 +#define JOB_DISPLAY_ORDER_COOK 5 +#define JOB_DISPLAY_ORDER_BOTANIST 6 +#define JOB_DISPLAY_ORDER_JANITOR 7 +#define JOB_DISPLAY_ORDER_CLOWN 8 +#define JOB_DISPLAY_ORDER_MIME 9 +#define JOB_DISPLAY_ORDER_CURATOR 10 +#define JOB_DISPLAY_ORDER_LAWYER 11 +#define JOB_DISPLAY_ORDER_CHAPLAIN 12 +#define JOB_DISPLAY_ORDER_QUARTERMASTER 13 +#define JOB_DISPLAY_ORDER_CARGO_TECHNICIAN 14 +#define JOB_DISPLAY_ORDER_SHAFT_MINER 15 +#define JOB_DISPLAY_ORDER_CHIEF_ENGINEER 16 +#define JOB_DISPLAY_ORDER_STATION_ENGINEER 17 +#define JOB_DISPLAY_ORDER_ATMOSPHERIC_TECHNICIAN 18 +#define JOB_DISPLAY_ORDER_CHIEF_MEDICAL_OFFICER 19 +#define JOB_DISPLAY_ORDER_MEDICAL_DOCTOR 20 +#define JOB_DISPLAY_ORDER_CHEMIST 21 +#define JOB_DISPLAY_ORDER_GENETICIST 22 +#define JOB_DISPLAY_ORDER_VIROLOGIST 23 +#define JOB_DISPLAY_ORDER_RESEARCH_DIRECTOR 24 +#define JOB_DISPLAY_ORDER_SCIENTIST 25 +#define JOB_DISPLAY_ORDER_ROBOTICIST 26 +#define JOB_DISPLAY_ORDER_HEAD_OF_SECURITY 27 +#define JOB_DISPLAY_ORDER_WARDEN 28 +#define JOB_DISPLAY_ORDER_DETECTIVE 29 +#define JOB_DISPLAY_ORDER_SECURITY_OFFICER 30 +#define JOB_DISPLAY_ORDER_AI 31 +#define JOB_DISPLAY_ORDER_CYBORG 32 diff --git a/code/__DEFINES/machines.dm b/code/__DEFINES/machines.dm index db13c21c44..8ae4e5c167 100644 --- a/code/__DEFINES/machines.dm +++ b/code/__DEFINES/machines.dm @@ -1,107 +1,107 @@ -// channel numbers for power -#define EQUIP 1 -#define LIGHT 2 -#define ENVIRON 3 -#define TOTAL 4 //for total power used only -#define STATIC_EQUIP 5 -#define STATIC_LIGHT 6 -#define STATIC_ENVIRON 7 - -//Power use -#define NO_POWER_USE 0 -#define IDLE_POWER_USE 1 -#define ACTIVE_POWER_USE 2 - - -//bitflags for door switches. -#define OPEN (1<<0) -#define IDSCAN (1<<1) -#define BOLTS (1<<2) -#define SHOCK (1<<3) -#define SAFE (1<<4) - -//used in design to specify which machine can build it -#define IMPRINTER (1<<0) //For circuits. Uses glass/chemicals. -#define PROTOLATHE (1<<1) //New stuff. Uses glass/metal/chemicals -#define AUTOLATHE (1<<2) //Uses glass/metal only. -#define CRAFTLATHE (1<<3) //Uses fuck if I know. For use eventually. -#define MECHFAB (1<<4) //Remember, objects utilising this flag should have construction_time and construction_cost vars. -#define BIOGENERATOR (1<<5) //Uses biomass -#define LIMBGROWER (1<<6) //Uses synthetic flesh -#define SMELTER (1<<7) //uses various minerals -#define AUTOYLATHE (1<<8) // CITADEL ADD -#define NANITE_COMPILER (1<<9) //Prints nanite disks -#define AUTOBOTTLER (1<<10) //Uses booze, for printing -//Note: More then one of these can be added to a design but imprinter and lathe designs are incompatable. - -//Modular computer/NTNet defines - -//Modular computer part defines -#define MC_CPU "CPU" -#define MC_HDD "HDD" -#define MC_SDD "SDD" -#define MC_CARD "CARD" -#define MC_NET "NET" -#define MC_PRINT "PRINT" -#define MC_CELL "CELL" -#define MC_CHARGE "CHARGE" -#define MC_AI "AI" - -//NTNet stuff, for modular computers - // NTNet module-configuration values. Do not change these. If you need to add another use larger number (5..6..7 etc) -#define NTNET_SOFTWAREDOWNLOAD 1 // Downloads of software from NTNet -#define NTNET_PEERTOPEER 2 // P2P transfers of files between devices -#define NTNET_COMMUNICATION 3 // Communication (messaging) -#define NTNET_SYSTEMCONTROL 4 // Control of various systems, RCon, air alarm control, etc. - -//NTNet transfer speeds, used when downloading/uploading a file/program. -#define NTNETSPEED_LOWSIGNAL 0.5 // GQ/s transfer speed when the device is wirelessly connected and on Low signal -#define NTNETSPEED_HIGHSIGNAL 1 // GQ/s transfer speed when the device is wirelessly connected and on High signal -#define NTNETSPEED_ETHERNET 2 // GQ/s transfer speed when the device is using wired connection - -//Caps for NTNet logging. Less than 10 would make logging useless anyway, more than 500 may make the log browser too laggy. Defaults to 100 unless user changes it. -#define MAX_NTNET_LOGS 300 -#define MIN_NTNET_LOGS 10 - -//Program bitflags -#define PROGRAM_ALL (~0) -#define PROGRAM_CONSOLE (1<<0) -#define PROGRAM_LAPTOP (1<<1) -#define PROGRAM_TABLET (1<<2) -//Program states -#define PROGRAM_STATE_KILLED 0 -#define PROGRAM_STATE_BACKGROUND 1 -#define PROGRAM_STATE_ACTIVE 2 - -#define FIREDOOR_OPEN 1 -#define FIREDOOR_CLOSED 2 - - - -// These are used by supermatter and supermatter monitor program, mostly for UI updating purposes. Higher should always be worse! -#define SUPERMATTER_ERROR -1 // Unknown status, shouldn't happen but just in case. -#define SUPERMATTER_INACTIVE 0 // No or minimal energy -#define SUPERMATTER_NORMAL 1 // Normal operation -#define SUPERMATTER_NOTIFY 2 // Ambient temp > 80% of CRITICAL_TEMPERATURE -#define SUPERMATTER_WARNING 3 // Ambient temp > CRITICAL_TEMPERATURE OR integrity damaged -#define SUPERMATTER_DANGER 4 // Integrity < 50% -#define SUPERMATTER_EMERGENCY 5 // Integrity < 25% -#define SUPERMATTER_DELAMINATING 6 // Pretty obvious. - -//Nuclear bomb stuff -#define NUKESTATE_INTACT 5 -#define NUKESTATE_UNSCREWED 4 -#define NUKESTATE_PANEL_REMOVED 3 -#define NUKESTATE_WELDED 2 -#define NUKESTATE_CORE_EXPOSED 1 -#define NUKESTATE_CORE_REMOVED 0 - -#define NUKE_OFF_LOCKED 0 -#define NUKE_OFF_UNLOCKED 1 -#define NUKE_ON_TIMING 2 -#define NUKE_ON_EXPLODING 3 - - -//these flags are used to tell the DNA modifier if a plant gene cannot be extracted or modified. -#define PLANT_GENE_REMOVABLE (1<<0) +// channel numbers for power +#define EQUIP 1 +#define LIGHT 2 +#define ENVIRON 3 +#define TOTAL 4 //for total power used only +#define STATIC_EQUIP 5 +#define STATIC_LIGHT 6 +#define STATIC_ENVIRON 7 + +//Power use +#define NO_POWER_USE 0 +#define IDLE_POWER_USE 1 +#define ACTIVE_POWER_USE 2 + + +//bitflags for door switches. +#define OPEN (1<<0) +#define IDSCAN (1<<1) +#define BOLTS (1<<2) +#define SHOCK (1<<3) +#define SAFE (1<<4) + +//used in design to specify which machine can build it +#define IMPRINTER (1<<0) //For circuits. Uses glass/chemicals. +#define PROTOLATHE (1<<1) //New stuff. Uses glass/metal/chemicals +#define AUTOLATHE (1<<2) //Uses glass/metal only. +#define CRAFTLATHE (1<<3) //Uses fuck if I know. For use eventually. +#define MECHFAB (1<<4) //Remember, objects utilising this flag should have construction_time and construction_cost vars. +#define BIOGENERATOR (1<<5) //Uses biomass +#define LIMBGROWER (1<<6) //Uses synthetic flesh +#define SMELTER (1<<7) //uses various minerals +#define AUTOYLATHE (1<<8) // CITADEL ADD +#define NANITE_COMPILER (1<<9) //Prints nanite disks +#define AUTOBOTTLER (1<<10) //Uses booze, for printing +//Note: More then one of these can be added to a design but imprinter and lathe designs are incompatable. + +//Modular computer/NTNet defines + +//Modular computer part defines +#define MC_CPU "CPU" +#define MC_HDD "HDD" +#define MC_SDD "SDD" +#define MC_CARD "CARD" +#define MC_NET "NET" +#define MC_PRINT "PRINT" +#define MC_CELL "CELL" +#define MC_CHARGE "CHARGE" +#define MC_AI "AI" + +//NTNet stuff, for modular computers + // NTNet module-configuration values. Do not change these. If you need to add another use larger number (5..6..7 etc) +#define NTNET_SOFTWAREDOWNLOAD 1 // Downloads of software from NTNet +#define NTNET_PEERTOPEER 2 // P2P transfers of files between devices +#define NTNET_COMMUNICATION 3 // Communication (messaging) +#define NTNET_SYSTEMCONTROL 4 // Control of various systems, RCon, air alarm control, etc. + +//NTNet transfer speeds, used when downloading/uploading a file/program. +#define NTNETSPEED_LOWSIGNAL 0.5 // GQ/s transfer speed when the device is wirelessly connected and on Low signal +#define NTNETSPEED_HIGHSIGNAL 1 // GQ/s transfer speed when the device is wirelessly connected and on High signal +#define NTNETSPEED_ETHERNET 2 // GQ/s transfer speed when the device is using wired connection + +//Caps for NTNet logging. Less than 10 would make logging useless anyway, more than 500 may make the log browser too laggy. Defaults to 100 unless user changes it. +#define MAX_NTNET_LOGS 300 +#define MIN_NTNET_LOGS 10 + +//Program bitflags +#define PROGRAM_ALL (~0) +#define PROGRAM_CONSOLE (1<<0) +#define PROGRAM_LAPTOP (1<<1) +#define PROGRAM_TABLET (1<<2) +//Program states +#define PROGRAM_STATE_KILLED 0 +#define PROGRAM_STATE_BACKGROUND 1 +#define PROGRAM_STATE_ACTIVE 2 + +#define FIREDOOR_OPEN 1 +#define FIREDOOR_CLOSED 2 + + + +// These are used by supermatter and supermatter monitor program, mostly for UI updating purposes. Higher should always be worse! +#define SUPERMATTER_ERROR -1 // Unknown status, shouldn't happen but just in case. +#define SUPERMATTER_INACTIVE 0 // No or minimal energy +#define SUPERMATTER_NORMAL 1 // Normal operation +#define SUPERMATTER_NOTIFY 2 // Ambient temp > 80% of CRITICAL_TEMPERATURE +#define SUPERMATTER_WARNING 3 // Ambient temp > CRITICAL_TEMPERATURE OR integrity damaged +#define SUPERMATTER_DANGER 4 // Integrity < 50% +#define SUPERMATTER_EMERGENCY 5 // Integrity < 25% +#define SUPERMATTER_DELAMINATING 6 // Pretty obvious. + +//Nuclear bomb stuff +#define NUKESTATE_INTACT 5 +#define NUKESTATE_UNSCREWED 4 +#define NUKESTATE_PANEL_REMOVED 3 +#define NUKESTATE_WELDED 2 +#define NUKESTATE_CORE_EXPOSED 1 +#define NUKESTATE_CORE_REMOVED 0 + +#define NUKE_OFF_LOCKED 0 +#define NUKE_OFF_UNLOCKED 1 +#define NUKE_ON_TIMING 2 +#define NUKE_ON_EXPLODING 3 + + +//these flags are used to tell the DNA modifier if a plant gene cannot be extracted or modified. +#define PLANT_GENE_REMOVABLE (1<<0) #define PLANT_GENE_EXTRACTABLE (1<<1) \ No newline at end of file diff --git a/code/__DEFINES/medal.dm b/code/__DEFINES/medal.dm index 2a545d9c64..89fc098e3d 100644 --- a/code/__DEFINES/medal.dm +++ b/code/__DEFINES/medal.dm @@ -1,29 +1,29 @@ -// Medal names -#define BOSS_KILL_MEDAL "Killer" -#define ALL_KILL_MEDAL "Exterminator" //Killing all of x type -#define BOSS_KILL_MEDAL_CRUSHER "Crusher" - -//Defines for boss medals -#define BOSS_MEDAL_MINER "Blood-drunk Miner" -#define BOSS_MEDAL_BUBBLEGUM "Bubblegum" -#define BOSS_MEDAL_COLOSSUS "Colossus" -#define BOSS_MEDAL_DRAKE "Drake" -#define BOSS_MEDAL_HIEROPHANT "Hierophant" -#define BOSS_MEDAL_LEGION "Legion" -#define BOSS_MEDAL_TENDRIL "Tendril" -#define BOSS_MEDAL_SWARMERS "Swarmer Beacon" - -// Score names -#define HIEROPHANT_SCORE "Hierophants Killed" -#define BOSS_SCORE "Bosses Killed" -#define BUBBLEGUM_SCORE "Bubblegum Killed" -#define COLOSSUS_SCORE "Colossus Killed" -#define DRAKE_SCORE "Drakes Killed" -#define LEGION_SCORE "Legion Killed" -#define SWARMER_BEACON_SCORE "Swarmer Beacons Killed" -#define TENDRIL_CLEAR_SCORE "Tendrils Killed" - -//Misc medals -#define MEDAL_METEOR "Your Life Before Your Eyes" -#define MEDAL_PULSE "Jackpot" +// Medal names +#define BOSS_KILL_MEDAL "Killer" +#define ALL_KILL_MEDAL "Exterminator" //Killing all of x type +#define BOSS_KILL_MEDAL_CRUSHER "Crusher" + +//Defines for boss medals +#define BOSS_MEDAL_MINER "Blood-drunk Miner" +#define BOSS_MEDAL_BUBBLEGUM "Bubblegum" +#define BOSS_MEDAL_COLOSSUS "Colossus" +#define BOSS_MEDAL_DRAKE "Drake" +#define BOSS_MEDAL_HIEROPHANT "Hierophant" +#define BOSS_MEDAL_LEGION "Legion" +#define BOSS_MEDAL_TENDRIL "Tendril" +#define BOSS_MEDAL_SWARMERS "Swarmer Beacon" + +// Score names +#define HIEROPHANT_SCORE "Hierophants Killed" +#define BOSS_SCORE "Bosses Killed" +#define BUBBLEGUM_SCORE "Bubblegum Killed" +#define COLOSSUS_SCORE "Colossus Killed" +#define DRAKE_SCORE "Drakes Killed" +#define LEGION_SCORE "Legion Killed" +#define SWARMER_BEACON_SCORE "Swarmer Beacons Killed" +#define TENDRIL_CLEAR_SCORE "Tendrils Killed" + +//Misc medals +#define MEDAL_METEOR "Your Life Before Your Eyes" +#define MEDAL_PULSE "Jackpot" #define MEDAL_TIMEWASTE "Overextended The Joke" \ No newline at end of file diff --git a/code/__DEFINES/networks.dm b/code/__DEFINES/networks.dm index 09b9e4cadf..115c165349 100644 --- a/code/__DEFINES/networks.dm +++ b/code/__DEFINES/networks.dm @@ -1,3 +1,3 @@ -#define HID_RESTRICTED_END 101 //the first nonrestricted ID, automatically assigned on connection creation. - -#define NETWORK_BROADCAST_ID "ALL" +#define HID_RESTRICTED_END 101 //the first nonrestricted ID, automatically assigned on connection creation. + +#define NETWORK_BROADCAST_ID "ALL" diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index 7a284ff1a0..06926317ee 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -1,84 +1,84 @@ - -//Preference toggles -#define SOUND_ADMINHELP (1<<0) -#define SOUND_MIDI (1<<1) -#define SOUND_AMBIENCE (1<<2) -#define SOUND_LOBBY (1<<3) -#define MEMBER_PUBLIC (1<<4) -#define INTENT_STYLE (1<<5) -#define MIDROUND_ANTAG (1<<6) -#define SOUND_INSTRUMENTS (1<<7) -#define SOUND_SHIP_AMBIENCE (1<<8) -#define SOUND_PRAYERS (1<<9) -#define ANNOUNCE_LOGIN (1<<10) -#define SOUND_ANNOUNCEMENTS (1<<11) -#define DISABLE_DEATHRATTLE (1<<12) -#define DISABLE_ARRIVALRATTLE (1<<13) -#define COMBOHUD_LIGHTING (1<<14) - -#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS) - -//Chat toggles -#define CHAT_OOC (1<<0) -#define CHAT_DEAD (1<<1) -#define CHAT_GHOSTEARS (1<<2) -#define CHAT_GHOSTSIGHT (1<<3) -#define CHAT_PRAYER (1<<4) -#define CHAT_RADIO (1<<5) -#define CHAT_PULLR (1<<6) -#define CHAT_GHOSTWHISPER (1<<7) -#define CHAT_GHOSTPDA (1<<8) -#define CHAT_GHOSTRADIO (1<<9) -#define CHAT_LOOC (1<<10) - -#define TOGGLES_DEFAULT_CHAT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_PULLR|CHAT_GHOSTWHISPER|CHAT_GHOSTPDA|CHAT_GHOSTRADIO|CHAT_LOOC) - -#define PARALLAX_INSANE -1 //for show offs -#define PARALLAX_HIGH 0 //default. -#define PARALLAX_MED 1 -#define PARALLAX_LOW 2 -#define PARALLAX_DISABLE 3 //this option must be the highest number - -#define PARALLAX_DELAY_DEFAULT world.tick_lag -#define PARALLAX_DELAY_MED 1 -#define PARALLAX_DELAY_LOW 2 - -#define SEC_DEPT_NONE "None" -#define SEC_DEPT_RANDOM "Random" -#define SEC_DEPT_ENGINEERING "Engineering" -#define SEC_DEPT_MEDICAL "Medical" -#define SEC_DEPT_SCIENCE "Science" -#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" -#define EXP_TYPE_ADMIN "Admin" - -//Flags in the players table in the db -#define DB_FLAG_EXEMPT 1 - -#define DEFAULT_CYBORG_NAME "Default Cyborg Name" - -//Job preferences levels -#define JP_LOW 1 -#define JP_MEDIUM 2 -#define JP_HIGH 3 - -//Chaos levels for dynamic voting -#define CHAOS_NONE "None (Extended)" -#define CHAOS_LOW "Low" -#define CHAOS_MED "Medium" -#define CHAOS_HIGH "High" -#define CHAOS_MAX "Maximum" + +//Preference toggles +#define SOUND_ADMINHELP (1<<0) +#define SOUND_MIDI (1<<1) +#define SOUND_AMBIENCE (1<<2) +#define SOUND_LOBBY (1<<3) +#define MEMBER_PUBLIC (1<<4) +#define INTENT_STYLE (1<<5) +#define MIDROUND_ANTAG (1<<6) +#define SOUND_INSTRUMENTS (1<<7) +#define SOUND_SHIP_AMBIENCE (1<<8) +#define SOUND_PRAYERS (1<<9) +#define ANNOUNCE_LOGIN (1<<10) +#define SOUND_ANNOUNCEMENTS (1<<11) +#define DISABLE_DEATHRATTLE (1<<12) +#define DISABLE_ARRIVALRATTLE (1<<13) +#define COMBOHUD_LIGHTING (1<<14) + +#define TOGGLES_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|MEMBER_PUBLIC|INTENT_STYLE|MIDROUND_ANTAG|SOUND_INSTRUMENTS|SOUND_SHIP_AMBIENCE|SOUND_PRAYERS|SOUND_ANNOUNCEMENTS) + +//Chat toggles +#define CHAT_OOC (1<<0) +#define CHAT_DEAD (1<<1) +#define CHAT_GHOSTEARS (1<<2) +#define CHAT_GHOSTSIGHT (1<<3) +#define CHAT_PRAYER (1<<4) +#define CHAT_RADIO (1<<5) +#define CHAT_PULLR (1<<6) +#define CHAT_GHOSTWHISPER (1<<7) +#define CHAT_GHOSTPDA (1<<8) +#define CHAT_GHOSTRADIO (1<<9) +#define CHAT_LOOC (1<<10) + +#define TOGGLES_DEFAULT_CHAT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_PULLR|CHAT_GHOSTWHISPER|CHAT_GHOSTPDA|CHAT_GHOSTRADIO|CHAT_LOOC) + +#define PARALLAX_INSANE -1 //for show offs +#define PARALLAX_HIGH 0 //default. +#define PARALLAX_MED 1 +#define PARALLAX_LOW 2 +#define PARALLAX_DISABLE 3 //this option must be the highest number + +#define PARALLAX_DELAY_DEFAULT world.tick_lag +#define PARALLAX_DELAY_MED 1 +#define PARALLAX_DELAY_LOW 2 + +#define SEC_DEPT_NONE "None" +#define SEC_DEPT_RANDOM "Random" +#define SEC_DEPT_ENGINEERING "Engineering" +#define SEC_DEPT_MEDICAL "Medical" +#define SEC_DEPT_SCIENCE "Science" +#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" +#define EXP_TYPE_ADMIN "Admin" + +//Flags in the players table in the db +#define DB_FLAG_EXEMPT 1 + +#define DEFAULT_CYBORG_NAME "Default Cyborg Name" + +//Job preferences levels +#define JP_LOW 1 +#define JP_MEDIUM 2 +#define JP_HIGH 3 + +//Chaos levels for dynamic voting +#define CHAOS_NONE "None (Extended)" +#define CHAOS_LOW "Low" +#define CHAOS_MED "Medium" +#define CHAOS_HIGH "High" +#define CHAOS_MAX "Maximum" diff --git a/code/__DEFINES/research.dm b/code/__DEFINES/research.dm index 95b89ae04e..9feb5f40c5 100644 --- a/code/__DEFINES/research.dm +++ b/code/__DEFINES/research.dm @@ -1,75 +1,75 @@ - -#define RDCONSOLE_UI_MODE_NORMAL 1 -#define RDCONSOLE_UI_MODE_EXPERT 2 -#define RDCONSOLE_UI_MODE_LIST 3 - -//RDSCREEN screens -#define RDSCREEN_MENU 0 -#define RDSCREEN_TECHDISK 1 -#define RDSCREEN_DESIGNDISK 20 -#define RDSCREEN_DESIGNDISK_UPLOAD 21 -#define RDSCREEN_DECONSTRUCT 3 -#define RDSCREEN_PROTOLATHE 40 -#define RDSCREEN_PROTOLATHE_MATERIALS 41 -#define RDSCREEN_PROTOLATHE_CHEMICALS 42 -#define RDSCREEN_PROTOLATHE_CATEGORY_VIEW 43 -#define RDSCREEN_PROTOLATHE_SEARCH 44 -#define RDSCREEN_IMPRINTER 50 -#define RDSCREEN_IMPRINTER_MATERIALS 51 -#define RDSCREEN_IMPRINTER_CHEMICALS 52 -#define RDSCREEN_IMPRINTER_CATEGORY_VIEW 53 -#define RDSCREEN_IMPRINTER_SEARCH 54 -#define RDSCREEN_SETTINGS 61 -#define RDSCREEN_DEVICE_LINKING 62 -#define RDSCREEN_TECHWEB 70 -#define RDSCREEN_TECHWEB_NODEVIEW 71 -#define RDSCREEN_TECHWEB_DESIGNVIEW 72 - -#define RDSCREEN_NOBREAK "" - -#define RDSCREEN_TEXT_NO_PROTOLATHE "

      No Protolathe Linked!


      " -#define RDSCREEN_TEXT_NO_IMPRINTER "

      No Circuit Imprinter Linked!


      " -#define RDSCREEN_TEXT_NO_DECONSTRUCT "

      No Destructive Analyzer Linked!


      " -#define RDSCREEN_TEXT_NO_TDISK "

      No Technology Disk Inserted!


      " -#define RDSCREEN_TEXT_NO_DDISK "

      No Design Disk Inserted!


      " -#define RDSCREEN_TEXT_NO_SNODE "

      No Technology Node Selected!


      " -#define RDSCREEN_TEXT_NO_SDESIGN "

      No Design Selected!


      " - -#define RDSCREEN_UI_LATHE_CHECK if(QDELETED(linked_lathe)) { return RDSCREEN_TEXT_NO_PROTOLATHE } -#define RDSCREEN_UI_IMPRINTER_CHECK if(QDELETED(linked_imprinter)) { return RDSCREEN_TEXT_NO_IMPRINTER } -#define RDSCREEN_UI_DECONSTRUCT_CHECK if(QDELETED(linked_destroy)) { return RDSCREEN_TEXT_NO_DECONSTRUCT } -#define RDSCREEN_UI_TDISK_CHECK if(QDELETED(t_disk)) { return RDSCREEN_TEXT_NO_TDISK } -#define RDSCREEN_UI_DDISK_CHECK if(QDELETED(d_disk)) { return RDSCREEN_TEXT_NO_DDISK } -#define RDSCREEN_UI_SNODE_CHECK if(!selected_node) { return RDSCREEN_TEXT_NO_SNODE } -#define RDSCREEN_UI_SDESIGN_CHECK if(!selected_design) { return RDSCREEN_TEXT_NO_SDESIGN } - -#define RESEARCH_FABRICATOR_SCREEN_MAIN 1 -#define RESEARCH_FABRICATOR_SCREEN_CHEMICALS 2 -#define RESEARCH_FABRICATOR_SCREEN_MATERIALS 3 -#define RESEARCH_FABRICATOR_SCREEN_SEARCH 4 -#define RESEARCH_FABRICATOR_SCREEN_CATEGORYVIEW 5 - -#define DEPARTMENTAL_FLAG_SECURITY (1<<0) -#define DEPARTMENTAL_FLAG_MEDICAL (1<<1) -#define DEPARTMENTAL_FLAG_CARGO (1<<2) -#define DEPARTMENTAL_FLAG_SCIENCE (1<<3) -#define DEPARTMENTAL_FLAG_ENGINEERING (1<<4) -#define DEPARTMENTAL_FLAG_SERVICE (1<<5) -#define DEPARTMENTAL_FLAG_ALL (1<<6) //NO THIS DOESN'T ALLOW YOU TO PRINT EVERYTHING, IT'S FOR ALL DEPARTMENTS! -//#define DEPARTMENTAL_FLAG_MINING (1<<7) - -#define DESIGN_ID_IGNORE "IGNORE_THIS_DESIGN" - -#define RESEARCH_MATERIAL_RECLAMATION_ID "__materials" - -//When adding new types, update the list below! -#define TECHWEB_POINT_TYPE_GENERIC "General Research" - -#define TECHWEB_POINT_TYPE_DEFAULT TECHWEB_POINT_TYPE_GENERIC - -//defined here so people don't forget to change this! -#define TECHWEB_POINT_TYPE_LIST_ASSOCIATIVE_NAMES list(\ - TECHWEB_POINT_TYPE_GENERIC = "General Research"\ - ) - -#define TECHWEB_BOMB_POINTCAP 50000 //Adjust as needed; Stops toxins from nullifying RND progression mechanics. Current Value Cap Radius: 100 + +#define RDCONSOLE_UI_MODE_NORMAL 1 +#define RDCONSOLE_UI_MODE_EXPERT 2 +#define RDCONSOLE_UI_MODE_LIST 3 + +//RDSCREEN screens +#define RDSCREEN_MENU 0 +#define RDSCREEN_TECHDISK 1 +#define RDSCREEN_DESIGNDISK 20 +#define RDSCREEN_DESIGNDISK_UPLOAD 21 +#define RDSCREEN_DECONSTRUCT 3 +#define RDSCREEN_PROTOLATHE 40 +#define RDSCREEN_PROTOLATHE_MATERIALS 41 +#define RDSCREEN_PROTOLATHE_CHEMICALS 42 +#define RDSCREEN_PROTOLATHE_CATEGORY_VIEW 43 +#define RDSCREEN_PROTOLATHE_SEARCH 44 +#define RDSCREEN_IMPRINTER 50 +#define RDSCREEN_IMPRINTER_MATERIALS 51 +#define RDSCREEN_IMPRINTER_CHEMICALS 52 +#define RDSCREEN_IMPRINTER_CATEGORY_VIEW 53 +#define RDSCREEN_IMPRINTER_SEARCH 54 +#define RDSCREEN_SETTINGS 61 +#define RDSCREEN_DEVICE_LINKING 62 +#define RDSCREEN_TECHWEB 70 +#define RDSCREEN_TECHWEB_NODEVIEW 71 +#define RDSCREEN_TECHWEB_DESIGNVIEW 72 + +#define RDSCREEN_NOBREAK "" + +#define RDSCREEN_TEXT_NO_PROTOLATHE "

      No Protolathe Linked!


      " +#define RDSCREEN_TEXT_NO_IMPRINTER "

      No Circuit Imprinter Linked!


      " +#define RDSCREEN_TEXT_NO_DECONSTRUCT "

      No Destructive Analyzer Linked!


      " +#define RDSCREEN_TEXT_NO_TDISK "

      No Technology Disk Inserted!


      " +#define RDSCREEN_TEXT_NO_DDISK "

      No Design Disk Inserted!


      " +#define RDSCREEN_TEXT_NO_SNODE "

      No Technology Node Selected!


      " +#define RDSCREEN_TEXT_NO_SDESIGN "

      No Design Selected!


      " + +#define RDSCREEN_UI_LATHE_CHECK if(QDELETED(linked_lathe)) { return RDSCREEN_TEXT_NO_PROTOLATHE } +#define RDSCREEN_UI_IMPRINTER_CHECK if(QDELETED(linked_imprinter)) { return RDSCREEN_TEXT_NO_IMPRINTER } +#define RDSCREEN_UI_DECONSTRUCT_CHECK if(QDELETED(linked_destroy)) { return RDSCREEN_TEXT_NO_DECONSTRUCT } +#define RDSCREEN_UI_TDISK_CHECK if(QDELETED(t_disk)) { return RDSCREEN_TEXT_NO_TDISK } +#define RDSCREEN_UI_DDISK_CHECK if(QDELETED(d_disk)) { return RDSCREEN_TEXT_NO_DDISK } +#define RDSCREEN_UI_SNODE_CHECK if(!selected_node) { return RDSCREEN_TEXT_NO_SNODE } +#define RDSCREEN_UI_SDESIGN_CHECK if(!selected_design) { return RDSCREEN_TEXT_NO_SDESIGN } + +#define RESEARCH_FABRICATOR_SCREEN_MAIN 1 +#define RESEARCH_FABRICATOR_SCREEN_CHEMICALS 2 +#define RESEARCH_FABRICATOR_SCREEN_MATERIALS 3 +#define RESEARCH_FABRICATOR_SCREEN_SEARCH 4 +#define RESEARCH_FABRICATOR_SCREEN_CATEGORYVIEW 5 + +#define DEPARTMENTAL_FLAG_SECURITY (1<<0) +#define DEPARTMENTAL_FLAG_MEDICAL (1<<1) +#define DEPARTMENTAL_FLAG_CARGO (1<<2) +#define DEPARTMENTAL_FLAG_SCIENCE (1<<3) +#define DEPARTMENTAL_FLAG_ENGINEERING (1<<4) +#define DEPARTMENTAL_FLAG_SERVICE (1<<5) +#define DEPARTMENTAL_FLAG_ALL (1<<6) //NO THIS DOESN'T ALLOW YOU TO PRINT EVERYTHING, IT'S FOR ALL DEPARTMENTS! +//#define DEPARTMENTAL_FLAG_MINING (1<<7) + +#define DESIGN_ID_IGNORE "IGNORE_THIS_DESIGN" + +#define RESEARCH_MATERIAL_RECLAMATION_ID "__materials" + +//When adding new types, update the list below! +#define TECHWEB_POINT_TYPE_GENERIC "General Research" + +#define TECHWEB_POINT_TYPE_DEFAULT TECHWEB_POINT_TYPE_GENERIC + +//defined here so people don't forget to change this! +#define TECHWEB_POINT_TYPE_LIST_ASSOCIATIVE_NAMES list(\ + TECHWEB_POINT_TYPE_GENERIC = "General Research"\ + ) + +#define TECHWEB_BOMB_POINTCAP 50000 //Adjust as needed; Stops toxins from nullifying RND progression mechanics. Current Value Cap Radius: 100 diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm index f6302813f5..581bb2bc29 100644 --- a/code/__DEFINES/sound.dm +++ b/code/__DEFINES/sound.dm @@ -1,81 +1,81 @@ -//max channel is 1024. Only go lower from here, because byond tends to pick the first availiable channel to play sounds on -#define CHANNEL_LOBBYMUSIC 1024 -#define CHANNEL_ADMIN 1023 -#define CHANNEL_VOX 1022 -#define CHANNEL_JUKEBOX 1021 -#define CHANNEL_JUKEBOX_START 1016 //The gap between this and CHANNEL_JUKEBOX determines the amount of free jukebox channels. This currently allows 6 jukebox channels to exist. -#define CHANNEL_JUSTICAR_ARK 1015 -#define CHANNEL_HEARTBEAT 1014 //sound channel for heartbeats -#define CHANNEL_AMBIENCE 1013 -#define CHANNEL_BUZZ 1012 -#define CHANNEL_BICYCLE 1011 - -//CIT CHANNELS - TRY NOT TO REGRESS -#define CHANNEL_PRED 1010 -#define CHANNEL_DIGEST 1009 -#define CHANNEL_PREYLOOP 1008 - -//THIS SHOULD ALWAYS BE THE LOWEST ONE! -//KEEP IT UPDATED - -#define CHANNEL_HIGHEST_AVAILABLE 1008 //CIT CHANGE - COMPENSATES FOR VORESOUND CHANNELS - - -#define SOUND_MINIMUM_PRESSURE 10 -#define FALLOFF_SOUNDS 1 - - -//Ambience types - -#define GENERIC list('sound/ambience/ambigen1.ogg','sound/ambience/ambigen3.ogg',\ - 'sound/ambience/ambigen4.ogg','sound/ambience/ambigen5.ogg',\ - 'sound/ambience/ambigen6.ogg','sound/ambience/ambigen7.ogg',\ - 'sound/ambience/ambigen8.ogg','sound/ambience/ambigen9.ogg',\ - 'sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg',\ - 'sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg','sound/ambience/ambigen15.ogg') - -#define HOLY list('sound/ambience/ambicha1.ogg','sound/ambience/ambicha2.ogg','sound/ambience/ambicha3.ogg',\ - 'sound/ambience/ambicha4.ogg', 'sound/ambience/ambiholy.ogg', 'sound/ambience/ambiholy2.ogg',\ - 'sound/ambience/ambiholy3.ogg') - -#define HIGHSEC list('sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg') - -#define RUINS list('sound/ambience/ambimine.ogg', 'sound/ambience/ambicave.ogg', 'sound/ambience/ambiruin.ogg',\ - 'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\ - 'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\ - 'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambitech3.ogg',\ - 'sound/ambience/ambimystery.ogg', 'sound/ambience/ambimaint1.ogg') - -#define ENGINEERING list('sound/ambience/ambisin1.ogg','sound/ambience/ambisin2.ogg','sound/ambience/ambisin3.ogg','sound/ambience/ambisin4.ogg',\ - 'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg', 'sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambitech3.ogg') - -#define MINING list('sound/ambience/ambimine.ogg', 'sound/ambience/ambicave.ogg', 'sound/ambience/ambiruin.ogg',\ - 'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\ - 'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\ - 'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambimaint1.ogg', 'sound/ambience/ambilava.ogg') - -#define MEDICAL list('sound/ambience/ambinice.ogg') - -#define SPOOKY list('sound/ambience/ambimo1.ogg','sound/ambience/ambimo2.ogg','sound/ambience/ambiruin7.ogg','sound/ambience/ambiruin6.ogg',\ - 'sound/ambience/ambiodd.ogg', 'sound/ambience/ambimystery.ogg') - -#define SPACE list('sound/ambience/ambispace.ogg', 'sound/ambience/ambispace2.ogg', 'sound/ambience/title2.ogg', 'sound/ambience/ambiatmos.ogg') - -#define MAINTENANCE list('sound/ambience/ambimaint1.ogg', 'sound/ambience/ambimaint2.ogg', 'sound/ambience/ambimaint3.ogg', 'sound/ambience/ambimaint4.ogg',\ - 'sound/ambience/ambimaint5.ogg', 'sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg', 'sound/ambience/ambitech2.ogg' ) - -#define AWAY_MISSION list('sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambiruin.ogg',\ - 'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\ - 'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\ - 'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambimaint.ogg',\ - 'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg', 'sound/ambience/ambiodd.ogg') - -#define REEBE list('sound/ambience/ambireebe1.ogg', 'sound/ambience/ambireebe2.ogg', 'sound/ambience/ambireebe3.ogg') - - - -#define CREEPY_SOUNDS list('sound/effects/ghost.ogg', 'sound/effects/ghost2.ogg', 'sound/effects/heart_beat.ogg', 'sound/effects/screech.ogg',\ - 'sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/behind_you2.ogg', 'sound/hallucinations/far_noise.ogg', 'sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg',\ - 'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\ - 'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\ - 'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg') +//max channel is 1024. Only go lower from here, because byond tends to pick the first availiable channel to play sounds on +#define CHANNEL_LOBBYMUSIC 1024 +#define CHANNEL_ADMIN 1023 +#define CHANNEL_VOX 1022 +#define CHANNEL_JUKEBOX 1021 +#define CHANNEL_JUKEBOX_START 1016 //The gap between this and CHANNEL_JUKEBOX determines the amount of free jukebox channels. This currently allows 6 jukebox channels to exist. +#define CHANNEL_JUSTICAR_ARK 1015 +#define CHANNEL_HEARTBEAT 1014 //sound channel for heartbeats +#define CHANNEL_AMBIENCE 1013 +#define CHANNEL_BUZZ 1012 +#define CHANNEL_BICYCLE 1011 + +//CIT CHANNELS - TRY NOT TO REGRESS +#define CHANNEL_PRED 1010 +#define CHANNEL_DIGEST 1009 +#define CHANNEL_PREYLOOP 1008 + +//THIS SHOULD ALWAYS BE THE LOWEST ONE! +//KEEP IT UPDATED + +#define CHANNEL_HIGHEST_AVAILABLE 1008 //CIT CHANGE - COMPENSATES FOR VORESOUND CHANNELS + + +#define SOUND_MINIMUM_PRESSURE 10 +#define FALLOFF_SOUNDS 1 + + +//Ambience types + +#define GENERIC list('sound/ambience/ambigen1.ogg','sound/ambience/ambigen3.ogg',\ + 'sound/ambience/ambigen4.ogg','sound/ambience/ambigen5.ogg',\ + 'sound/ambience/ambigen6.ogg','sound/ambience/ambigen7.ogg',\ + 'sound/ambience/ambigen8.ogg','sound/ambience/ambigen9.ogg',\ + 'sound/ambience/ambigen10.ogg','sound/ambience/ambigen11.ogg',\ + 'sound/ambience/ambigen12.ogg','sound/ambience/ambigen14.ogg','sound/ambience/ambigen15.ogg') + +#define HOLY list('sound/ambience/ambicha1.ogg','sound/ambience/ambicha2.ogg','sound/ambience/ambicha3.ogg',\ + 'sound/ambience/ambicha4.ogg', 'sound/ambience/ambiholy.ogg', 'sound/ambience/ambiholy2.ogg',\ + 'sound/ambience/ambiholy3.ogg') + +#define HIGHSEC list('sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg') + +#define RUINS list('sound/ambience/ambimine.ogg', 'sound/ambience/ambicave.ogg', 'sound/ambience/ambiruin.ogg',\ + 'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\ + 'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\ + 'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambitech3.ogg',\ + 'sound/ambience/ambimystery.ogg', 'sound/ambience/ambimaint1.ogg') + +#define ENGINEERING list('sound/ambience/ambisin1.ogg','sound/ambience/ambisin2.ogg','sound/ambience/ambisin3.ogg','sound/ambience/ambisin4.ogg',\ + 'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg', 'sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambitech3.ogg') + +#define MINING list('sound/ambience/ambimine.ogg', 'sound/ambience/ambicave.ogg', 'sound/ambience/ambiruin.ogg',\ + 'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\ + 'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\ + 'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambimaint1.ogg', 'sound/ambience/ambilava.ogg') + +#define MEDICAL list('sound/ambience/ambinice.ogg') + +#define SPOOKY list('sound/ambience/ambimo1.ogg','sound/ambience/ambimo2.ogg','sound/ambience/ambiruin7.ogg','sound/ambience/ambiruin6.ogg',\ + 'sound/ambience/ambiodd.ogg', 'sound/ambience/ambimystery.ogg') + +#define SPACE list('sound/ambience/ambispace.ogg', 'sound/ambience/ambispace2.ogg', 'sound/ambience/title2.ogg', 'sound/ambience/ambiatmos.ogg') + +#define MAINTENANCE list('sound/ambience/ambimaint1.ogg', 'sound/ambience/ambimaint2.ogg', 'sound/ambience/ambimaint3.ogg', 'sound/ambience/ambimaint4.ogg',\ + 'sound/ambience/ambimaint5.ogg', 'sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg', 'sound/ambience/ambitech2.ogg' ) + +#define AWAY_MISSION list('sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambiruin.ogg',\ + 'sound/ambience/ambiruin2.ogg', 'sound/ambience/ambiruin3.ogg', 'sound/ambience/ambiruin4.ogg',\ + 'sound/ambience/ambiruin5.ogg', 'sound/ambience/ambiruin6.ogg', 'sound/ambience/ambiruin7.ogg',\ + 'sound/ambience/ambidanger.ogg', 'sound/ambience/ambidanger2.ogg', 'sound/ambience/ambimaint.ogg',\ + 'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg', 'sound/ambience/ambiodd.ogg') + +#define REEBE list('sound/ambience/ambireebe1.ogg', 'sound/ambience/ambireebe2.ogg', 'sound/ambience/ambireebe3.ogg') + + + +#define CREEPY_SOUNDS list('sound/effects/ghost.ogg', 'sound/effects/ghost2.ogg', 'sound/effects/heart_beat.ogg', 'sound/effects/screech.ogg',\ + 'sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/behind_you2.ogg', 'sound/hallucinations/far_noise.ogg', 'sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg',\ + 'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\ + 'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\ + 'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg') diff --git a/code/__DEFINES/stat.dm b/code/__DEFINES/stat.dm index b975aa1f89..2dade0825f 100644 --- a/code/__DEFINES/stat.dm +++ b/code/__DEFINES/stat.dm @@ -1,22 +1,22 @@ -/* - Used with the various stat variables (mob, machines) -*/ - -//mob/var/stat things -#define CONSCIOUS 0 -#define SOFT_CRIT 1 -#define UNCONSCIOUS 2 -#define DEAD 3 - -//Maximum healthiness an individual can have -#define MAX_SATIETY 600 - -// bitflags for machine stat variable -#define BROKEN (1<<0) -#define NOPOWER (1<<1) -#define MAINT (1<<2) // under maintaince -#define EMPED (1<<3) // temporary broken by EMP pulse - -//ai power requirement defines -#define POWER_REQ_ALL 1 -#define POWER_REQ_CLOCKCULT 2 +/* + Used with the various stat variables (mob, machines) +*/ + +//mob/var/stat things +#define CONSCIOUS 0 +#define SOFT_CRIT 1 +#define UNCONSCIOUS 2 +#define DEAD 3 + +//Maximum healthiness an individual can have +#define MAX_SATIETY 600 + +// bitflags for machine stat variable +#define BROKEN (1<<0) +#define NOPOWER (1<<1) +#define MAINT (1<<2) // under maintaince +#define EMPED (1<<3) // temporary broken by EMP pulse + +//ai power requirement defines +#define POWER_REQ_ALL 1 +#define POWER_REQ_CLOCKCULT 2 diff --git a/code/__DEFINES/tgs.config.dm b/code/__DEFINES/tgs.config.dm index b05cff7e01..a40b5d4663 100644 --- a/code/__DEFINES/tgs.config.dm +++ b/code/__DEFINES/tgs.config.dm @@ -1,10 +1,10 @@ -#define TGS_EXTERNAL_CONFIGURATION -#define TGS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name) -#define TGS_READ_GLOBAL(Name) GLOB.##Name -#define TGS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value -#define TGS_WORLD_ANNOUNCE(message) to_chat(world, "[html_encode(##message)]") -#define TGS_INFO_LOG(message) log_world("TGS: Info: [##message]") -#define TGS_ERROR_LOG(message) log_world("TGS: Error: [##message]") -#define TGS_NOTIFY_ADMINS(event) message_admins(##event) -#define TGS_CLIENT_COUNT GLOB.clients.len -#define TGS_PROTECT_DATUM(Path) GENERAL_PROTECT_DATUM(##Path) +#define TGS_EXTERNAL_CONFIGURATION +#define TGS_DEFINE_AND_SET_GLOBAL(Name, Value) GLOBAL_VAR_INIT(##Name, ##Value); GLOBAL_PROTECT(##Name) +#define TGS_READ_GLOBAL(Name) GLOB.##Name +#define TGS_WRITE_GLOBAL(Name, Value) GLOB.##Name = ##Value +#define TGS_WORLD_ANNOUNCE(message) to_chat(world, "[html_encode(##message)]") +#define TGS_INFO_LOG(message) log_world("TGS: Info: [##message]") +#define TGS_ERROR_LOG(message) log_world("TGS: Error: [##message]") +#define TGS_NOTIFY_ADMINS(event) message_admins(##event) +#define TGS_CLIENT_COUNT GLOB.clients.len +#define TGS_PROTECT_DATUM(Path) GENERAL_PROTECT_DATUM(##Path) diff --git a/code/__DEFINES/tgs.dm b/code/__DEFINES/tgs.dm index d24054a24c..db4f046ec3 100644 --- a/code/__DEFINES/tgs.dm +++ b/code/__DEFINES/tgs.dm @@ -1,242 +1,242 @@ -//tgstation-server DMAPI - -//All functions and datums outside this document are subject to change with any version and should not be relied on - -//CONFIGURATION - -//create this define if you want to do configuration outside of this file -#ifndef TGS_EXTERNAL_CONFIGURATION - -//Comment this out once you've filled in the below -#error TGS API unconfigured - -//Uncomment this if you wish to allow the game to interact with TGS 3 -//This will raise the minimum required security level of your game to TGS_SECURITY_TRUSTED due to it utilizing call()() -//#define TGS_V3_API - -//Required interfaces (fill in with your codebase equivalent): - -//create a global variable named `Name` and set it to `Value` -//These globals must not be modifiable from anywhere outside of the server tools -#define TGS_DEFINE_AND_SET_GLOBAL(Name, Value) - -//Read the value in the global variable `Name` -#define TGS_READ_GLOBAL(Name) - -//Set the value in the global variable `Name` to `Value` -#define TGS_WRITE_GLOBAL(Name, Value) - -//Disallow ANYONE from reflecting a given `path`, security measure to prevent in-game priveledge escalation -#define TGS_PROTECT_DATUM(Path) - -//display an announcement `message` from the server to all players -#define TGS_WORLD_ANNOUNCE(message) - -//Notify current in-game administrators of a string `event` -#define TGS_NOTIFY_ADMINS(event) - -//Write an info `message` to a server log -#define TGS_INFO_LOG(message) - -//Write an error `message` to a server log -#define TGS_ERROR_LOG(message) - -//Get the number of connected /clients -#define TGS_CLIENT_COUNT - -#endif - -//EVENT CODES - -#define TGS_EVENT_PORT_SWAP -2 //before a port change is about to happen, extra parameter is new port -#define TGS_EVENT_REBOOT_MODE_CHANGE -1 //before a reboot mode change, extras parameters are the current and new reboot mode enums - -//See the descriptions for these codes here: https://github.com/tgstation/tgstation-server/blob/master/src/Tgstation.Server.Host/Components/EventType.cs -#define TGS_EVENT_REPO_RESET_ORIGIN 0 -#define TGS_EVENT_REPO_CHECKOUT 1 -#define TGS_EVENT_REPO_FETCH 2 -#define TGS_EVENT_REPO_MERGE_PULL_REQUEST 3 -#define TGS_EVENT_REPO_PRE_SYNCHRONIZE 4 -#define TGS_EVENT_BYOND_INSTALL_START 5 -#define TGS_EVENT_BYOND_INSTALL_FAIL 6 -#define TGS_EVENT_BYOND_ACTIVE_VERSION_CHANGE 7 -#define TGS_EVENT_COMPILE_START 8 -#define TGS_EVENT_COMPILE_CANCELLED 9 -#define TGS_EVENT_COMPILE_FAILURE 10 -#define TGS_EVENT_COMPILE_COMPLETE 11 -#define TGS_EVENT_INSTANCE_AUTO_UPDATE_START 12 -#define TGS_EVENT_REPO_MERGE_CONFLICT 13 - -//OTHER ENUMS - -#define TGS_REBOOT_MODE_NORMAL 0 -#define TGS_REBOOT_MODE_SHUTDOWN 1 -#define TGS_REBOOT_MODE_RESTART 2 - -#define TGS_SECURITY_TRUSTED 0 -#define TGS_SECURITY_SAFE 1 -#define TGS_SECURITY_ULTRASAFE 2 - -//REQUIRED HOOKS - -//Call this somewhere in /world/New() that is always run -//event_handler: optional user defined event handler. The default behaviour is to broadcast the event in english to all connected admin channels -//minimum_required_security_level: The minimum required security level to run the game in which the DMAPI is integrated -/world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE) - return - -//Call this when your initializations are complete and your game is ready to play before any player interactions happen -//This may use world.sleep_offline to make this happen so ensure no changes are made to it while this call is running -//Most importantly, before this point, note that any static files or directories may be in use by another server. Your code should account for this -//This function should not be called before ..() in /world/New() -/world/proc/TgsInitializationComplete() - return - -//Put this at the start of /world/Topic() -#define TGS_TOPIC var/tgs_topic_return = TgsTopic(args[1]); if(tgs_topic_return) return tgs_topic_return - -//Call this at the beginning of world/Reboot(reason) -/world/proc/TgsReboot() - return - -//DATUM DEFINITIONS -//unless otherwise specified all datums defined here should be considered read-only, warranty void if written - -//represents git revision information about the current world build -/datum/tgs_revision_information - var/commit //full sha of compiled commit - var/origin_commit //full sha of last known remote commit. This may be null if the TGS repository is not currently tracking a remote branch - -//represents a merge of a GitHub pull request -/datum/tgs_revision_information/test_merge - var/number //pull request number - var/title //pull request title - var/body //pull request body - var/author //pull request github author - var/url //link to pull request html - var/pull_request_commit //commit of the pull request when it was merged - var/time_merged //timestamp of when the merge commit for the pull request was created - var/comment //optional comment left by the one who initiated the test merge - -//represents a connected chat channel -/datum/tgs_chat_channel - var/id //internal channel representation - var/friendly_name //user friendly channel name - var/connection_name //the name of the configured chat connection - var/is_admin_channel //if the server operator has marked this channel for game admins only - var/is_private_channel //if this is a private chat channel - var/custom_tag //user defined string associated with channel - -//represents a chat user -/datum/tgs_chat_user - var/id //Internal user representation, requires channel to be unique - var/friendly_name //The user's public name - var/mention //The text to use to ping this user in a message - var/datum/tgs_chat_channel/channel //The /datum/tgs_chat_channel this user was from - -//user definable callback for handling events -//extra parameters may be specified depending on the event -/datum/tgs_event_handler/proc/HandleEvent(event_code, ...) - set waitfor = FALSE - return - -//user definable chat command -/datum/tgs_chat_command - var/name = "" //the string to trigger this command on a chat bot. e.g. TGS3_BOT: do_this_command - var/help_text = "" //help text for this command - var/admin_only = FALSE //set to TRUE if this command should only be usable by registered chat admins - -//override to implement command -//sender: The tgs_chat_user who send to command -//params: The trimmed string following the command name -//The return value will be stringified and sent to the appropriate chat -/datum/tgs_chat_command/proc/Run(datum/tgs_chat_user/sender, params) - CRASH("[type] has no implementation for Run()") - -//FUNCTIONS - -//Returns the respective string version of the API -/world/proc/TgsMaximumAPIVersion() - return - -/world/proc/TgsMinimumAPIVersion() - return - -//Gets the current version of the server tools running the server -/world/proc/TgsVersion() - return - -//Returns TRUE if the world was launched under the server tools and the API matches, FALSE otherwise -//No function below this succeeds if it returns FALSE -/world/proc/TgsAvailable() - return - -/world/proc/TgsInstanceName() - return - -//Get the current `/datum/tgs_revision_information` -/world/proc/TgsRevision() - return - -//Get the current BYOND security level -/world/proc/TgsSecurityLevel() - return - -//Gets a list of active `/datum/tgs_revision_information/test_merge`s -/world/proc/TgsTestMerges() - return - -//Forces a hard reboot of BYOND by ending the process -//unlike del(world) clients will try to reconnect -//If the service has not requested a shutdown, the next server will take over -/world/proc/TgsEndProcess() - return - -//Gets a list of connected tgs_chat_channel -/world/proc/TgsChatChannelInfo() - return - -//Sends a message to connected game chats -//message: The message to send -//channels: optional channels to limit the broadcast to -/world/proc/TgsChatBroadcast(message, list/channels) - return - -//Send a message to non-admin connected chats -//message: The message to send -//admin_only: If TRUE, message will instead be sent to only admin connected chats -/world/proc/TgsTargetedChatBroadcast(message, admin_only) - return - -//Send a private message to a specific user -//message: The message to send -//user: The /datum/tgs_chat_user to send to -/world/proc/TgsChatPrivateMessage(message, datum/tgs_chat_user/user) - return - -/* -The MIT License - -Copyright (c) 2017 Jordan Brown - -Permission is hereby granted, free of charge, -to any person obtaining a copy of this software and -associated documentation files (the "Software"), to -deal in the Software without restriction, including -without limitation the rights to use, copy, modify, -merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom -the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +//tgstation-server DMAPI + +//All functions and datums outside this document are subject to change with any version and should not be relied on + +//CONFIGURATION + +//create this define if you want to do configuration outside of this file +#ifndef TGS_EXTERNAL_CONFIGURATION + +//Comment this out once you've filled in the below +#error TGS API unconfigured + +//Uncomment this if you wish to allow the game to interact with TGS 3 +//This will raise the minimum required security level of your game to TGS_SECURITY_TRUSTED due to it utilizing call()() +//#define TGS_V3_API + +//Required interfaces (fill in with your codebase equivalent): + +//create a global variable named `Name` and set it to `Value` +//These globals must not be modifiable from anywhere outside of the server tools +#define TGS_DEFINE_AND_SET_GLOBAL(Name, Value) + +//Read the value in the global variable `Name` +#define TGS_READ_GLOBAL(Name) + +//Set the value in the global variable `Name` to `Value` +#define TGS_WRITE_GLOBAL(Name, Value) + +//Disallow ANYONE from reflecting a given `path`, security measure to prevent in-game priveledge escalation +#define TGS_PROTECT_DATUM(Path) + +//display an announcement `message` from the server to all players +#define TGS_WORLD_ANNOUNCE(message) + +//Notify current in-game administrators of a string `event` +#define TGS_NOTIFY_ADMINS(event) + +//Write an info `message` to a server log +#define TGS_INFO_LOG(message) + +//Write an error `message` to a server log +#define TGS_ERROR_LOG(message) + +//Get the number of connected /clients +#define TGS_CLIENT_COUNT + +#endif + +//EVENT CODES + +#define TGS_EVENT_PORT_SWAP -2 //before a port change is about to happen, extra parameter is new port +#define TGS_EVENT_REBOOT_MODE_CHANGE -1 //before a reboot mode change, extras parameters are the current and new reboot mode enums + +//See the descriptions for these codes here: https://github.com/tgstation/tgstation-server/blob/master/src/Tgstation.Server.Host/Components/EventType.cs +#define TGS_EVENT_REPO_RESET_ORIGIN 0 +#define TGS_EVENT_REPO_CHECKOUT 1 +#define TGS_EVENT_REPO_FETCH 2 +#define TGS_EVENT_REPO_MERGE_PULL_REQUEST 3 +#define TGS_EVENT_REPO_PRE_SYNCHRONIZE 4 +#define TGS_EVENT_BYOND_INSTALL_START 5 +#define TGS_EVENT_BYOND_INSTALL_FAIL 6 +#define TGS_EVENT_BYOND_ACTIVE_VERSION_CHANGE 7 +#define TGS_EVENT_COMPILE_START 8 +#define TGS_EVENT_COMPILE_CANCELLED 9 +#define TGS_EVENT_COMPILE_FAILURE 10 +#define TGS_EVENT_COMPILE_COMPLETE 11 +#define TGS_EVENT_INSTANCE_AUTO_UPDATE_START 12 +#define TGS_EVENT_REPO_MERGE_CONFLICT 13 + +//OTHER ENUMS + +#define TGS_REBOOT_MODE_NORMAL 0 +#define TGS_REBOOT_MODE_SHUTDOWN 1 +#define TGS_REBOOT_MODE_RESTART 2 + +#define TGS_SECURITY_TRUSTED 0 +#define TGS_SECURITY_SAFE 1 +#define TGS_SECURITY_ULTRASAFE 2 + +//REQUIRED HOOKS + +//Call this somewhere in /world/New() that is always run +//event_handler: optional user defined event handler. The default behaviour is to broadcast the event in english to all connected admin channels +//minimum_required_security_level: The minimum required security level to run the game in which the DMAPI is integrated +/world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE) + return + +//Call this when your initializations are complete and your game is ready to play before any player interactions happen +//This may use world.sleep_offline to make this happen so ensure no changes are made to it while this call is running +//Most importantly, before this point, note that any static files or directories may be in use by another server. Your code should account for this +//This function should not be called before ..() in /world/New() +/world/proc/TgsInitializationComplete() + return + +//Put this at the start of /world/Topic() +#define TGS_TOPIC var/tgs_topic_return = TgsTopic(args[1]); if(tgs_topic_return) return tgs_topic_return + +//Call this at the beginning of world/Reboot(reason) +/world/proc/TgsReboot() + return + +//DATUM DEFINITIONS +//unless otherwise specified all datums defined here should be considered read-only, warranty void if written + +//represents git revision information about the current world build +/datum/tgs_revision_information + var/commit //full sha of compiled commit + var/origin_commit //full sha of last known remote commit. This may be null if the TGS repository is not currently tracking a remote branch + +//represents a merge of a GitHub pull request +/datum/tgs_revision_information/test_merge + var/number //pull request number + var/title //pull request title + var/body //pull request body + var/author //pull request github author + var/url //link to pull request html + var/pull_request_commit //commit of the pull request when it was merged + var/time_merged //timestamp of when the merge commit for the pull request was created + var/comment //optional comment left by the one who initiated the test merge + +//represents a connected chat channel +/datum/tgs_chat_channel + var/id //internal channel representation + var/friendly_name //user friendly channel name + var/connection_name //the name of the configured chat connection + var/is_admin_channel //if the server operator has marked this channel for game admins only + var/is_private_channel //if this is a private chat channel + var/custom_tag //user defined string associated with channel + +//represents a chat user +/datum/tgs_chat_user + var/id //Internal user representation, requires channel to be unique + var/friendly_name //The user's public name + var/mention //The text to use to ping this user in a message + var/datum/tgs_chat_channel/channel //The /datum/tgs_chat_channel this user was from + +//user definable callback for handling events +//extra parameters may be specified depending on the event +/datum/tgs_event_handler/proc/HandleEvent(event_code, ...) + set waitfor = FALSE + return + +//user definable chat command +/datum/tgs_chat_command + var/name = "" //the string to trigger this command on a chat bot. e.g. TGS3_BOT: do_this_command + var/help_text = "" //help text for this command + var/admin_only = FALSE //set to TRUE if this command should only be usable by registered chat admins + +//override to implement command +//sender: The tgs_chat_user who send to command +//params: The trimmed string following the command name +//The return value will be stringified and sent to the appropriate chat +/datum/tgs_chat_command/proc/Run(datum/tgs_chat_user/sender, params) + CRASH("[type] has no implementation for Run()") + +//FUNCTIONS + +//Returns the respective string version of the API +/world/proc/TgsMaximumAPIVersion() + return + +/world/proc/TgsMinimumAPIVersion() + return + +//Gets the current version of the server tools running the server +/world/proc/TgsVersion() + return + +//Returns TRUE if the world was launched under the server tools and the API matches, FALSE otherwise +//No function below this succeeds if it returns FALSE +/world/proc/TgsAvailable() + return + +/world/proc/TgsInstanceName() + return + +//Get the current `/datum/tgs_revision_information` +/world/proc/TgsRevision() + return + +//Get the current BYOND security level +/world/proc/TgsSecurityLevel() + return + +//Gets a list of active `/datum/tgs_revision_information/test_merge`s +/world/proc/TgsTestMerges() + return + +//Forces a hard reboot of BYOND by ending the process +//unlike del(world) clients will try to reconnect +//If the service has not requested a shutdown, the next server will take over +/world/proc/TgsEndProcess() + return + +//Gets a list of connected tgs_chat_channel +/world/proc/TgsChatChannelInfo() + return + +//Sends a message to connected game chats +//message: The message to send +//channels: optional channels to limit the broadcast to +/world/proc/TgsChatBroadcast(message, list/channels) + return + +//Send a message to non-admin connected chats +//message: The message to send +//admin_only: If TRUE, message will instead be sent to only admin connected chats +/world/proc/TgsTargetedChatBroadcast(message, admin_only) + return + +//Send a private message to a specific user +//message: The message to send +//user: The /datum/tgs_chat_user to send to +/world/proc/TgsChatPrivateMessage(message, datum/tgs_chat_user/user) + return + +/* +The MIT License + +Copyright (c) 2017 Jordan Brown + +Permission is hereby granted, free of charge, +to any person obtaining a copy of this software and +associated documentation files (the "Software"), to +deal in the Software without restriction, including +without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom +the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ \ No newline at end of file diff --git a/code/__DEFINES/tools.dm b/code/__DEFINES/tools.dm index 00e08129ae..3fd6b069d4 100644 --- a/code/__DEFINES/tools.dm +++ b/code/__DEFINES/tools.dm @@ -1,21 +1,21 @@ -// Tool types -#define TOOL_CROWBAR "crowbar" -#define TOOL_MULTITOOL "multitool" -#define TOOL_SCREWDRIVER "screwdriver" -#define TOOL_WIRECUTTER "wirecutter" -#define TOOL_WRENCH "wrench" -#define TOOL_WELDER "welder" -#define TOOL_ANALYZER "analyzer" -#define TOOL_MINING "mining" -#define TOOL_SHOVEL "shovel" -#define TOOL_RETRACTOR "retractor" -#define TOOL_HEMOSTAT "hemostat" -#define TOOL_CAUTERY "cautery" -#define TOOL_DRILL "drill" -#define TOOL_SCALPEL "scalpel" -#define TOOL_SAW "saw" - - -// If delay between the start and the end of tool operation is less than MIN_TOOL_SOUND_DELAY, -// tool sound is only played when op is started. If not, it's played twice. -#define MIN_TOOL_SOUND_DELAY 20 +// Tool types +#define TOOL_CROWBAR "crowbar" +#define TOOL_MULTITOOL "multitool" +#define TOOL_SCREWDRIVER "screwdriver" +#define TOOL_WIRECUTTER "wirecutter" +#define TOOL_WRENCH "wrench" +#define TOOL_WELDER "welder" +#define TOOL_ANALYZER "analyzer" +#define TOOL_MINING "mining" +#define TOOL_SHOVEL "shovel" +#define TOOL_RETRACTOR "retractor" +#define TOOL_HEMOSTAT "hemostat" +#define TOOL_CAUTERY "cautery" +#define TOOL_DRILL "drill" +#define TOOL_SCALPEL "scalpel" +#define TOOL_SAW "saw" + + +// If delay between the start and the end of tool operation is less than MIN_TOOL_SOUND_DELAY, +// tool sound is only played when op is started. If not, it's played twice. +#define MIN_TOOL_SOUND_DELAY 20 diff --git a/code/__DEFINES/wires.dm b/code/__DEFINES/wires.dm index 960d0479be..34063c1787 100644 --- a/code/__DEFINES/wires.dm +++ b/code/__DEFINES/wires.dm @@ -1,50 +1,50 @@ -//retvals for attempt_wires_interaction -#define WIRE_INTERACTION_FAIL 0 -#define WIRE_INTERACTION_SUCCESSFUL 1 -#define WIRE_INTERACTION_BLOCK 2 //don't do anything else rather than open wires and whatever else. - -#define WIRE_DUD_PREFIX "__dud" -#define WIRE_ACTIVATE "Activate" -#define WIRE_AI "AI Connection" -#define WIRE_ALARM "Alarm" -#define WIRE_AVOIDANCE "Avoidance" -#define WIRE_BACKUP1 "Auxiliary Power 1" -#define WIRE_BACKUP2 "Auxiliary Power 2" -#define WIRE_BEACON "Beacon" -#define WIRE_BOLTS "Bolts" -#define WIRE_BOOM "Boom" -#define WIRE_CAMERA "Camera" -#define WIRE_CONTRABAND "Contraband" -#define WIRE_DELAY "Delay" -#define WIRE_DISABLE "Disable" -#define WIRE_DISARM "Disarm" -#define WIRE_HACK "Hack" -#define WIRE_IDSCAN "ID Scan" -#define WIRE_INTERFACE "Interface" -#define WIRE_LAWSYNC "AI Law Synchronization" -#define WIRE_LIGHT "Bolt Lights" -#define WIRE_LIMIT "Limiter" -#define WIRE_LOADCHECK "Load Check" -#define WIRE_LOCKDOWN "Lockdown" -#define WIRE_MOTOR1 "Motor 1" -#define WIRE_MOTOR2 "Motor 2" -#define WIRE_OPEN "Open" -#define WIRE_PANIC "Panic Siphon" -#define WIRE_POWER "Power" -#define WIRE_POWER1 "Main Power 1" -#define WIRE_POWER2 "Main Power 2" -#define WIRE_PROCEED "Proceed" -#define WIRE_RX "Receive" -#define WIRE_RESET_MODULE "Reset Module" -#define WIRE_SAFETY "Safety" -#define WIRE_SHOCK "High Voltage Ground" -#define WIRE_SIGNAL "Signal" -#define WIRE_SPEAKER "Speaker" -#define WIRE_STRENGTH "Strength" -#define WIRE_THROW "Throw" -#define WIRE_TIMING "Timing" -#define WIRE_TX "Transmit" -#define WIRE_UNBOLT "Unbolt" -#define WIRE_ZAP "High Voltage Circuit" -#define WIRE_ZAP1 "High Voltage Circuit 1" -#define WIRE_ZAP2 "High Voltage Circuit 2" +//retvals for attempt_wires_interaction +#define WIRE_INTERACTION_FAIL 0 +#define WIRE_INTERACTION_SUCCESSFUL 1 +#define WIRE_INTERACTION_BLOCK 2 //don't do anything else rather than open wires and whatever else. + +#define WIRE_DUD_PREFIX "__dud" +#define WIRE_ACTIVATE "Activate" +#define WIRE_AI "AI Connection" +#define WIRE_ALARM "Alarm" +#define WIRE_AVOIDANCE "Avoidance" +#define WIRE_BACKUP1 "Auxiliary Power 1" +#define WIRE_BACKUP2 "Auxiliary Power 2" +#define WIRE_BEACON "Beacon" +#define WIRE_BOLTS "Bolts" +#define WIRE_BOOM "Boom" +#define WIRE_CAMERA "Camera" +#define WIRE_CONTRABAND "Contraband" +#define WIRE_DELAY "Delay" +#define WIRE_DISABLE "Disable" +#define WIRE_DISARM "Disarm" +#define WIRE_HACK "Hack" +#define WIRE_IDSCAN "ID Scan" +#define WIRE_INTERFACE "Interface" +#define WIRE_LAWSYNC "AI Law Synchronization" +#define WIRE_LIGHT "Bolt Lights" +#define WIRE_LIMIT "Limiter" +#define WIRE_LOADCHECK "Load Check" +#define WIRE_LOCKDOWN "Lockdown" +#define WIRE_MOTOR1 "Motor 1" +#define WIRE_MOTOR2 "Motor 2" +#define WIRE_OPEN "Open" +#define WIRE_PANIC "Panic Siphon" +#define WIRE_POWER "Power" +#define WIRE_POWER1 "Main Power 1" +#define WIRE_POWER2 "Main Power 2" +#define WIRE_PROCEED "Proceed" +#define WIRE_RX "Receive" +#define WIRE_RESET_MODULE "Reset Module" +#define WIRE_SAFETY "Safety" +#define WIRE_SHOCK "High Voltage Ground" +#define WIRE_SIGNAL "Signal" +#define WIRE_SPEAKER "Speaker" +#define WIRE_STRENGTH "Strength" +#define WIRE_THROW "Throw" +#define WIRE_TIMING "Timing" +#define WIRE_TX "Transmit" +#define WIRE_UNBOLT "Unbolt" +#define WIRE_ZAP "High Voltage Circuit" +#define WIRE_ZAP1 "High Voltage Circuit 1" +#define WIRE_ZAP2 "High Voltage Circuit 2" diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index 3b8b3765ef..8e44b57396 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -1,582 +1,582 @@ -/* - * Holds procs to help with list operations - * Contains groups: - * Misc - * Sorting - */ - -/* - * Misc - */ - -#define LAZYINITLIST(L) if (!L) L = list() -#define UNSETEMPTY(L) if (L && !length(L)) L = null -#define LAZYREMOVE(L, I) if(L) { L -= I; if(!length(L)) { L = null; } } -#define LAZYADD(L, I) if(!L) { L = list(); } L += I; -#define LAZYOR(L, I) if(!L) { L = list(); } L |= I; -#define LAZYFIND(L, V) L ? L.Find(V) : 0 -#define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= length(L) ? L[I] : null) : L[I]) : null) -#define LAZYSET(L, K, V) if(!L) { L = list(); } L[K] = V; -#define LAZYLEN(L) length(L) -#define LAZYCLEARLIST(L) if(L) L.Cut() -#define SANITIZE_LIST(L) ( islist(L) ? L : list() ) -#define reverseList(L) reverseRange(L.Copy()) - -// binary search sorted insert -// IN: Object to be inserted -// LIST: List to insert object into -// TYPECONT: The typepath of the contents of the list -// COMPARE: The variable on the objects to compare -#define BINARY_INSERT(IN, LIST, TYPECONT, COMPARE) \ - var/__BIN_CTTL = length(LIST);\ - if(!__BIN_CTTL) {\ - LIST += IN;\ - } else {\ - var/__BIN_LEFT = 1;\ - var/__BIN_RIGHT = __BIN_CTTL;\ - var/__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ - var/##TYPECONT/__BIN_ITEM;\ - while(__BIN_LEFT < __BIN_RIGHT) {\ - __BIN_ITEM = LIST[__BIN_MID];\ - if(__BIN_ITEM.##COMPARE <= IN.##COMPARE) {\ - __BIN_LEFT = __BIN_MID + 1;\ - } else {\ - __BIN_RIGHT = __BIN_MID;\ - };\ - __BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ - };\ - __BIN_ITEM = LIST[__BIN_MID];\ - __BIN_MID = __BIN_ITEM.##COMPARE > IN.##COMPARE ? __BIN_MID : __BIN_MID + 1;\ - LIST.Insert(__BIN_MID, IN);\ - } - -//Returns a list in plain english as a string -/proc/english_list(list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" ) - var/total = input.len - if (!total) - return "[nothing_text]" - else if (total == 1) - return "[input[1]]" - else if (total == 2) - return "[input[1]][and_text][input[2]]" - else - var/output = "" - var/index = 1 - while (index < total) - if (index == total - 1) - comma_text = final_comma_text - - output += "[input[index]][comma_text]" - index++ - - return "[output][and_text][input[index]]" - -//Returns list element or null. Should prevent "index out of bounds" error. -/proc/listgetindex(list/L, index) - if(LAZYLEN(L)) - if(isnum(index) && ISINTEGER(index)) - if(ISINRANGE(index,1,L.len)) - return L[index] - else if(index in L) - return L[index] - return - -//Return either pick(list) or null if list is not of type /list or is empty -/proc/safepick(list/L) - if(LAZYLEN(L)) - return pick(L) - -//Checks if the list is empty -/proc/isemptylist(list/L) - if(!L.len) - return TRUE - return FALSE - -//Checks for specific types in a list -/proc/is_type_in_list(atom/A, list/L) - if(!LAZYLEN(L) || !A) - return FALSE - for(var/type in L) - if(istype(A, type)) - return TRUE - return FALSE - -//Checks for specific types in specifically structured (Assoc "type" = TRUE) lists ('typecaches') -#define is_type_in_typecache(A, L) (A && length(L) && L[(ispath(A) ? A : A:type)]) - -//Checks for a string in a list -/proc/is_string_in_list(string, list/L) - if(!LAZYLEN(L) || !string) - return - for(var/V in L) - if(string == V) - return TRUE - return - -//Removes a string from a list -/proc/remove_strings_from_list(string, list/L) - if(!LAZYLEN(L) || !string) - return - for(var/V in L) - if(V == string) - L -= V //No return here so that it removes all strings of that type - return - -//returns a new list with only atoms that are in typecache L -/proc/typecache_filter_list(list/atoms, list/typecache) - RETURN_TYPE(/list) - . = list() - for(var/thing in atoms) - var/atom/A = thing - if (typecache[A.type]) - . += A - -/proc/typecache_filter_list_reverse(list/atoms, list/typecache) - RETURN_TYPE(/list) - . = list() - for(var/thing in atoms) - var/atom/A = thing - if(!typecache[A.type]) - . += A - -/proc/typecache_filter_multi_list_exclusion(list/atoms, list/typecache_include, list/typecache_exclude) - . = list() - for(var/thing in atoms) - var/atom/A = thing - if(typecache_include[A.type] && !typecache_exclude[A.type]) - . += A - -//Like typesof() or subtypesof(), but returns a typecache instead of a list -/proc/typecacheof(path, ignore_root_path, only_root_path = FALSE) - if(ispath(path)) - var/list/types = list() - if(only_root_path) - types = list(path) - else - types = ignore_root_path ? subtypesof(path) : typesof(path) - var/list/L = list() - for(var/T in types) - L[T] = TRUE - return L - else if(islist(path)) - var/list/pathlist = path - var/list/L = list() - if(ignore_root_path) - for(var/P in pathlist) - for(var/T in subtypesof(P)) - L[T] = TRUE - else - for(var/P in pathlist) - if(only_root_path) - L[P] = TRUE - else - for(var/T in typesof(P)) - L[T] = TRUE - return L - -//Empties the list by setting the length to 0. Hopefully the elements get garbage collected -/proc/clearlist(list/list) - if(istype(list)) - list.len = 0 - return - -//Removes any null entries from the list -//Returns TRUE if the list had nulls, FALSE otherwise -/proc/listclearnulls(list/L) - var/start_len = L.len - var/list/N = new(start_len) - L -= N - return L.len < start_len - -/* - * Returns list containing all the entries from first list that are not present in second. - * If skiprep = 1, repeated elements are treated as one. - * If either of arguments is not a list, returns null - */ -/proc/difflist(list/first, list/second, skiprep=0) - if(!islist(first) || !islist(second)) - return - var/list/result = new - if(skiprep) - for(var/e in first) - if(!(e in result) && !(e in second)) - result += e - else - result = first - second - return result - -/* - * Returns list containing entries that are in either list but not both. - * If skipref = 1, repeated elements are treated as one. - * If either of arguments is not a list, returns null - */ -/proc/uniquemergelist(list/first, list/second, skiprep=0) - if(!islist(first) || !islist(second)) - return - var/list/result = new - if(skiprep) - result = difflist(first, second, skiprep)+difflist(second, first, skiprep) - else - result = first ^ second - return result - -//Picks a random element from a list based on a weighting system: -//1. Adds up the total of weights for each element -//2. Gets a number between 1 and that total -//3. For each element in the list, subtracts its weighting from that number -//4. If that makes the number 0 or less, return that element. -/proc/pickweight(list/L) - var/total = 0 - var/item - for (item in L) - if (!L[item]) - L[item] = 1 - total += L[item] - - total = rand(1, total) - for (item in L) - total -=L [item] - if (total <= 0) - return item - - return null - -/proc/pickweightAllowZero(list/L) //The original pickweight proc will sometimes pick entries with zero weight. I'm not sure if changing the original will break anything, so I left it be. - var/total = 0 - var/item - for (item in L) - if (!L[item]) - L[item] = 0 - total += L[item] - - total = rand(0, total) - for (item in L) - total -=L [item] - if (total <= 0 && L[item]) - return item - - return null - -//Pick a random element from the list and remove it from the list. -/proc/pick_n_take(list/L) - RETURN_TYPE(L[_].type) - if(L.len) - var/picked = rand(1,L.len) - . = L[picked] - L.Cut(picked,picked+1) //Cut is far more efficient that Remove() - -//Returns the top(last) element from the list and removes it from the list (typical stack function) -/proc/pop(list/L) - if(L.len) - . = L[L.len] - L.len-- - -/proc/popleft(list/L) - if(L.len) - . = L[1] - L.Cut(1,2) - -/proc/sorted_insert(list/L, thing, comparator) - var/pos = L.len - while(pos > 0 && call(comparator)(thing, L[pos]) > 0) - pos-- - L.Insert(pos+1, thing) - -// Returns the next item in a list -/proc/next_list_item(item, list/L) - var/i - i = L.Find(item) - if(i == L.len) - i = 1 - else - i++ - return L[i] - -// Returns the previous item in a list -/proc/previous_list_item(item, list/L) - var/i - i = L.Find(item) - if(i == 1) - i = L.len - else - i-- - return L[i] - -//Randomize: Return the list in a random order -/proc/shuffle(list/L) - if(!L) - return - L = L.Copy() - - for(var/i=1, i= 0 ? /proc/cmp_ckey_asc : /proc/cmp_ckey_dsc) - -//Specifically for record datums in a list. -/proc/sortRecord(list/L, field = "name", order = 1) - GLOB.cmp_field = field - return sortTim(L, order >= 0 ? /proc/cmp_records_asc : /proc/cmp_records_dsc) - -//any value in a list -/proc/sortList(list/L, cmp=/proc/cmp_text_asc) - return sortTim(L.Copy(), cmp) - -//uses sortList() but uses the var's name specifically. This should probably be using mergeAtom() instead -/proc/sortNames(list/L, order=1) - return sortTim(L, order >= 0 ? /proc/cmp_name_asc : /proc/cmp_name_dsc) - - -//Converts a bitfield to a list of numbers (or words if a wordlist is provided) -/proc/bitfield2list(bitfield = 0, list/wordlist) - var/list/r = list() - if(islist(wordlist)) - var/max = min(wordlist.len,16) - var/bit = 1 - for(var/i=1, i<=max, i++) - if(bitfield & bit) - r += wordlist[i] - bit = bit << 1 - else - for(var/bit=1, bit<=65535, bit = bit << 1) - if(bitfield & bit) - r += bit - - return r - -// Returns the key based on the index -#define KEYBYINDEX(L, index) (((index <= length(L)) && (index > 0)) ? L[index] : null) - -/proc/count_by_type(list/L, type) - var/i = 0 - for(var/T in L) - if(istype(T, type)) - i++ - return i - -/proc/count_occurences_of_value(list/L, val, limit) //special thanks to salmonsnake - . = 0 - for (var/i in 1 to limit) - if (L[i] == val) - .++ - -/proc/find_record(field, value, list/L) - for(var/datum/data/record/R in L) - if(R.fields[field] == value) - return R - - -//Move a single element from position fromIndex within a list, to position toIndex -//All elements in the range [1,toIndex) before the move will be before the pivot afterwards -//All elements in the range [toIndex, L.len+1) before the move will be after the pivot afterwards -//In other words, it's as if the range [fromIndex,toIndex) have been rotated using a <<< operation common to other languages. -//fromIndex and toIndex must be in the range [1,L.len+1] -//This will preserve associations ~Carnie -/proc/moveElement(list/L, fromIndex, toIndex) - if(fromIndex == toIndex || fromIndex+1 == toIndex) //no need to move - return - if(fromIndex > toIndex) - ++fromIndex //since a null will be inserted before fromIndex, the index needs to be nudged right by one - - L.Insert(toIndex, null) - L.Swap(fromIndex, toIndex) - L.Cut(fromIndex, fromIndex+1) - - -//Move elements [fromIndex,fromIndex+len) to [toIndex-len, toIndex) -//Same as moveElement but for ranges of elements -//This will preserve associations ~Carnie -/proc/moveRange(list/L, fromIndex, toIndex, len=1) - var/distance = abs(toIndex - fromIndex) - if(len >= distance) //there are more elements to be moved than the distance to be moved. Therefore the same result can be achieved (with fewer operations) by moving elements between where we are and where we are going. The result being, our range we are moving is shifted left or right by dist elements - if(fromIndex <= toIndex) - return //no need to move - fromIndex += len //we want to shift left instead of right - - for(var/i=0, i toIndex) - fromIndex += len - - for(var/i=0, i distance) //there is an overlap, therefore swapping each element will require more swaps than inserting new elements - if(fromIndex < toIndex) - toIndex += len - else - fromIndex += len - - for(var/i=0, i fromIndex) - var/a = toIndex - toIndex = fromIndex - fromIndex = a - - for(var/i=0, i 513 -#error Remie said that lummox was adding a way to get a lists -#error contents via list.values, if that is true remove this -#error otherwise, update the version and bug lummox -#endif -//Flattens a keyed list into a list of it's contents -/proc/flatten_list(list/key_list) - if(!islist(key_list)) - return null - . = list() - for(var/key in key_list) - . |= key_list[key] - -/proc/make_associative(list/flat_list) - . = list() - for(var/thing in flat_list) - .[thing] = TRUE - -//Picks from the list, with some safeties, and returns the "default" arg if it fails -#define DEFAULTPICK(L, default) ((islist(L) && length(L)) ? pick(L) : default) - -/* Definining a counter as a series of key -> numeric value entries - - * All these procs modify in place. -*/ - -/proc/counterlist_scale(list/L, scalar) - var/list/out = list() - for(var/key in L) - out[key] = L[key] * scalar - . = out - -/proc/counterlist_sum(list/L) - . = 0 - for(var/key in L) - . += L[key] - -/proc/counterlist_normalise(list/L) - var/avg = counterlist_sum(L) - if(avg != 0) - . = counterlist_scale(L, 1 / avg) - else - . = L - -/proc/counterlist_combine(list/L1, list/L2) - for(var/key in L2) - var/other_value = L2[key] - if(key in L1) - L1[key] += other_value - else - L1[key] = other_value - -/proc/assoc_list_strip_value(list/input) - var/list/ret = list() - for(var/key in input) - ret += key +/* + * Holds procs to help with list operations + * Contains groups: + * Misc + * Sorting + */ + +/* + * Misc + */ + +#define LAZYINITLIST(L) if (!L) L = list() +#define UNSETEMPTY(L) if (L && !length(L)) L = null +#define LAZYREMOVE(L, I) if(L) { L -= I; if(!length(L)) { L = null; } } +#define LAZYADD(L, I) if(!L) { L = list(); } L += I; +#define LAZYOR(L, I) if(!L) { L = list(); } L |= I; +#define LAZYFIND(L, V) L ? L.Find(V) : 0 +#define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= length(L) ? L[I] : null) : L[I]) : null) +#define LAZYSET(L, K, V) if(!L) { L = list(); } L[K] = V; +#define LAZYLEN(L) length(L) +#define LAZYCLEARLIST(L) if(L) L.Cut() +#define SANITIZE_LIST(L) ( islist(L) ? L : list() ) +#define reverseList(L) reverseRange(L.Copy()) + +// binary search sorted insert +// IN: Object to be inserted +// LIST: List to insert object into +// TYPECONT: The typepath of the contents of the list +// COMPARE: The variable on the objects to compare +#define BINARY_INSERT(IN, LIST, TYPECONT, COMPARE) \ + var/__BIN_CTTL = length(LIST);\ + if(!__BIN_CTTL) {\ + LIST += IN;\ + } else {\ + var/__BIN_LEFT = 1;\ + var/__BIN_RIGHT = __BIN_CTTL;\ + var/__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ + var/##TYPECONT/__BIN_ITEM;\ + while(__BIN_LEFT < __BIN_RIGHT) {\ + __BIN_ITEM = LIST[__BIN_MID];\ + if(__BIN_ITEM.##COMPARE <= IN.##COMPARE) {\ + __BIN_LEFT = __BIN_MID + 1;\ + } else {\ + __BIN_RIGHT = __BIN_MID;\ + };\ + __BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ + };\ + __BIN_ITEM = LIST[__BIN_MID];\ + __BIN_MID = __BIN_ITEM.##COMPARE > IN.##COMPARE ? __BIN_MID : __BIN_MID + 1;\ + LIST.Insert(__BIN_MID, IN);\ + } + +//Returns a list in plain english as a string +/proc/english_list(list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" ) + var/total = input.len + if (!total) + return "[nothing_text]" + else if (total == 1) + return "[input[1]]" + else if (total == 2) + return "[input[1]][and_text][input[2]]" + else + var/output = "" + var/index = 1 + while (index < total) + if (index == total - 1) + comma_text = final_comma_text + + output += "[input[index]][comma_text]" + index++ + + return "[output][and_text][input[index]]" + +//Returns list element or null. Should prevent "index out of bounds" error. +/proc/listgetindex(list/L, index) + if(LAZYLEN(L)) + if(isnum(index) && ISINTEGER(index)) + if(ISINRANGE(index,1,L.len)) + return L[index] + else if(index in L) + return L[index] + return + +//Return either pick(list) or null if list is not of type /list or is empty +/proc/safepick(list/L) + if(LAZYLEN(L)) + return pick(L) + +//Checks if the list is empty +/proc/isemptylist(list/L) + if(!L.len) + return TRUE + return FALSE + +//Checks for specific types in a list +/proc/is_type_in_list(atom/A, list/L) + if(!LAZYLEN(L) || !A) + return FALSE + for(var/type in L) + if(istype(A, type)) + return TRUE + return FALSE + +//Checks for specific types in specifically structured (Assoc "type" = TRUE) lists ('typecaches') +#define is_type_in_typecache(A, L) (A && length(L) && L[(ispath(A) ? A : A:type)]) + +//Checks for a string in a list +/proc/is_string_in_list(string, list/L) + if(!LAZYLEN(L) || !string) + return + for(var/V in L) + if(string == V) + return TRUE + return + +//Removes a string from a list +/proc/remove_strings_from_list(string, list/L) + if(!LAZYLEN(L) || !string) + return + for(var/V in L) + if(V == string) + L -= V //No return here so that it removes all strings of that type + return + +//returns a new list with only atoms that are in typecache L +/proc/typecache_filter_list(list/atoms, list/typecache) + RETURN_TYPE(/list) + . = list() + for(var/thing in atoms) + var/atom/A = thing + if (typecache[A.type]) + . += A + +/proc/typecache_filter_list_reverse(list/atoms, list/typecache) + RETURN_TYPE(/list) + . = list() + for(var/thing in atoms) + var/atom/A = thing + if(!typecache[A.type]) + . += A + +/proc/typecache_filter_multi_list_exclusion(list/atoms, list/typecache_include, list/typecache_exclude) + . = list() + for(var/thing in atoms) + var/atom/A = thing + if(typecache_include[A.type] && !typecache_exclude[A.type]) + . += A + +//Like typesof() or subtypesof(), but returns a typecache instead of a list +/proc/typecacheof(path, ignore_root_path, only_root_path = FALSE) + if(ispath(path)) + var/list/types = list() + if(only_root_path) + types = list(path) + else + types = ignore_root_path ? subtypesof(path) : typesof(path) + var/list/L = list() + for(var/T in types) + L[T] = TRUE + return L + else if(islist(path)) + var/list/pathlist = path + var/list/L = list() + if(ignore_root_path) + for(var/P in pathlist) + for(var/T in subtypesof(P)) + L[T] = TRUE + else + for(var/P in pathlist) + if(only_root_path) + L[P] = TRUE + else + for(var/T in typesof(P)) + L[T] = TRUE + return L + +//Empties the list by setting the length to 0. Hopefully the elements get garbage collected +/proc/clearlist(list/list) + if(istype(list)) + list.len = 0 + return + +//Removes any null entries from the list +//Returns TRUE if the list had nulls, FALSE otherwise +/proc/listclearnulls(list/L) + var/start_len = L.len + var/list/N = new(start_len) + L -= N + return L.len < start_len + +/* + * Returns list containing all the entries from first list that are not present in second. + * If skiprep = 1, repeated elements are treated as one. + * If either of arguments is not a list, returns null + */ +/proc/difflist(list/first, list/second, skiprep=0) + if(!islist(first) || !islist(second)) + return + var/list/result = new + if(skiprep) + for(var/e in first) + if(!(e in result) && !(e in second)) + result += e + else + result = first - second + return result + +/* + * Returns list containing entries that are in either list but not both. + * If skipref = 1, repeated elements are treated as one. + * If either of arguments is not a list, returns null + */ +/proc/uniquemergelist(list/first, list/second, skiprep=0) + if(!islist(first) || !islist(second)) + return + var/list/result = new + if(skiprep) + result = difflist(first, second, skiprep)+difflist(second, first, skiprep) + else + result = first ^ second + return result + +//Picks a random element from a list based on a weighting system: +//1. Adds up the total of weights for each element +//2. Gets a number between 1 and that total +//3. For each element in the list, subtracts its weighting from that number +//4. If that makes the number 0 or less, return that element. +/proc/pickweight(list/L) + var/total = 0 + var/item + for (item in L) + if (!L[item]) + L[item] = 1 + total += L[item] + + total = rand(1, total) + for (item in L) + total -=L [item] + if (total <= 0) + return item + + return null + +/proc/pickweightAllowZero(list/L) //The original pickweight proc will sometimes pick entries with zero weight. I'm not sure if changing the original will break anything, so I left it be. + var/total = 0 + var/item + for (item in L) + if (!L[item]) + L[item] = 0 + total += L[item] + + total = rand(0, total) + for (item in L) + total -=L [item] + if (total <= 0 && L[item]) + return item + + return null + +//Pick a random element from the list and remove it from the list. +/proc/pick_n_take(list/L) + RETURN_TYPE(L[_].type) + if(L.len) + var/picked = rand(1,L.len) + . = L[picked] + L.Cut(picked,picked+1) //Cut is far more efficient that Remove() + +//Returns the top(last) element from the list and removes it from the list (typical stack function) +/proc/pop(list/L) + if(L.len) + . = L[L.len] + L.len-- + +/proc/popleft(list/L) + if(L.len) + . = L[1] + L.Cut(1,2) + +/proc/sorted_insert(list/L, thing, comparator) + var/pos = L.len + while(pos > 0 && call(comparator)(thing, L[pos]) > 0) + pos-- + L.Insert(pos+1, thing) + +// Returns the next item in a list +/proc/next_list_item(item, list/L) + var/i + i = L.Find(item) + if(i == L.len) + i = 1 + else + i++ + return L[i] + +// Returns the previous item in a list +/proc/previous_list_item(item, list/L) + var/i + i = L.Find(item) + if(i == 1) + i = L.len + else + i-- + return L[i] + +//Randomize: Return the list in a random order +/proc/shuffle(list/L) + if(!L) + return + L = L.Copy() + + for(var/i=1, i= 0 ? /proc/cmp_ckey_asc : /proc/cmp_ckey_dsc) + +//Specifically for record datums in a list. +/proc/sortRecord(list/L, field = "name", order = 1) + GLOB.cmp_field = field + return sortTim(L, order >= 0 ? /proc/cmp_records_asc : /proc/cmp_records_dsc) + +//any value in a list +/proc/sortList(list/L, cmp=/proc/cmp_text_asc) + return sortTim(L.Copy(), cmp) + +//uses sortList() but uses the var's name specifically. This should probably be using mergeAtom() instead +/proc/sortNames(list/L, order=1) + return sortTim(L, order >= 0 ? /proc/cmp_name_asc : /proc/cmp_name_dsc) + + +//Converts a bitfield to a list of numbers (or words if a wordlist is provided) +/proc/bitfield2list(bitfield = 0, list/wordlist) + var/list/r = list() + if(islist(wordlist)) + var/max = min(wordlist.len,16) + var/bit = 1 + for(var/i=1, i<=max, i++) + if(bitfield & bit) + r += wordlist[i] + bit = bit << 1 + else + for(var/bit=1, bit<=65535, bit = bit << 1) + if(bitfield & bit) + r += bit + + return r + +// Returns the key based on the index +#define KEYBYINDEX(L, index) (((index <= length(L)) && (index > 0)) ? L[index] : null) + +/proc/count_by_type(list/L, type) + var/i = 0 + for(var/T in L) + if(istype(T, type)) + i++ + return i + +/proc/count_occurences_of_value(list/L, val, limit) //special thanks to salmonsnake + . = 0 + for (var/i in 1 to limit) + if (L[i] == val) + .++ + +/proc/find_record(field, value, list/L) + for(var/datum/data/record/R in L) + if(R.fields[field] == value) + return R + + +//Move a single element from position fromIndex within a list, to position toIndex +//All elements in the range [1,toIndex) before the move will be before the pivot afterwards +//All elements in the range [toIndex, L.len+1) before the move will be after the pivot afterwards +//In other words, it's as if the range [fromIndex,toIndex) have been rotated using a <<< operation common to other languages. +//fromIndex and toIndex must be in the range [1,L.len+1] +//This will preserve associations ~Carnie +/proc/moveElement(list/L, fromIndex, toIndex) + if(fromIndex == toIndex || fromIndex+1 == toIndex) //no need to move + return + if(fromIndex > toIndex) + ++fromIndex //since a null will be inserted before fromIndex, the index needs to be nudged right by one + + L.Insert(toIndex, null) + L.Swap(fromIndex, toIndex) + L.Cut(fromIndex, fromIndex+1) + + +//Move elements [fromIndex,fromIndex+len) to [toIndex-len, toIndex) +//Same as moveElement but for ranges of elements +//This will preserve associations ~Carnie +/proc/moveRange(list/L, fromIndex, toIndex, len=1) + var/distance = abs(toIndex - fromIndex) + if(len >= distance) //there are more elements to be moved than the distance to be moved. Therefore the same result can be achieved (with fewer operations) by moving elements between where we are and where we are going. The result being, our range we are moving is shifted left or right by dist elements + if(fromIndex <= toIndex) + return //no need to move + fromIndex += len //we want to shift left instead of right + + for(var/i=0, i toIndex) + fromIndex += len + + for(var/i=0, i distance) //there is an overlap, therefore swapping each element will require more swaps than inserting new elements + if(fromIndex < toIndex) + toIndex += len + else + fromIndex += len + + for(var/i=0, i fromIndex) + var/a = toIndex + toIndex = fromIndex + fromIndex = a + + for(var/i=0, i 513 +#error Remie said that lummox was adding a way to get a lists +#error contents via list.values, if that is true remove this +#error otherwise, update the version and bug lummox +#endif +//Flattens a keyed list into a list of it's contents +/proc/flatten_list(list/key_list) + if(!islist(key_list)) + return null + . = list() + for(var/key in key_list) + . |= key_list[key] + +/proc/make_associative(list/flat_list) + . = list() + for(var/thing in flat_list) + .[thing] = TRUE + +//Picks from the list, with some safeties, and returns the "default" arg if it fails +#define DEFAULTPICK(L, default) ((islist(L) && length(L)) ? pick(L) : default) + +/* Definining a counter as a series of key -> numeric value entries + + * All these procs modify in place. +*/ + +/proc/counterlist_scale(list/L, scalar) + var/list/out = list() + for(var/key in L) + out[key] = L[key] * scalar + . = out + +/proc/counterlist_sum(list/L) + . = 0 + for(var/key in L) + . += L[key] + +/proc/counterlist_normalise(list/L) + var/avg = counterlist_sum(L) + if(avg != 0) + . = counterlist_scale(L, 1 / avg) + else + . = L + +/proc/counterlist_combine(list/L1, list/L2) + for(var/key in L2) + var/other_value = L2[key] + if(key in L1) + L1[key] += other_value + else + L1[key] = other_value + +/proc/assoc_list_strip_value(list/input) + var/list/ret = list() + for(var/key in input) + ret += key return ret \ No newline at end of file diff --git a/code/__HELPERS/files.dm b/code/__HELPERS/files.dm index 5271b407a5..4160c1976a 100644 --- a/code/__HELPERS/files.dm +++ b/code/__HELPERS/files.dm @@ -1,73 +1,73 @@ -//Sends resource files to client cache -/client/proc/getFiles() - for(var/file in args) - src << browse_rsc(file) - -/client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list("txt","log","htm", "html", "md")) - var/path = root - - for(var/i=0, iError: browse_files(): File not found/Invalid file([path]).") - return - - return path - -#define FTPDELAY 200 //200 tick delay to discourage spam -#define ADMIN_FTPDELAY_MODIFIER 0.5 //Admins get to spam files faster since we ~trust~ them! -/* This proc is a failsafe to prevent spamming of file requests. - It is just a timer that only permits a download every [FTPDELAY] ticks. - This can be changed by modifying FTPDELAY's value above. - - PLEASE USE RESPONSIBLY, Some log files can reach sizes of 4MB! */ -/client/proc/file_spam_check() - var/time_to_wait = GLOB.fileaccess_timer - world.time - if(time_to_wait > 0) - to_chat(src, "Error: file_spam_check(): Spam. Please wait [DisplayTimeText(time_to_wait)].") - return 1 - var/delay = FTPDELAY - if(holder) - delay *= ADMIN_FTPDELAY_MODIFIER - GLOB.fileaccess_timer = world.time + delay - return 0 -#undef FTPDELAY -#undef ADMIN_FTPDELAY_MODIFIER - -/proc/pathwalk(path) - var/list/jobs = list(path) - var/list/filenames = list() - - while(jobs.len) - var/current_dir = pop(jobs) - var/list/new_filenames = flist(current_dir) - for(var/new_filename in new_filenames) - // if filename ends in / it is a directory, append to currdir - if(findtext(new_filename, "/", -1)) - jobs += current_dir + new_filename - else - filenames += current_dir + new_filename - return filenames - -/proc/pathflatten(path) - return replacetext(path, "/", "_") +//Sends resource files to client cache +/client/proc/getFiles() + for(var/file in args) + src << browse_rsc(file) + +/client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list("txt","log","htm", "html", "md")) + var/path = root + + for(var/i=0, iError: browse_files(): File not found/Invalid file([path]).") + return + + return path + +#define FTPDELAY 200 //200 tick delay to discourage spam +#define ADMIN_FTPDELAY_MODIFIER 0.5 //Admins get to spam files faster since we ~trust~ them! +/* This proc is a failsafe to prevent spamming of file requests. + It is just a timer that only permits a download every [FTPDELAY] ticks. + This can be changed by modifying FTPDELAY's value above. + + PLEASE USE RESPONSIBLY, Some log files can reach sizes of 4MB! */ +/client/proc/file_spam_check() + var/time_to_wait = GLOB.fileaccess_timer - world.time + if(time_to_wait > 0) + to_chat(src, "Error: file_spam_check(): Spam. Please wait [DisplayTimeText(time_to_wait)].") + return 1 + var/delay = FTPDELAY + if(holder) + delay *= ADMIN_FTPDELAY_MODIFIER + GLOB.fileaccess_timer = world.time + delay + return 0 +#undef FTPDELAY +#undef ADMIN_FTPDELAY_MODIFIER + +/proc/pathwalk(path) + var/list/jobs = list(path) + var/list/filenames = list() + + while(jobs.len) + var/current_dir = pop(jobs) + var/list/new_filenames = flist(current_dir) + for(var/new_filename in new_filenames) + // if filename ends in / it is a directory, append to currdir + if(findtext(new_filename, "/", -1)) + jobs += current_dir + new_filename + else + filenames += current_dir + new_filename + return filenames + +/proc/pathflatten(path) + return replacetext(path, "/", "_") diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 65c7145d8f..ca4b913369 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -1,570 +1,570 @@ -//supposedly the fastest way to do this according to https://gist.github.com/Giacom/be635398926bb463b42a -#define RANGE_TURFS(RADIUS, CENTER) \ - block( \ - locate(max(CENTER.x-(RADIUS),1), max(CENTER.y-(RADIUS),1), CENTER.z), \ - locate(min(CENTER.x+(RADIUS),world.maxx), min(CENTER.y+(RADIUS),world.maxy), CENTER.z) \ - ) - -#define Z_TURFS(ZLEVEL) block(locate(1,1,ZLEVEL), locate(world.maxx, world.maxy, ZLEVEL)) -#define CULT_POLL_WAIT 2400 - -/proc/get_area_name(atom/X, format_text = FALSE) - var/area/A = isarea(X) ? X : get_area(X) - if(!A) - return null - return format_text ? format_text(A.name) : A.name - -/proc/get_areas_in_range(dist=0, atom/center=usr) - if(!dist) - var/turf/T = get_turf(center) - return T ? list(T.loc) : list() - if(!center) - return list() - - var/list/turfs = RANGE_TURFS(dist, center) - var/list/areas = list() - for(var/V in turfs) - var/turf/T = V - areas |= T.loc - return areas - -/proc/get_adjacent_areas(atom/center) - . = list(get_area(get_ranged_target_turf(center, NORTH, 1)), - get_area(get_ranged_target_turf(center, SOUTH, 1)), - get_area(get_ranged_target_turf(center, EAST, 1)), - get_area(get_ranged_target_turf(center, WEST, 1))) - listclearnulls(.) - -/proc/get_open_turf_in_dir(atom/center, dir) - var/turf/open/T = get_ranged_target_turf(center, dir, 1) - if(istype(T)) - return T - -/proc/get_adjacent_open_turfs(atom/center) - . = list(get_open_turf_in_dir(center, NORTH), - get_open_turf_in_dir(center, SOUTH), - get_open_turf_in_dir(center, EAST), - get_open_turf_in_dir(center, WEST)) - listclearnulls(.) - -/proc/get_adjacent_open_areas(atom/center) - . = list() - var/list/adjacent_turfs = get_adjacent_open_turfs(center) - for(var/I in adjacent_turfs) - . |= get_area(I) - -// Like view but bypasses luminosity check - -/proc/get_hear(range, atom/source) - - var/lum = source.luminosity - source.luminosity = 6 - - var/list/heard = view(range, source) - source.luminosity = lum - - return heard - -/proc/alone_in_area(area/the_area, mob/must_be_alone, check_type = /mob/living/carbon) - var/area/our_area = get_area(the_area) - for(var/C in GLOB.alive_mob_list) - if(!istype(C, check_type)) - continue - if(C == must_be_alone) - continue - if(our_area == get_area(C)) - return 0 - return 1 - -//We used to use linear regression to approximate the answer, but Mloc realized this was actually faster. -//And lo and behold, it is, and it's more accurate to boot. -/proc/cheap_hypotenuse(Ax,Ay,Bx,By) - return sqrt(abs(Ax - Bx)**2 + abs(Ay - By)**2) //A squared + B squared = C squared - -/proc/circlerange(center=usr,radius=3) - - var/turf/centerturf = get_turf(center) - var/list/turfs = new/list() - var/rsq = radius * (radius+0.5) - - for(var/atom/T in range(radius, centerturf)) - var/dx = T.x - centerturf.x - var/dy = T.y - centerturf.y - if(dx*dx + dy*dy <= rsq) - turfs += T - - //turfs += centerturf - return turfs - -/proc/circleview(center=usr,radius=3) - - var/turf/centerturf = get_turf(center) - var/list/atoms = new/list() - var/rsq = radius * (radius+0.5) - - for(var/atom/A in view(radius, centerturf)) - var/dx = A.x - centerturf.x - var/dy = A.y - centerturf.y - if(dx*dx + dy*dy <= rsq) - atoms += A - - //turfs += centerturf - return atoms - -/proc/get_dist_euclidian(atom/Loc1 as turf|mob|obj,atom/Loc2 as turf|mob|obj) - var/dx = Loc1.x - Loc2.x - var/dy = Loc1.y - Loc2.y - - var/dist = sqrt(dx**2 + dy**2) - - return dist - -/proc/circlerangeturfs(center=usr,radius=3) - - var/turf/centerturf = get_turf(center) - var/list/turfs = new/list() - var/rsq = radius * (radius+0.5) - - for(var/turf/T in range(radius, centerturf)) - var/dx = T.x - centerturf.x - var/dy = T.y - centerturf.y - if(dx*dx + dy*dy <= rsq) - turfs += T - return turfs - -/proc/circleviewturfs(center=usr,radius=3) //Is there even a diffrence between this proc and circlerangeturfs()? - - var/turf/centerturf = get_turf(center) - var/list/turfs = new/list() - var/rsq = radius * (radius+0.5) - - for(var/turf/T in view(radius, centerturf)) - var/dx = T.x - centerturf.x - var/dy = T.y - centerturf.y - if(dx*dx + dy*dy <= rsq) - turfs += T - return turfs - - -//This is the new version of recursive_mob_check, used for say(). -//The other proc was left intact because morgue trays use it. -//Sped this up again for real this time -/proc/recursive_hear_check(O) - var/list/processing_list = list(O) - . = list() - while(processing_list.len) - var/atom/A = processing_list[1] - if(A.flags_1 & HEAR_1) - . += A - processing_list.Cut(1, 2) - processing_list += A.contents - -/** recursive_organ_check - * inputs: O (object to start with) - * outputs: - * description: A pseudo-recursive loop based off of the recursive mob check, this check looks for any organs held - * within 'O', toggling their frozen flag. This check excludes items held within other safe organ - * storage units, so that only the lowest level of container dictates whether we do or don't decompose - */ -/proc/recursive_organ_check(atom/O) - - var/list/processing_list = list(O) - var/list/processed_list = list() - var/index = 1 - var/obj/item/organ/found_organ - - while(index <= length(processing_list)) - - var/atom/A = processing_list[index] - - if(istype(A, /obj/item/organ)) - found_organ = A - found_organ.organ_flags ^= ORGAN_FROZEN - - else if(istype(A, /mob/living/carbon)) - var/mob/living/carbon/Q = A - for(var/organ in Q.internal_organs) - found_organ = organ - found_organ.organ_flags ^= ORGAN_FROZEN - - for(var/atom/B in A) //objects held within other objects are added to the processing list, unless that object is something that can hold organs safely - if(!processed_list[B] && !istype(B, /obj/structure/closet/crate/freezer) && !istype(B, /obj/structure/closet/secure_closet/freezer)) - processing_list+= B - - index++ - processed_list[A] = A - - return - - -// Better recursive loop, technically sort of not actually recursive cause that shit is retarded, enjoy. -//No need for a recursive limit either -/proc/recursive_mob_check(atom/O,client_check=1,sight_check=1,include_radio=1) - - var/list/processing_list = list(O) - var/list/processed_list = list() - var/list/found_mobs = list() - - while(processing_list.len) - - var/atom/A = processing_list[1] - var/passed = 0 - - if(ismob(A)) - var/mob/A_tmp = A - passed=1 - - if(client_check && !A_tmp.client) - passed=0 - - if(sight_check && !isInSight(A_tmp, O)) - passed=0 - - else if(include_radio && istype(A, /obj/item/radio)) - passed=1 - - if(sight_check && !isInSight(A, O)) - passed=0 - - if(passed) - found_mobs |= A - - for(var/atom/B in A) - if(!processed_list[B]) - processing_list |= B - - processing_list.Cut(1, 2) - processed_list[A] = A - - return found_mobs - - -/proc/get_hearers_in_view(R, atom/source) - // Returns a list of hearers in view(R) from source (ignoring luminosity). Used in saycode. - var/turf/T = get_turf(source) - . = list() - - if(!T) - return - - var/list/processing_list = list() - if (R == 0) // if the range is zero, we know exactly where to look for, we can skip view - processing_list += T.contents // We can shave off one iteration by assuming turfs cannot hear - else // A variation of get_hear inlined here to take advantage of the compiler's fastpath for obj/mob in view - var/lum = T.luminosity - T.luminosity = 6 // This is the maximum luminosity - var/list/cachedview = view(R, T) - for(var/mob/M in cachedview) - processing_list += M - for(var/obj/O in cachedview) - processing_list += O - T.luminosity = lum - - while(processing_list.len) // recursive_hear_check inlined here - var/atom/A = processing_list[1] - if(A.flags_1 & HEAR_1) - . += A - SEND_SIGNAL(A, COMSIG_ATOM_HEARER_IN_VIEW, processing_list, .) - processing_list.Cut(1, 2) - processing_list += A.contents - -/proc/get_mobs_in_radio_ranges(list/obj/item/radio/radios) - . = list() - // Returns a list of mobs who can hear any of the radios given in @radios - for(var/obj/item/radio/R in radios) - if(R) - . |= get_hearers_in_view(R.canhear_range, R) - - -#define SIGNV(X) ((X<0)?-1:1) - -/proc/inLineOfSight(X1,Y1,X2,Y2,Z=1,PX1=16.5,PY1=16.5,PX2=16.5,PY2=16.5) - var/turf/T - if(X1==X2) - if(Y1==Y2) - return 1 //Light cannot be blocked on same tile - else - var/s = SIGN(Y2-Y1) - Y1+=s - while(Y1!=Y2) - T=locate(X1,Y1,Z) - if(T.opacity) - return 0 - Y1+=s - else - var/m=(32*(Y2-Y1)+(PY2-PY1))/(32*(X2-X1)+(PX2-PX1)) - var/b=(Y1+PY1/32-0.015625)-m*(X1+PX1/32-0.015625) //In tiles - var/signX = SIGN(X2-X1) - var/signY = SIGN(Y2-Y1) - if(X1 abs (dx)) //slope is above 1:1 (move horizontally in a tie) - if(dy > 0) - return get_step(start, SOUTH) - else - return get_step(start, NORTH) - else - if(dx > 0) - return get_step(start, WEST) - else - return get_step(start, EAST) - - -/proc/try_move_adjacent(atom/movable/AM) - var/turf/T = get_turf(AM) - for(var/direction in GLOB.cardinals) - if(AM.Move(get_step(T, direction))) - break - -/proc/get_mob_by_key(key) - var/ckey = ckey(key) - for(var/i in GLOB.player_list) - var/mob/M = i - if(M.ckey == ckey) - return M - return null - -/proc/considered_alive(datum/mind/M, enforce_human = TRUE) - if(M && M.current) - if(enforce_human) - var/mob/living/carbon/human/H - if(ishuman(M.current)) - H = M.current - return M.current.stat != DEAD && !issilicon(M.current) && !isbrain(M.current) && (!H || H.dna.species.id != "memezombies") - else if(isliving(M.current)) - return M.current.stat != DEAD - return FALSE - -/proc/considered_afk(datum/mind/M) - return !M || !M.current || !M.current.client || M.current.client.is_afk() - -/proc/ScreenText(obj/O, maptext="", screen_loc="CENTER-7,CENTER-7", maptext_height=480, maptext_width=480) - if(!isobj(O)) - O = new /obj/screen/text() - O.maptext = maptext - O.maptext_height = maptext_height - O.maptext_width = maptext_width - O.screen_loc = screen_loc - return O - -/proc/remove_images_from_clients(image/I, list/show_to) - for(var/client/C in show_to) - C.images -= I - -/proc/flick_overlay(image/I, list/show_to, duration) - for(var/client/C in show_to) - C.images += I - addtimer(CALLBACK(GLOBAL_PROC, /proc/remove_images_from_clients, I, show_to), duration, TIMER_CLIENT_TIME) - -/proc/flick_overlay_view(image/I, atom/target, duration) //wrapper for the above, flicks to everyone who can see the target atom - var/list/viewing = list() - for(var/m in viewers(target)) - var/mob/M = m - if(M.client) - viewing += M.client - flick_overlay(I, viewing, duration) - -/proc/get_active_player_count(var/alive_check = 0, var/afk_check = 0, var/human_check = 0) - // Get active players who are playing in the round - var/active_players = 0 - for(var/i = 1; i <= GLOB.player_list.len; i++) - var/mob/M = GLOB.player_list[i] - if(M && M.client) - if(alive_check && M.stat) - continue - else if(afk_check && M.client.is_afk()) - continue - else if(human_check && !ishuman(M)) - continue - else if(isnewplayer(M)) // exclude people in the lobby - continue - else if(isobserver(M)) // Ghosts are fine if they were playing once (didn't start as observers) - var/mob/dead/observer/O = M - if(O.started_as_observer) // Exclude people who started as observers - continue - active_players++ - return active_players - -/proc/showCandidatePollWindow(mob/M, poll_time, Question, list/candidates, ignore_category, time_passed, flashwindow = TRUE) - set waitfor = 0 - - SEND_SOUND(M, 'sound/misc/notice2.ogg') //Alerting them to their consideration - if(flashwindow) - window_flash(M.client) - switch(ignore_category ? askuser(M,Question,"Please answer in [DisplayTimeText(poll_time)]!","Yes","No","Never for this round", StealFocus=0, Timeout=poll_time) : askuser(M,Question,"Please answer in [DisplayTimeText(poll_time)]!","Yes","No", StealFocus=0, Timeout=poll_time)) - if(1) - to_chat(M, "Choice registered: Yes.") - if(time_passed + poll_time <= world.time) - to_chat(M, "Sorry, you answered too late to be considered!") - SEND_SOUND(M, 'sound/machines/buzz-sigh.ogg') - candidates -= M - else - candidates += M - if(2) - to_chat(M, "Choice registered: No.") - candidates -= M - if(3) - var/list/L = GLOB.poll_ignore[ignore_category] - if(!L) - GLOB.poll_ignore[ignore_category] = list() - GLOB.poll_ignore[ignore_category] += M.ckey - to_chat(M, "Choice registered: Never for this round.") - candidates -= M - else - candidates -= M - -/proc/pollGhostCandidates(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE) - var/datum/element/ghost_role_eligibility/eligibility = SSdcs.GetElement(/datum/element/ghost_role_eligibility) - var/list/candidates = eligibility.get_all_ghost_role_eligible() - return pollCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category, flashwindow, candidates) - -/proc/pollCandidates(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE, list/group = null) - var/time_passed = world.time - if (!Question) - Question = "Would you like to be a special role?" - var/list/result = list() - for(var/m in group) - var/mob/M = m - if(!M.key || !M.client || (ignore_category && GLOB.poll_ignore[ignore_category] && M.ckey in GLOB.poll_ignore[ignore_category])) - continue - if(be_special_flag) - if(!(M.client.prefs) || !(be_special_flag in M.client.prefs.be_special)) - continue - if(gametypeCheck) - if(!gametypeCheck.age_check(M.client)) - continue - if(jobbanType) - if(jobban_isbanned(M, jobbanType) || QDELETED(M) || jobban_isbanned(M, ROLE_SYNDICATE) || QDELETED(M)) - continue - - showCandidatePollWindow(M, poll_time, Question, result, ignore_category, time_passed, flashwindow) - sleep(poll_time) - - //Check all our candidates, to make sure they didn't log off or get deleted during the wait period. - for(var/mob/M in result) - if(!M.key || !M.client) - result -= M - - listclearnulls(result) - - return result - -/proc/pollCandidatesForMob(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, mob/M, ignore_category = null) - var/list/L = pollGhostCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category) - if(!M || QDELETED(M) || !M.loc) - return list() - return L - -/proc/pollCandidatesForMobs(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, list/mobs, ignore_category = null) - var/list/L = pollGhostCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category) - var/i=1 - for(var/v in mobs) - var/atom/A = v - if(!A || QDELETED(A) || !A.loc) - mobs.Cut(i,i+1) - else - ++i - return L - -/proc/poll_helper(var/mob/living/M) - -/proc/makeBody(mob/dead/observer/G_found) // Uses stripped down and bastardized code from respawn character - if(!G_found || !G_found.key) - return - - //First we spawn a dude. - var/mob/living/carbon/human/new_character = new//The mob being spawned. - SSjob.SendToLateJoin(new_character) - - G_found.client.prefs.copy_to(new_character) - new_character.dna.update_dna_identity() - G_found.transfer_ckey(new_character, FALSE) - - return new_character - -/proc/send_to_playing_players(thing) //sends a whatever to all playing players; use instead of to_chat(world, where needed) - for(var/M in GLOB.player_list) - if(M && !isnewplayer(M)) - to_chat(M, thing) - -/proc/window_flash(client/C, ignorepref = FALSE) - if(ismob(C)) - var/mob/M = C - if(M.client) - C = M.client - if(!C || (!C.prefs.windowflashing && !ignorepref)) - return - winset(C, "mainwindow", "flash=5") - -/proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank) - if(!SSticker.IsRoundInProgress() || QDELETED(character)) - return - var/area/A = get_area(character) - var/message = "\ - [character.real_name] ([rank]) has arrived at the station at \ - [A.name]." - deadchat_broadcast(message, follow_target = character, message_type=DEADCHAT_ARRIVALRATTLE) - if((!GLOB.announcement_systems.len) || (!character.mind)) - return - if((character.mind.assigned_role == "Cyborg") || (character.mind.assigned_role == character.mind.special_role)) - return - - var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems) - announcer.announce("ARRIVAL", character.real_name, rank, list()) //make the list empty to make it announce it in common - -/proc/GetHexColors(const/hexa) - return list( - GetRedPart(hexa)/ 255, - GetGreenPart(hexa)/ 255, - GetBluePart(hexa)/ 255 - ) - -/proc/GetRedPart(const/hexa) - return hex2num(copytext(hexa, 2, 4)) - -/proc/GetGreenPart(const/hexa) - return hex2num(copytext(hexa, 4, 6)) - -/proc/GetBluePart(const/hexa) - return hex2num(copytext(hexa, 6, 8)) - -/proc/lavaland_equipment_pressure_check(turf/T) - . = FALSE - if(!istype(T)) - return - var/datum/gas_mixture/environment = T.return_air() - if(!istype(environment)) - return - var/pressure = environment.return_pressure() - if(pressure <= LAVALAND_EQUIPMENT_EFFECT_PRESSURE) - . = TRUE +//supposedly the fastest way to do this according to https://gist.github.com/Giacom/be635398926bb463b42a +#define RANGE_TURFS(RADIUS, CENTER) \ + block( \ + locate(max(CENTER.x-(RADIUS),1), max(CENTER.y-(RADIUS),1), CENTER.z), \ + locate(min(CENTER.x+(RADIUS),world.maxx), min(CENTER.y+(RADIUS),world.maxy), CENTER.z) \ + ) + +#define Z_TURFS(ZLEVEL) block(locate(1,1,ZLEVEL), locate(world.maxx, world.maxy, ZLEVEL)) +#define CULT_POLL_WAIT 2400 + +/proc/get_area_name(atom/X, format_text = FALSE) + var/area/A = isarea(X) ? X : get_area(X) + if(!A) + return null + return format_text ? format_text(A.name) : A.name + +/proc/get_areas_in_range(dist=0, atom/center=usr) + if(!dist) + var/turf/T = get_turf(center) + return T ? list(T.loc) : list() + if(!center) + return list() + + var/list/turfs = RANGE_TURFS(dist, center) + var/list/areas = list() + for(var/V in turfs) + var/turf/T = V + areas |= T.loc + return areas + +/proc/get_adjacent_areas(atom/center) + . = list(get_area(get_ranged_target_turf(center, NORTH, 1)), + get_area(get_ranged_target_turf(center, SOUTH, 1)), + get_area(get_ranged_target_turf(center, EAST, 1)), + get_area(get_ranged_target_turf(center, WEST, 1))) + listclearnulls(.) + +/proc/get_open_turf_in_dir(atom/center, dir) + var/turf/open/T = get_ranged_target_turf(center, dir, 1) + if(istype(T)) + return T + +/proc/get_adjacent_open_turfs(atom/center) + . = list(get_open_turf_in_dir(center, NORTH), + get_open_turf_in_dir(center, SOUTH), + get_open_turf_in_dir(center, EAST), + get_open_turf_in_dir(center, WEST)) + listclearnulls(.) + +/proc/get_adjacent_open_areas(atom/center) + . = list() + var/list/adjacent_turfs = get_adjacent_open_turfs(center) + for(var/I in adjacent_turfs) + . |= get_area(I) + +// Like view but bypasses luminosity check + +/proc/get_hear(range, atom/source) + + var/lum = source.luminosity + source.luminosity = 6 + + var/list/heard = view(range, source) + source.luminosity = lum + + return heard + +/proc/alone_in_area(area/the_area, mob/must_be_alone, check_type = /mob/living/carbon) + var/area/our_area = get_area(the_area) + for(var/C in GLOB.alive_mob_list) + if(!istype(C, check_type)) + continue + if(C == must_be_alone) + continue + if(our_area == get_area(C)) + return 0 + return 1 + +//We used to use linear regression to approximate the answer, but Mloc realized this was actually faster. +//And lo and behold, it is, and it's more accurate to boot. +/proc/cheap_hypotenuse(Ax,Ay,Bx,By) + return sqrt(abs(Ax - Bx)**2 + abs(Ay - By)**2) //A squared + B squared = C squared + +/proc/circlerange(center=usr,radius=3) + + var/turf/centerturf = get_turf(center) + var/list/turfs = new/list() + var/rsq = radius * (radius+0.5) + + for(var/atom/T in range(radius, centerturf)) + var/dx = T.x - centerturf.x + var/dy = T.y - centerturf.y + if(dx*dx + dy*dy <= rsq) + turfs += T + + //turfs += centerturf + return turfs + +/proc/circleview(center=usr,radius=3) + + var/turf/centerturf = get_turf(center) + var/list/atoms = new/list() + var/rsq = radius * (radius+0.5) + + for(var/atom/A in view(radius, centerturf)) + var/dx = A.x - centerturf.x + var/dy = A.y - centerturf.y + if(dx*dx + dy*dy <= rsq) + atoms += A + + //turfs += centerturf + return atoms + +/proc/get_dist_euclidian(atom/Loc1 as turf|mob|obj,atom/Loc2 as turf|mob|obj) + var/dx = Loc1.x - Loc2.x + var/dy = Loc1.y - Loc2.y + + var/dist = sqrt(dx**2 + dy**2) + + return dist + +/proc/circlerangeturfs(center=usr,radius=3) + + var/turf/centerturf = get_turf(center) + var/list/turfs = new/list() + var/rsq = radius * (radius+0.5) + + for(var/turf/T in range(radius, centerturf)) + var/dx = T.x - centerturf.x + var/dy = T.y - centerturf.y + if(dx*dx + dy*dy <= rsq) + turfs += T + return turfs + +/proc/circleviewturfs(center=usr,radius=3) //Is there even a diffrence between this proc and circlerangeturfs()? + + var/turf/centerturf = get_turf(center) + var/list/turfs = new/list() + var/rsq = radius * (radius+0.5) + + for(var/turf/T in view(radius, centerturf)) + var/dx = T.x - centerturf.x + var/dy = T.y - centerturf.y + if(dx*dx + dy*dy <= rsq) + turfs += T + return turfs + + +//This is the new version of recursive_mob_check, used for say(). +//The other proc was left intact because morgue trays use it. +//Sped this up again for real this time +/proc/recursive_hear_check(O) + var/list/processing_list = list(O) + . = list() + while(processing_list.len) + var/atom/A = processing_list[1] + if(A.flags_1 & HEAR_1) + . += A + processing_list.Cut(1, 2) + processing_list += A.contents + +/** recursive_organ_check + * inputs: O (object to start with) + * outputs: + * description: A pseudo-recursive loop based off of the recursive mob check, this check looks for any organs held + * within 'O', toggling their frozen flag. This check excludes items held within other safe organ + * storage units, so that only the lowest level of container dictates whether we do or don't decompose + */ +/proc/recursive_organ_check(atom/O) + + var/list/processing_list = list(O) + var/list/processed_list = list() + var/index = 1 + var/obj/item/organ/found_organ + + while(index <= length(processing_list)) + + var/atom/A = processing_list[index] + + if(istype(A, /obj/item/organ)) + found_organ = A + found_organ.organ_flags ^= ORGAN_FROZEN + + else if(istype(A, /mob/living/carbon)) + var/mob/living/carbon/Q = A + for(var/organ in Q.internal_organs) + found_organ = organ + found_organ.organ_flags ^= ORGAN_FROZEN + + for(var/atom/B in A) //objects held within other objects are added to the processing list, unless that object is something that can hold organs safely + if(!processed_list[B] && !istype(B, /obj/structure/closet/crate/freezer) && !istype(B, /obj/structure/closet/secure_closet/freezer)) + processing_list+= B + + index++ + processed_list[A] = A + + return + + +// Better recursive loop, technically sort of not actually recursive cause that shit is retarded, enjoy. +//No need for a recursive limit either +/proc/recursive_mob_check(atom/O,client_check=1,sight_check=1,include_radio=1) + + var/list/processing_list = list(O) + var/list/processed_list = list() + var/list/found_mobs = list() + + while(processing_list.len) + + var/atom/A = processing_list[1] + var/passed = 0 + + if(ismob(A)) + var/mob/A_tmp = A + passed=1 + + if(client_check && !A_tmp.client) + passed=0 + + if(sight_check && !isInSight(A_tmp, O)) + passed=0 + + else if(include_radio && istype(A, /obj/item/radio)) + passed=1 + + if(sight_check && !isInSight(A, O)) + passed=0 + + if(passed) + found_mobs |= A + + for(var/atom/B in A) + if(!processed_list[B]) + processing_list |= B + + processing_list.Cut(1, 2) + processed_list[A] = A + + return found_mobs + + +/proc/get_hearers_in_view(R, atom/source) + // Returns a list of hearers in view(R) from source (ignoring luminosity). Used in saycode. + var/turf/T = get_turf(source) + . = list() + + if(!T) + return + + var/list/processing_list = list() + if (R == 0) // if the range is zero, we know exactly where to look for, we can skip view + processing_list += T.contents // We can shave off one iteration by assuming turfs cannot hear + else // A variation of get_hear inlined here to take advantage of the compiler's fastpath for obj/mob in view + var/lum = T.luminosity + T.luminosity = 6 // This is the maximum luminosity + var/list/cachedview = view(R, T) + for(var/mob/M in cachedview) + processing_list += M + for(var/obj/O in cachedview) + processing_list += O + T.luminosity = lum + + while(processing_list.len) // recursive_hear_check inlined here + var/atom/A = processing_list[1] + if(A.flags_1 & HEAR_1) + . += A + SEND_SIGNAL(A, COMSIG_ATOM_HEARER_IN_VIEW, processing_list, .) + processing_list.Cut(1, 2) + processing_list += A.contents + +/proc/get_mobs_in_radio_ranges(list/obj/item/radio/radios) + . = list() + // Returns a list of mobs who can hear any of the radios given in @radios + for(var/obj/item/radio/R in radios) + if(R) + . |= get_hearers_in_view(R.canhear_range, R) + + +#define SIGNV(X) ((X<0)?-1:1) + +/proc/inLineOfSight(X1,Y1,X2,Y2,Z=1,PX1=16.5,PY1=16.5,PX2=16.5,PY2=16.5) + var/turf/T + if(X1==X2) + if(Y1==Y2) + return 1 //Light cannot be blocked on same tile + else + var/s = SIGN(Y2-Y1) + Y1+=s + while(Y1!=Y2) + T=locate(X1,Y1,Z) + if(T.opacity) + return 0 + Y1+=s + else + var/m=(32*(Y2-Y1)+(PY2-PY1))/(32*(X2-X1)+(PX2-PX1)) + var/b=(Y1+PY1/32-0.015625)-m*(X1+PX1/32-0.015625) //In tiles + var/signX = SIGN(X2-X1) + var/signY = SIGN(Y2-Y1) + if(X1 abs (dx)) //slope is above 1:1 (move horizontally in a tie) + if(dy > 0) + return get_step(start, SOUTH) + else + return get_step(start, NORTH) + else + if(dx > 0) + return get_step(start, WEST) + else + return get_step(start, EAST) + + +/proc/try_move_adjacent(atom/movable/AM) + var/turf/T = get_turf(AM) + for(var/direction in GLOB.cardinals) + if(AM.Move(get_step(T, direction))) + break + +/proc/get_mob_by_key(key) + var/ckey = ckey(key) + for(var/i in GLOB.player_list) + var/mob/M = i + if(M.ckey == ckey) + return M + return null + +/proc/considered_alive(datum/mind/M, enforce_human = TRUE) + if(M && M.current) + if(enforce_human) + var/mob/living/carbon/human/H + if(ishuman(M.current)) + H = M.current + return M.current.stat != DEAD && !issilicon(M.current) && !isbrain(M.current) && (!H || H.dna.species.id != "memezombies") + else if(isliving(M.current)) + return M.current.stat != DEAD + return FALSE + +/proc/considered_afk(datum/mind/M) + return !M || !M.current || !M.current.client || M.current.client.is_afk() + +/proc/ScreenText(obj/O, maptext="", screen_loc="CENTER-7,CENTER-7", maptext_height=480, maptext_width=480) + if(!isobj(O)) + O = new /obj/screen/text() + O.maptext = maptext + O.maptext_height = maptext_height + O.maptext_width = maptext_width + O.screen_loc = screen_loc + return O + +/proc/remove_images_from_clients(image/I, list/show_to) + for(var/client/C in show_to) + C.images -= I + +/proc/flick_overlay(image/I, list/show_to, duration) + for(var/client/C in show_to) + C.images += I + addtimer(CALLBACK(GLOBAL_PROC, /proc/remove_images_from_clients, I, show_to), duration, TIMER_CLIENT_TIME) + +/proc/flick_overlay_view(image/I, atom/target, duration) //wrapper for the above, flicks to everyone who can see the target atom + var/list/viewing = list() + for(var/m in viewers(target)) + var/mob/M = m + if(M.client) + viewing += M.client + flick_overlay(I, viewing, duration) + +/proc/get_active_player_count(var/alive_check = 0, var/afk_check = 0, var/human_check = 0) + // Get active players who are playing in the round + var/active_players = 0 + for(var/i = 1; i <= GLOB.player_list.len; i++) + var/mob/M = GLOB.player_list[i] + if(M && M.client) + if(alive_check && M.stat) + continue + else if(afk_check && M.client.is_afk()) + continue + else if(human_check && !ishuman(M)) + continue + else if(isnewplayer(M)) // exclude people in the lobby + continue + else if(isobserver(M)) // Ghosts are fine if they were playing once (didn't start as observers) + var/mob/dead/observer/O = M + if(O.started_as_observer) // Exclude people who started as observers + continue + active_players++ + return active_players + +/proc/showCandidatePollWindow(mob/M, poll_time, Question, list/candidates, ignore_category, time_passed, flashwindow = TRUE) + set waitfor = 0 + + SEND_SOUND(M, 'sound/misc/notice2.ogg') //Alerting them to their consideration + if(flashwindow) + window_flash(M.client) + switch(ignore_category ? askuser(M,Question,"Please answer in [DisplayTimeText(poll_time)]!","Yes","No","Never for this round", StealFocus=0, Timeout=poll_time) : askuser(M,Question,"Please answer in [DisplayTimeText(poll_time)]!","Yes","No", StealFocus=0, Timeout=poll_time)) + if(1) + to_chat(M, "Choice registered: Yes.") + if(time_passed + poll_time <= world.time) + to_chat(M, "Sorry, you answered too late to be considered!") + SEND_SOUND(M, 'sound/machines/buzz-sigh.ogg') + candidates -= M + else + candidates += M + if(2) + to_chat(M, "Choice registered: No.") + candidates -= M + if(3) + var/list/L = GLOB.poll_ignore[ignore_category] + if(!L) + GLOB.poll_ignore[ignore_category] = list() + GLOB.poll_ignore[ignore_category] += M.ckey + to_chat(M, "Choice registered: Never for this round.") + candidates -= M + else + candidates -= M + +/proc/pollGhostCandidates(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE) + var/datum/element/ghost_role_eligibility/eligibility = SSdcs.GetElement(/datum/element/ghost_role_eligibility) + var/list/candidates = eligibility.get_all_ghost_role_eligible() + return pollCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category, flashwindow, candidates) + +/proc/pollCandidates(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE, list/group = null) + var/time_passed = world.time + if (!Question) + Question = "Would you like to be a special role?" + var/list/result = list() + for(var/m in group) + var/mob/M = m + if(!M.key || !M.client || (ignore_category && GLOB.poll_ignore[ignore_category] && M.ckey in GLOB.poll_ignore[ignore_category])) + continue + if(be_special_flag) + if(!(M.client.prefs) || !(be_special_flag in M.client.prefs.be_special)) + continue + if(gametypeCheck) + if(!gametypeCheck.age_check(M.client)) + continue + if(jobbanType) + if(jobban_isbanned(M, jobbanType) || QDELETED(M) || jobban_isbanned(M, ROLE_SYNDICATE) || QDELETED(M)) + continue + + showCandidatePollWindow(M, poll_time, Question, result, ignore_category, time_passed, flashwindow) + sleep(poll_time) + + //Check all our candidates, to make sure they didn't log off or get deleted during the wait period. + for(var/mob/M in result) + if(!M.key || !M.client) + result -= M + + listclearnulls(result) + + return result + +/proc/pollCandidatesForMob(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, mob/M, ignore_category = null) + var/list/L = pollGhostCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category) + if(!M || QDELETED(M) || !M.loc) + return list() + return L + +/proc/pollCandidatesForMobs(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, list/mobs, ignore_category = null) + var/list/L = pollGhostCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category) + var/i=1 + for(var/v in mobs) + var/atom/A = v + if(!A || QDELETED(A) || !A.loc) + mobs.Cut(i,i+1) + else + ++i + return L + +/proc/poll_helper(var/mob/living/M) + +/proc/makeBody(mob/dead/observer/G_found) // Uses stripped down and bastardized code from respawn character + if(!G_found || !G_found.key) + return + + //First we spawn a dude. + var/mob/living/carbon/human/new_character = new//The mob being spawned. + SSjob.SendToLateJoin(new_character) + + G_found.client.prefs.copy_to(new_character) + new_character.dna.update_dna_identity() + G_found.transfer_ckey(new_character, FALSE) + + return new_character + +/proc/send_to_playing_players(thing) //sends a whatever to all playing players; use instead of to_chat(world, where needed) + for(var/M in GLOB.player_list) + if(M && !isnewplayer(M)) + to_chat(M, thing) + +/proc/window_flash(client/C, ignorepref = FALSE) + if(ismob(C)) + var/mob/M = C + if(M.client) + C = M.client + if(!C || (!C.prefs.windowflashing && !ignorepref)) + return + winset(C, "mainwindow", "flash=5") + +/proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank) + if(!SSticker.IsRoundInProgress() || QDELETED(character)) + return + var/area/A = get_area(character) + var/message = "\ + [character.real_name] ([rank]) has arrived at the station at \ + [A.name]." + deadchat_broadcast(message, follow_target = character, message_type=DEADCHAT_ARRIVALRATTLE) + if((!GLOB.announcement_systems.len) || (!character.mind)) + return + if((character.mind.assigned_role == "Cyborg") || (character.mind.assigned_role == character.mind.special_role)) + return + + var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems) + announcer.announce("ARRIVAL", character.real_name, rank, list()) //make the list empty to make it announce it in common + +/proc/GetHexColors(const/hexa) + return list( + GetRedPart(hexa)/ 255, + GetGreenPart(hexa)/ 255, + GetBluePart(hexa)/ 255 + ) + +/proc/GetRedPart(const/hexa) + return hex2num(copytext(hexa, 2, 4)) + +/proc/GetGreenPart(const/hexa) + return hex2num(copytext(hexa, 4, 6)) + +/proc/GetBluePart(const/hexa) + return hex2num(copytext(hexa, 6, 8)) + +/proc/lavaland_equipment_pressure_check(turf/T) + . = FALSE + if(!istype(T)) + return + var/datum/gas_mixture/environment = T.return_air() + if(!istype(environment)) + return + var/pressure = environment.return_pressure() + if(pressure <= LAVALAND_EQUIPMENT_EFFECT_PRESSURE) + . = TRUE diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index a7bf5da17f..ff9d1bec4c 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -1,128 +1,128 @@ -////////////////////////// -/////Initial Building///// -////////////////////////// - -/proc/make_datum_references_lists() - //hair - init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, GLOB.hair_styles_list, GLOB.hair_styles_male_list, GLOB.hair_styles_female_list) - //facial hair - init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list) - //underwear - init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/bottom, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f) - //undershirt - init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/top, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f) - //socks - init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/socks, GLOB.socks_list) - //bodypart accessories (blizzard intensifies) - init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.body_markings_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, GLOB.tails_list_lizard) - init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/lizard, GLOB.animated_tails_list_lizard) - init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, GLOB.tails_list_human) - init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/human, GLOB.animated_tails_list_human) - init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts, GLOB.snouts_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/horns,GLOB.horns_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, GLOB.ears_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.wings_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/wings_open, GLOB.wings_open_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, GLOB.frills_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, GLOB.spines_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/spines_animated, GLOB.animated_spines_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/legs, GLOB.legs_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.r_wings_list,roundstart = TRUE) - init_sprite_accessory_subtypes(/datum/sprite_accessory/caps, GLOB.caps_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/insect_wings, GLOB.insect_wings_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/insect_fluff, GLOB.insect_fluffs_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/deco_wings, GLOB.deco_wings_list) - -//CIT CHANGES START HERE, ADDS SNOWFLAKE BODYPARTS AND MORE - //mammal bodyparts (fucking furries) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_body_markings, GLOB.mam_body_markings_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails, GLOB.mam_tails_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_ears, GLOB.mam_ears_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_snouts, GLOB.mam_snouts_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails_animated, GLOB.mam_tails_animated_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/taur, GLOB.taur_list) - //xeno parts (hiss?) - init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_head, GLOB.xeno_head_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_tail, GLOB.xeno_tail_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_dorsal, GLOB.xeno_dorsal_list) - //ipcs - init_sprite_accessory_subtypes(/datum/sprite_accessory/screen, GLOB.ipc_screens_list, roundstart = TRUE) - init_sprite_accessory_subtypes(/datum/sprite_accessory/antenna, GLOB.ipc_antennas_list, roundstart = TRUE) - //genitals - init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list) - for(var/K in GLOB.cock_shapes_list) - var/datum/sprite_accessory/penis/value = GLOB.cock_shapes_list[K] - GLOB.cock_shapes_icons[K] = value.icon_state - - init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list) - init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list) - GLOB.breasts_size_list = list ("a", "b", "c", "d", "e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing. - GLOB.gentlemans_organ_names = list("phallus", "willy", "dick", "prick", "member", "tool", "gentleman's organ", - "cock", "wang", "knob", "dong", "joystick", "pecker", "johnson", "weenie", "tadger", "schlong", "thirsty ferret", - "baloney pony", "schlanger", "Mutton dagger", "old blind bob","Hanging Johnny", "fishing rod", "Tally whacker", "polly rocket", - "One eyed trouser trout", "Ding dong", "ankle spanker", "Pork sword", "engine cranker", "Harry hot dog", "Davy Crockett", - "Kidney cracker", "Heat seeking moisture missile", "Giggle stick", "love whistle", "Tube steak", "Uncle Dick", "Purple helmet warrior") - for(var/K in GLOB.breasts_shapes_list) - var/datum/sprite_accessory/breasts/value = GLOB.breasts_shapes_list[K] - GLOB.breasts_shapes_icons[K] = value.icon_state - - init_sprite_accessory_subtypes(/datum/sprite_accessory/testicles, GLOB.balls_shapes_list) - for(var/K in GLOB.balls_shapes_list) - var/datum/sprite_accessory/testicles/value = GLOB.balls_shapes_list[K] - GLOB.balls_shapes_icons[K] = value.icon_state - - for(var/gpath in subtypesof(/obj/item/organ/genital)) - var/obj/item/organ/genital/G = gpath - if(!CHECK_BITFIELD(initial(G.genital_flags), GENITAL_BLACKLISTED)) - GLOB.genitals_list[initial(G.name)] = gpath -//END OF CIT CHANGES - - //Species - for(var/spath in subtypesof(/datum/species)) - var/datum/species/S = new spath() - GLOB.species_list[S.id] = spath - - //Surgeries - for(var/path in subtypesof(/datum/surgery)) - GLOB.surgeries_list += new path() - - //Materials - for(var/path in subtypesof(/datum/material)) - var/datum/material/D = new path() - GLOB.materials_list[D.id] = D - - //Emotes - for(var/path in subtypesof(/datum/emote)) - var/datum/emote/E = new path() - E.emote_list[E.key] = E - - //Uplink Items - for(var/path in subtypesof(/datum/uplink_item)) - var/datum/uplink_item/I = path - if(!initial(I.item)) //We add categories to a separate list. - GLOB.uplink_categories |= initial(I.category) - continue - GLOB.uplink_items += path - //(sub)typesof entries are listed by the order they are loaded in the code, so we'll have to rearrange them here. - GLOB.uplink_items = sortList(GLOB.uplink_items, /proc/cmp_uplink_items_dsc) - - init_subtypes(/datum/crafting_recipe, GLOB.crafting_recipes) - -//creates every subtype of prototype (excluding prototype) and adds it to list L. -//if no list/L is provided, one is created. -/proc/init_subtypes(prototype, list/L) - if(!istype(L)) - L = list() - for(var/path in subtypesof(prototype)) - L += new path() - return L - -//returns a list of paths to every subtype of prototype (excluding prototype) -//if no list/L is provided, one is created. -/proc/init_paths(prototype, list/L) - if(!istype(L)) - L = list() - for(var/path in subtypesof(prototype)) - L+= path - return L +////////////////////////// +/////Initial Building///// +////////////////////////// + +/proc/make_datum_references_lists() + //hair + init_sprite_accessory_subtypes(/datum/sprite_accessory/hair, GLOB.hair_styles_list, GLOB.hair_styles_male_list, GLOB.hair_styles_female_list) + //facial hair + init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list) + //underwear + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/bottom, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f) + //undershirt + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/top, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f) + //socks + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/socks, GLOB.socks_list) + //bodypart accessories (blizzard intensifies) + init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.body_markings_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, GLOB.tails_list_lizard) + init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/lizard, GLOB.animated_tails_list_lizard) + init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, GLOB.tails_list_human) + init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/human, GLOB.animated_tails_list_human) + init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts, GLOB.snouts_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/horns,GLOB.horns_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, GLOB.ears_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.wings_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/wings_open, GLOB.wings_open_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, GLOB.frills_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, GLOB.spines_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/spines_animated, GLOB.animated_spines_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/legs, GLOB.legs_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.r_wings_list,roundstart = TRUE) + init_sprite_accessory_subtypes(/datum/sprite_accessory/caps, GLOB.caps_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/insect_wings, GLOB.insect_wings_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/insect_fluff, GLOB.insect_fluffs_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/deco_wings, GLOB.deco_wings_list) + +//CIT CHANGES START HERE, ADDS SNOWFLAKE BODYPARTS AND MORE + //mammal bodyparts (fucking furries) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_body_markings, GLOB.mam_body_markings_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails, GLOB.mam_tails_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_ears, GLOB.mam_ears_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_snouts, GLOB.mam_snouts_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails_animated, GLOB.mam_tails_animated_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/taur, GLOB.taur_list) + //xeno parts (hiss?) + init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_head, GLOB.xeno_head_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_tail, GLOB.xeno_tail_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_dorsal, GLOB.xeno_dorsal_list) + //ipcs + init_sprite_accessory_subtypes(/datum/sprite_accessory/screen, GLOB.ipc_screens_list, roundstart = TRUE) + init_sprite_accessory_subtypes(/datum/sprite_accessory/antenna, GLOB.ipc_antennas_list, roundstart = TRUE) + //genitals + init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list) + for(var/K in GLOB.cock_shapes_list) + var/datum/sprite_accessory/penis/value = GLOB.cock_shapes_list[K] + GLOB.cock_shapes_icons[K] = value.icon_state + + init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list) + GLOB.breasts_size_list = list ("a", "b", "c", "d", "e") //We need the list to choose from initialized, but it's no longer a sprite_accessory thing. + GLOB.gentlemans_organ_names = list("phallus", "willy", "dick", "prick", "member", "tool", "gentleman's organ", + "cock", "wang", "knob", "dong", "joystick", "pecker", "johnson", "weenie", "tadger", "schlong", "thirsty ferret", + "baloney pony", "schlanger", "Mutton dagger", "old blind bob","Hanging Johnny", "fishing rod", "Tally whacker", "polly rocket", + "One eyed trouser trout", "Ding dong", "ankle spanker", "Pork sword", "engine cranker", "Harry hot dog", "Davy Crockett", + "Kidney cracker", "Heat seeking moisture missile", "Giggle stick", "love whistle", "Tube steak", "Uncle Dick", "Purple helmet warrior") + for(var/K in GLOB.breasts_shapes_list) + var/datum/sprite_accessory/breasts/value = GLOB.breasts_shapes_list[K] + GLOB.breasts_shapes_icons[K] = value.icon_state + + init_sprite_accessory_subtypes(/datum/sprite_accessory/testicles, GLOB.balls_shapes_list) + for(var/K in GLOB.balls_shapes_list) + var/datum/sprite_accessory/testicles/value = GLOB.balls_shapes_list[K] + GLOB.balls_shapes_icons[K] = value.icon_state + + for(var/gpath in subtypesof(/obj/item/organ/genital)) + var/obj/item/organ/genital/G = gpath + if(!CHECK_BITFIELD(initial(G.genital_flags), GENITAL_BLACKLISTED)) + GLOB.genitals_list[initial(G.name)] = gpath +//END OF CIT CHANGES + + //Species + for(var/spath in subtypesof(/datum/species)) + var/datum/species/S = new spath() + GLOB.species_list[S.id] = spath + + //Surgeries + for(var/path in subtypesof(/datum/surgery)) + GLOB.surgeries_list += new path() + + //Materials + for(var/path in subtypesof(/datum/material)) + var/datum/material/D = new path() + GLOB.materials_list[D.id] = D + + //Emotes + for(var/path in subtypesof(/datum/emote)) + var/datum/emote/E = new path() + E.emote_list[E.key] = E + + //Uplink Items + for(var/path in subtypesof(/datum/uplink_item)) + var/datum/uplink_item/I = path + if(!initial(I.item)) //We add categories to a separate list. + GLOB.uplink_categories |= initial(I.category) + continue + GLOB.uplink_items += path + //(sub)typesof entries are listed by the order they are loaded in the code, so we'll have to rearrange them here. + GLOB.uplink_items = sortList(GLOB.uplink_items, /proc/cmp_uplink_items_dsc) + + init_subtypes(/datum/crafting_recipe, GLOB.crafting_recipes) + +//creates every subtype of prototype (excluding prototype) and adds it to list L. +//if no list/L is provided, one is created. +/proc/init_subtypes(prototype, list/L) + if(!istype(L)) + L = list() + for(var/path in subtypesof(prototype)) + L += new path() + return L + +//returns a list of paths to every subtype of prototype (excluding prototype) +//if no list/L is provided, one is created. +/proc/init_paths(prototype, list/L) + if(!istype(L)) + L = list() + for(var/path in subtypesof(prototype)) + L+= path + return L diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 1af3143d9d..8e88f869a9 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -1,1211 +1,1211 @@ -/* -IconProcs README - -A BYOND library for manipulating icons and colors - -by Lummox JR - -version 1.0 - -The IconProcs library was made to make a lot of common icon operations much easier. BYOND's icon manipulation -routines are very capable but some of the advanced capabilities like using alpha transparency can be unintuitive to beginners. - -CHANGING ICONS - -Several new procs have been added to the /icon datum to simplify working with icons. To use them, -remember you first need to setup an /icon var like so: - -GLOBAL_DATUM_INIT(my_icon, /icon, new('iconfile.dmi')) - -icon/ChangeOpacity(amount = 1) - A very common operation in DM is to try to make an icon more or less transparent. Making an icon more - transparent is usually much easier than making it less so, however. This proc basically is a frontend - for MapColors() which can change opacity any way you like, in much the same way that SetIntensity() - can make an icon lighter or darker. If amount is 0.5, the opacity of the icon will be cut in half. - If amount is 2, opacity is doubled and anything more than half-opaque will become fully opaque. -icon/GrayScale() - Converts the icon to grayscale instead of a fully colored icon. Alpha values are left intact. -icon/ColorTone(tone) - Similar to GrayScale(), this proc converts the icon to a range of black -> tone -> white, where tone is an - RGB color (its alpha is ignored). This can be used to create a sepia tone or similar effect. - See also the global ColorTone() proc. -icon/MinColors(icon) - The icon is blended with a second icon where the minimum of each RGB pixel is the result. - Transparency may increase, as if the icons were blended with ICON_ADD. You may supply a color in place of an icon. -icon/MaxColors(icon) - The icon is blended with a second icon where the maximum of each RGB pixel is the result. - Opacity may increase, as if the icons were blended with ICON_OR. You may supply a color in place of an icon. -icon/Opaque(background = "#000000") - All alpha values are set to 255 throughout the icon. Transparent pixels become black, or whatever background color you specify. -icon/BecomeAlphaMask() - You can convert a simple grayscale icon into an alpha mask to use with other icons very easily with this proc. - The black parts become transparent, the white parts stay white, and anything in between becomes a translucent shade of white. -icon/AddAlphaMask(mask) - The alpha values of the mask icon will be blended with the current icon. Anywhere the mask is opaque, - the current icon is untouched. Anywhere the mask is transparent, the current icon becomes transparent. - Where the mask is translucent, the current icon becomes more transparent. -icon/UseAlphaMask(mask, mode) - Sometimes you may want to take the alpha values from one icon and use them on a different icon. - This proc will do that. Just supply the icon whose alpha mask you want to use, and src will change - so it has the same colors as before but uses the mask for opacity. - -COLOR MANAGEMENT AND HSV - -RGB isn't the only way to represent color. Sometimes it's more useful to work with a model called HSV, which stands for hue, saturation, and value. - - * The hue of a color describes where it is along the color wheel. It goes from red to yellow to green to - cyan to blue to magenta and back to red. - * The saturation of a color is how much color is in it. A color with low saturation will be more gray, - and with no saturation at all it is a shade of gray. - * The value of a color determines how bright it is. A high-value color is vivid, moderate value is dark, - and no value at all is black. - -Just as BYOND uses "#rrggbb" to represent RGB values, a similar format is used for HSV: "#hhhssvv". The hue is three -hex digits because it ranges from 0 to 0x5FF. - - * 0 to 0xFF - red to yellow - * 0x100 to 0x1FF - yellow to green - * 0x200 to 0x2FF - green to cyan - * 0x300 to 0x3FF - cyan to blue - * 0x400 to 0x4FF - blue to magenta - * 0x500 to 0x5FF - magenta to red - -Knowing this, you can figure out that red is "#000ffff" in HSV format, which is hue 0 (red), saturation 255 (as colorful as possible), -value 255 (as bright as possible). Green is "#200ffff" and blue is "#400ffff". - -More than one HSV color can match the same RGB color. - -Here are some procs you can use for color management: - -ReadRGB(rgb) - Takes an RGB string like "#ffaa55" and converts it to a list such as list(255,170,85). If an RGBA format is used - that includes alpha, the list will have a fourth item for the alpha value. -hsv(hue, sat, val, apha) - Counterpart to rgb(), this takes the values you input and converts them to a string in "#hhhssvv" or "#hhhssvvaa" - format. Alpha is not included in the result if null. -ReadHSV(rgb) - Takes an HSV string like "#100FF80" and converts it to a list such as list(256,255,128). If an HSVA format is used that - includes alpha, the list will have a fourth item for the alpha value. -RGBtoHSV(rgb) - Takes an RGB or RGBA string like "#ffaa55" and converts it into an HSV or HSVA color such as "#080aaff". -HSVtoRGB(hsv) - Takes an HSV or HSVA string like "#080aaff" and converts it into an RGB or RGBA color such as "#ff55aa". -BlendRGB(rgb1, rgb2, amount) - Blends between two RGB or RGBA colors using regular RGB blending. If amount is 0, the first color is the result; - if 1, the second color is the result. 0.5 produces an average of the two. Values outside the 0 to 1 range are allowed as well. - The returned value is an RGB or RGBA color. -BlendHSV(hsv1, hsv2, amount) - Blends between two HSV or HSVA colors using HSV blending, which tends to produce nicer results than regular RGB - blending because the brightness of the color is left intact. If amount is 0, the first color is the result; if 1, - the second color is the result. 0.5 produces an average of the two. Values outside the 0 to 1 range are allowed as well. - The returned value is an HSV or HSVA color. -BlendRGBasHSV(rgb1, rgb2, amount) - Like BlendHSV(), but the colors used and the return value are RGB or RGBA colors. The blending is done in HSV form. -HueToAngle(hue) - Converts a hue to an angle range of 0 to 360. Angle 0 is red, 120 is green, and 240 is blue. -AngleToHue(hue) - Converts an angle to a hue in the valid range. -RotateHue(hsv, angle) - Takes an HSV or HSVA value and rotates the hue forward through red, green, and blue by an angle from 0 to 360. - (Rotating red by 60° produces yellow.) The result is another HSV or HSVA color with the same saturation and value - as the original, but a different hue. -GrayScale(rgb) - Takes an RGB or RGBA color and converts it to grayscale. Returns an RGB or RGBA string. -ColorTone(rgb, tone) - Similar to GrayScale(), this proc converts an RGB or RGBA color to a range of black -> tone -> white instead of - using strict shades of gray. The tone value is an RGB color; any alpha value is ignored. -*/ - -/* -Get Flat Icon DEMO by DarkCampainger - -This is a test for the get flat icon proc, modified approprietly for icons and their states. -Probably not a good idea to run this unless you want to see how the proc works in detail. -mob - icon = 'old_or_unused.dmi' - icon_state = "green" - - Login() - // Testing image underlays - underlays += image(icon='old_or_unused.dmi',icon_state="red") - underlays += image(icon='old_or_unused.dmi',icon_state="red", pixel_x = 32) - underlays += image(icon='old_or_unused.dmi',icon_state="red", pixel_x = -32) - - // Testing image overlays - add_overlay(image(icon='old_or_unused.dmi',icon_state="green", pixel_x = 32, pixel_y = -32)) - add_overlay(image(icon='old_or_unused.dmi',icon_state="green", pixel_x = 32, pixel_y = 32)) - add_overlay(image(icon='old_or_unused.dmi',icon_state="green", pixel_x = -32, pixel_y = -32)) - - // Testing icon file overlays (defaults to mob's state) - add_overlay('_flat_demoIcons2.dmi') - - // Testing icon_state overlays (defaults to mob's icon) - add_overlay("white") - - // Testing dynamic icon overlays - var/icon/I = icon('old_or_unused.dmi', icon_state="aqua") - I.Shift(NORTH,16,1) - add_overlay(I) - - // Testing dynamic image overlays - I=image(icon=I,pixel_x = -32, pixel_y = 32) - add_overlay(I) - - // Testing object types (and layers) - add_overlay(/obj/effect/overlayTest) - - loc = locate (10,10,1) - verb - Browse_Icon() - set name = "1. Browse Icon" - // Give it a name for the cache - var/iconName = "[ckey(src.name)]_flattened.dmi" - // Send the icon to src's local cache - src<

      ") - - Output_Icon() - set name = "2. Output Icon" - to_chat(src, "Icon is: [icon2base64html(getFlatIcon(src))]") - - Label_Icon() - set name = "3. Label Icon" - // Give it a name for the cache - var/iconName = "[ckey(src.name)]_flattened.dmi" - // Copy the file to the rsc manually - var/icon/I = fcopy_rsc(getFlatIcon(src)) - // Send the icon to src's local cache - src< transparent, gray -> translucent white, white -> solid white -/icon/proc/BecomeAlphaMask() - SwapColor(null, "#000000ff") // don't let transparent become gray - MapColors(0,0,0,0.3, 0,0,0,0.59, 0,0,0,0.11, 0,0,0,0, 1,1,1,0) - -/icon/proc/UseAlphaMask(mask) - Opaque() - AddAlphaMask(mask) - -/icon/proc/AddAlphaMask(mask) - var/icon/M = new(mask) - M.Blend("#ffffff", ICON_SUBTRACT) - // apply mask - Blend(M, ICON_ADD) - -/* - HSV format is represented as "#hhhssvv" or "#hhhssvvaa" - - Hue ranges from 0 to 0x5ff (1535) - - 0x000 = red - 0x100 = yellow - 0x200 = green - 0x300 = cyan - 0x400 = blue - 0x500 = magenta - - Saturation is from 0 to 0xff (255) - - More saturation = more color - Less saturation = more gray - - Value ranges from 0 to 0xff (255) - - Higher value means brighter color - */ - -/proc/ReadRGB(rgb) - if(!rgb) - return - - // interpret the HSV or HSVA value - var/i=1,start=1 - if(text2ascii(rgb) == 35) ++start // skip opening # - var/ch,which=0,r=0,g=0,b=0,alpha=0,usealpha - var/digits=0 - for(i=start, i<=length(rgb), ++i) - ch = text2ascii(rgb, i) - if(ch < 48 || (ch > 57 && ch < 65) || (ch > 70 && ch < 97) || ch > 102) - break - ++digits - if(digits == 8) - break - - var/single = digits < 6 - if(digits != 3 && digits != 4 && digits != 6 && digits != 8) - return - if(digits == 4 || digits == 8) - usealpha = 1 - for(i=start, digits>0, ++i) - ch = text2ascii(rgb, i) - if(ch >= 48 && ch <= 57) - ch -= 48 - else if(ch >= 65 && ch <= 70) - ch -= 55 - else if(ch >= 97 && ch <= 102) - ch -= 87 - else - break - --digits - switch(which) - if(0) - r = (r << 4) | ch - if(single) - r |= r << 4 - ++which - else if(!(digits & 1)) - ++which - if(1) - g = (g << 4) | ch - if(single) - g |= g << 4 - ++which - else if(!(digits & 1)) - ++which - if(2) - b = (b << 4) | ch - if(single) - b |= b << 4 - ++which - else if(!(digits & 1)) - ++which - if(3) - alpha = (alpha << 4) | ch - if(single) - alpha |= alpha << 4 - - . = list(r, g, b) - if(usealpha) - . += alpha - -/proc/ReadHSV(hsv) - if(!hsv) - return - - // interpret the HSV or HSVA value - var/i=1,start=1 - if(text2ascii(hsv) == 35) - ++start // skip opening # - var/ch,which=0,hue=0,sat=0,val=0,alpha=0,usealpha - var/digits=0 - for(i=start, i<=length(hsv), ++i) - ch = text2ascii(hsv, i) - if(ch < 48 || (ch > 57 && ch < 65) || (ch > 70 && ch < 97) || ch > 102) - break - ++digits - if(digits == 9) - break - if(digits > 7) - usealpha = 1 - if(digits <= 4) - ++which - if(digits <= 2) - ++which - for(i=start, digits>0, ++i) - ch = text2ascii(hsv, i) - if(ch >= 48 && ch <= 57) - ch -= 48 - else if(ch >= 65 && ch <= 70) - ch -= 55 - else if(ch >= 97 && ch <= 102) - ch -= 87 - else - break - --digits - switch(which) - if(0) - hue = (hue << 4) | ch - if(digits == (usealpha ? 6 : 4)) - ++which - if(1) - sat = (sat << 4) | ch - if(digits == (usealpha ? 4 : 2)) - ++which - if(2) - val = (val << 4) | ch - if(digits == (usealpha ? 2 : 0)) - ++which - if(3) - alpha = (alpha << 4) | ch - - . = list(hue, sat, val) - if(usealpha) - . += alpha - -/proc/HSVtoRGB(hsv) - if(!hsv) - return "#000000" - var/list/HSV = ReadHSV(hsv) - if(!HSV) - return "#000000" - - var/hue = HSV[1] - var/sat = HSV[2] - var/val = HSV[3] - - // Compress hue into easier-to-manage range - hue -= hue >> 8 - if(hue >= 0x5fa) - hue -= 0x5fa - - var/hi,mid,lo,r,g,b - hi = val - lo = round((255 - sat) * val / 255, 1) - mid = lo + round(abs(round(hue, 510) - hue) * (hi - lo) / 255, 1) - if(hue >= 765) - if(hue >= 1275) {r=hi; g=lo; b=mid} - else if(hue >= 1020) {r=mid; g=lo; b=hi } - else {r=lo; g=mid; b=hi } - else - if(hue >= 510) {r=lo; g=hi; b=mid} - else if(hue >= 255) {r=mid; g=hi; b=lo } - else {r=hi; g=mid; b=lo } - - return (HSV.len > 3) ? rgb(r,g,b,HSV[4]) : rgb(r,g,b) - -/proc/RGBtoHSV(rgb) - if(!rgb) - return "#0000000" - var/list/RGB = ReadRGB(rgb) - if(!RGB) - return "#0000000" - - var/r = RGB[1] - var/g = RGB[2] - var/b = RGB[3] - var/hi = max(r,g,b) - var/lo = min(r,g,b) - - var/val = hi - var/sat = hi ? round((hi-lo) * 255 / hi, 1) : 0 - var/hue = 0 - - if(sat) - var/dir - var/mid - if(hi == r) - if(lo == b) {hue=0; dir=1; mid=g} - else {hue=1535; dir=-1; mid=b} - else if(hi == g) - if(lo == r) {hue=512; dir=1; mid=b} - else {hue=511; dir=-1; mid=r} - else if(hi == b) - if(lo == g) {hue=1024; dir=1; mid=r} - else {hue=1023; dir=-1; mid=g} - hue += dir * round((mid-lo) * 255 / (hi-lo), 1) - - return hsv(hue, sat, val, (RGB.len>3 ? RGB[4] : null)) - -/proc/hsv(hue, sat, val, alpha) - if(hue < 0 || hue >= 1536) - hue %= 1536 - if(hue < 0) - hue += 1536 - if((hue & 0xFF) == 0xFF) - ++hue - if(hue >= 1536) - hue = 0 - if(sat < 0) - sat = 0 - if(sat > 255) - sat = 255 - if(val < 0) - val = 0 - if(val > 255) - val = 255 - . = "#" - . += TO_HEX_DIGIT(hue >> 8) - . += TO_HEX_DIGIT(hue >> 4) - . += TO_HEX_DIGIT(hue) - . += TO_HEX_DIGIT(sat >> 4) - . += TO_HEX_DIGIT(sat) - . += TO_HEX_DIGIT(val >> 4) - . += TO_HEX_DIGIT(val) - if(!isnull(alpha)) - if(alpha < 0) - alpha = 0 - if(alpha > 255) - alpha = 255 - . += TO_HEX_DIGIT(alpha >> 4) - . += TO_HEX_DIGIT(alpha) - -/* - Smooth blend between HSV colors - - amount=0 is the first color - amount=1 is the second color - amount=0.5 is directly between the two colors - - amount<0 or amount>1 are allowed - */ -/proc/BlendHSV(hsv1, hsv2, amount) - var/list/HSV1 = ReadHSV(hsv1) - var/list/HSV2 = ReadHSV(hsv2) - - // add missing alpha if needed - if(HSV1.len < HSV2.len) - HSV1 += 255 - else if(HSV2.len < HSV1.len) - HSV2 += 255 - var/usealpha = HSV1.len > 3 - - // normalize hsv values in case anything is screwy - if(HSV1[1] > 1536) - HSV1[1] %= 1536 - if(HSV2[1] > 1536) - HSV2[1] %= 1536 - if(HSV1[1] < 0) - HSV1[1] += 1536 - if(HSV2[1] < 0) - HSV2[1] += 1536 - if(!HSV1[3]) {HSV1[1] = 0; HSV1[2] = 0} - if(!HSV2[3]) {HSV2[1] = 0; HSV2[2] = 0} - - // no value for one color means don't change saturation - if(!HSV1[3]) - HSV1[2] = HSV2[2] - if(!HSV2[3]) - HSV2[2] = HSV1[2] - // no saturation for one color means don't change hues - if(!HSV1[2]) - HSV1[1] = HSV2[1] - if(!HSV2[2]) - HSV2[1] = HSV1[1] - - // Compress hues into easier-to-manage range - HSV1[1] -= HSV1[1] >> 8 - HSV2[1] -= HSV2[1] >> 8 - - var/hue_diff = HSV2[1] - HSV1[1] - if(hue_diff > 765) - hue_diff -= 1530 - else if(hue_diff <= -765) - hue_diff += 1530 - - var/hue = round(HSV1[1] + hue_diff * amount, 1) - var/sat = round(HSV1[2] + (HSV2[2] - HSV1[2]) * amount, 1) - var/val = round(HSV1[3] + (HSV2[3] - HSV1[3]) * amount, 1) - var/alpha = usealpha ? round(HSV1[4] + (HSV2[4] - HSV1[4]) * amount, 1) : null - - // normalize hue - if(hue < 0 || hue >= 1530) - hue %= 1530 - if(hue < 0) - hue += 1530 - // decompress hue - hue += round(hue / 255) - - return hsv(hue, sat, val, alpha) - -/* - Smooth blend between RGB colors - - amount=0 is the first color - amount=1 is the second color - amount=0.5 is directly between the two colors - - amount<0 or amount>1 are allowed - */ -/proc/BlendRGB(rgb1, rgb2, amount) - var/list/RGB1 = ReadRGB(rgb1) - var/list/RGB2 = ReadRGB(rgb2) - - // add missing alpha if needed - if(RGB1.len < RGB2.len) - RGB1 += 255 - else if(RGB2.len < RGB1.len) - RGB2 += 255 - var/usealpha = RGB1.len > 3 - - var/r = round(RGB1[1] + (RGB2[1] - RGB1[1]) * amount, 1) - var/g = round(RGB1[2] + (RGB2[2] - RGB1[2]) * amount, 1) - var/b = round(RGB1[3] + (RGB2[3] - RGB1[3]) * amount, 1) - var/alpha = usealpha ? round(RGB1[4] + (RGB2[4] - RGB1[4]) * amount, 1) : null - - return isnull(alpha) ? rgb(r, g, b) : rgb(r, g, b, alpha) - -/proc/BlendRGBasHSV(rgb1, rgb2, amount) - return HSVtoRGB(RGBtoHSV(rgb1), RGBtoHSV(rgb2), amount) - -/proc/HueToAngle(hue) - // normalize hsv in case anything is screwy - if(hue < 0 || hue >= 1536) - hue %= 1536 - if(hue < 0) - hue += 1536 - // Compress hue into easier-to-manage range - hue -= hue >> 8 - return hue / (1530/360) - -/proc/AngleToHue(angle) - // normalize hsv in case anything is screwy - if(angle < 0 || angle >= 360) - angle -= 360 * round(angle / 360) - var/hue = angle * (1530/360) - // Decompress hue - hue += round(hue / 255) - return hue - - -// positive angle rotates forward through red->green->blue -/proc/RotateHue(hsv, angle) - var/list/HSV = ReadHSV(hsv) - - // normalize hsv in case anything is screwy - if(HSV[1] >= 1536) - HSV[1] %= 1536 - if(HSV[1] < 0) - HSV[1] += 1536 - - // Compress hue into easier-to-manage range - HSV[1] -= HSV[1] >> 8 - - if(angle < 0 || angle >= 360) - angle -= 360 * round(angle / 360) - HSV[1] = round(HSV[1] + angle * (1530/360), 1) - - // normalize hue - if(HSV[1] < 0 || HSV[1] >= 1530) - HSV[1] %= 1530 - if(HSV[1] < 0) - HSV[1] += 1530 - // decompress hue - HSV[1] += round(HSV[1] / 255) - - return hsv(HSV[1], HSV[2], HSV[3], (HSV.len > 3 ? HSV[4] : null)) - -// Convert an rgb color to grayscale -/proc/GrayScale(rgb) - var/list/RGB = ReadRGB(rgb) - var/gray = RGB[1]*0.3 + RGB[2]*0.59 + RGB[3]*0.11 - return (RGB.len > 3) ? rgb(gray, gray, gray, RGB[4]) : rgb(gray, gray, gray) - -// Change grayscale color to black->tone->white range -/proc/ColorTone(rgb, tone) - var/list/RGB = ReadRGB(rgb) - var/list/TONE = ReadRGB(tone) - - var/gray = RGB[1]*0.3 + RGB[2]*0.59 + RGB[3]*0.11 - var/tone_gray = TONE[1]*0.3 + TONE[2]*0.59 + TONE[3]*0.11 - - if(gray <= tone_gray) - return BlendRGB("#000000", tone, gray/(tone_gray || 1)) - else - return BlendRGB(tone, "#ffffff", (gray-tone_gray)/((255-tone_gray) || 1)) - - -//Used in the OLD chem colour mixing algorithm -/proc/GetColors(hex) - hex = uppertext(hex) - // No alpha set? Default to full alpha. - if(length(hex) == 7) - hex += "FF" - var/hi1 = text2ascii(hex, 2) // R - var/lo1 = text2ascii(hex, 3) // R - var/hi2 = text2ascii(hex, 4) // G - var/lo2 = text2ascii(hex, 5) // G - var/hi3 = text2ascii(hex, 6) // B - var/lo3 = text2ascii(hex, 7) // B - var/hi4 = text2ascii(hex, 8) // A - var/lo4 = text2ascii(hex, 9) // A - return list(((hi1>= 65 ? hi1-55 : hi1-48)<<4) | (lo1 >= 65 ? lo1-55 : lo1-48), - ((hi2 >= 65 ? hi2-55 : hi2-48)<<4) | (lo2 >= 65 ? lo2-55 : lo2-48), - ((hi3 >= 65 ? hi3-55 : hi3-48)<<4) | (lo3 >= 65 ? lo3-55 : lo3-48), - ((hi4 >= 65 ? hi4-55 : hi4-48)<<4) | (lo4 >= 65 ? lo4-55 : lo4-48)) - -// Creates a single icon from a given /atom or /image. Only the first argument is required. -/proc/getFlatIcon(image/A, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE) - //Define... defines. - var/static/icon/flat_template = icon('icons/effects/effects.dmi', "nothing") - - #define BLANK icon(flat_template) - #define SET_SELF(SETVAR) do { \ - var/icon/SELF_ICON=icon(icon(curicon, curstate, base_icon_dir),"",SOUTH,no_anim?1:null); \ - if(A.alpha<255) { \ - SELF_ICON.Blend(rgb(255,255,255,A.alpha),ICON_MULTIPLY);\ - } \ - if(A.color) { \ - if(islist(A.color)){ \ - SELF_ICON.MapColors(arglist(A.color))} \ - else{ \ - SELF_ICON.Blend(A.color,ICON_MULTIPLY)} \ - } \ - ##SETVAR=SELF_ICON;\ - } while (0) - - #define INDEX_X_LOW 1 - #define INDEX_X_HIGH 2 - #define INDEX_Y_LOW 3 - #define INDEX_Y_HIGH 4 - - #define flatX1 flat_size[INDEX_X_LOW] - #define flatX2 flat_size[INDEX_X_HIGH] - #define flatY1 flat_size[INDEX_Y_LOW] - #define flatY2 flat_size[INDEX_Y_HIGH] - #define addX1 add_size[INDEX_X_LOW] - #define addX2 add_size[INDEX_X_HIGH] - #define addY1 add_size[INDEX_Y_LOW] - #define addY2 add_size[INDEX_Y_HIGH] - - if(!A || A.alpha <= 0) - return BLANK - - var/noIcon = FALSE - if(start) - if(!defdir) - defdir = A.dir - if(!deficon) - deficon = A.icon - if(!defstate) - defstate = A.icon_state - if(!defblend) - defblend = A.blend_mode - - var/curicon = A.icon || deficon - var/curstate = A.icon_state || defstate - - if(!((noIcon = (!curicon)))) - var/curstates = icon_states(curicon) - if(!(curstate in curstates)) - if("" in curstates) - curstate = "" - else - noIcon = TRUE // Do not render this object. - - var/curdir - var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have - - //These should use the parent's direction (most likely) - if(!A.dir || A.dir == SOUTH) - curdir = defdir - else - curdir = A.dir - - //Try to remove/optimize this section ASAP, CPU hog. - //Determines if there's directionals. - if(!noIcon && curdir != SOUTH) - var/exist = FALSE - var/static/list/checkdirs = list(NORTH, EAST, WEST) - for(var/i in checkdirs) //Not using GLOB for a reason. - if(length(icon_states(icon(curicon, curstate, i)))) - exist = TRUE - break - if(!exist) - base_icon_dir = SOUTH - // - - if(!base_icon_dir) - base_icon_dir = curdir - - ASSERT(!BLEND_DEFAULT) //I might just be stupid but lets make sure this define is 0. - - var/curblend = A.blend_mode || defblend - - if(A.overlays.len || A.underlays.len) - var/icon/flat = BLANK - // Layers will be a sorted list of icons/overlays, based on the order in which they are displayed - var/list/layers = list() - var/image/copy - // Add the atom's icon itself, without pixel_x/y offsets. - if(!noIcon) - copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=base_icon_dir) - copy.color = A.color - copy.alpha = A.alpha - copy.blend_mode = curblend - layers[copy] = A.layer - - // Loop through the underlays, then overlays, sorting them into the layers list - for(var/process_set in 0 to 1) - var/list/process = process_set? A.overlays : A.underlays - for(var/i in 1 to process.len) - var/image/current = process[i] - if(!current) - continue - if(current.plane != FLOAT_PLANE && current.plane != A.plane) - continue - var/current_layer = current.layer - if(current_layer < 0) - if(current_layer <= -1000) - return flat - current_layer = process_set + A.layer + current_layer / 1000 - - for(var/p in 1 to layers.len) - var/image/cmp = layers[p] - if(current_layer < layers[cmp]) - layers.Insert(p, current) - break - layers[current] = current_layer - - //sortTim(layers, /proc/cmp_image_layer_asc) - - var/icon/add // Icon of overlay being added - - // Current dimensions of flattened icon - var/list/flat_size = list(1, flat.Width(), 1, flat.Height()) - // Dimensions of overlay being added - var/list/add_size[4] - - for(var/V in layers) - var/image/I = V - if(I.alpha == 0) - continue - - if(I == copy) // 'I' is an /image based on the object being flattened. - curblend = BLEND_OVERLAY - add = icon(I.icon, I.icon_state, base_icon_dir) - else // 'I' is an appearance object. - add = getFlatIcon(image(I), curdir, curicon, curstate, curblend, FALSE, no_anim) - if(!add) - continue - // Find the new dimensions of the flat icon to fit the added overlay - add_size = list( - min(flatX1, I.pixel_x+1), - max(flatX2, I.pixel_x+add.Width()), - min(flatY1, I.pixel_y+1), - max(flatY2, I.pixel_y+add.Height()) - ) - - if(flat_size ~! add_size) - // Resize the flattened icon so the new icon fits - flat.Crop( - addX1 - flatX1 + 1, - addY1 - flatY1 + 1, - addX2 - flatX1 + 1, - addY2 - flatY1 + 1 - ) - flat_size = add_size.Copy() - - // Blend the overlay into the flattened icon - flat.Blend(add, blendMode2iconMode(curblend), I.pixel_x + 2 - flatX1, I.pixel_y + 2 - flatY1) - - if(A.color) - if(islist(A.color)) - flat.MapColors(arglist(A.color)) - else - flat.Blend(A.color, ICON_MULTIPLY) - - if(A.alpha < 255) - flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY) - - if(no_anim) - //Clean up repeated frames - var/icon/cleaned = new /icon() - cleaned.Insert(flat, "", SOUTH, 1, 0) - . = cleaned - else - . = icon(flat, "", SOUTH) - else //There's no overlays. - if(!noIcon) - SET_SELF(.) - - //Clear defines - #undef flatX1 - #undef flatX2 - #undef flatY1 - #undef flatY2 - #undef addX1 - #undef addX2 - #undef addY1 - #undef addY2 - - #undef INDEX_X_LOW - #undef INDEX_X_HIGH - #undef INDEX_Y_LOW - #undef INDEX_Y_HIGH - - #undef BLANK - #undef SET_SELF - -/proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N - var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A. - for(var/V in A.overlays)//For every image in overlays. var/image/I will not work, don't try it. - var/image/I = V - if(I.layer>A.layer) - continue//If layer is greater than what we need, skip it. - var/icon/image_overlay = new(I.icon,I.icon_state)//Blend only works with icon objects. - //Also, icons cannot directly set icon_state. Slower than changing variables but whatever. - alpha_mask.Blend(image_overlay,ICON_OR)//OR so they are lumped together in a nice overlay. - return alpha_mask//And now return the mask. - -/mob/proc/AddCamoOverlay(atom/A)//A is the atom which we are using as the overlay. - var/icon/opacity_icon = new(A.icon, A.icon_state)//Don't really care for overlays/underlays. - //Now we need to culculate overlays+underlays and add them together to form an image for a mask. - var/icon/alpha_mask = getIconMask(src)//getFlatIcon(src) is accurate but SLOW. Not designed for running each tick. This is also a little slow since it's blending a bunch of icons together but good enough. - opacity_icon.AddAlphaMask(alpha_mask)//Likely the main source of lag for this proc. Probably not designed to run each tick. - opacity_icon.ChangeOpacity(0.4)//Front end for MapColors so it's fast. 0.5 means half opacity and looks the best in my opinion. - for(var/i=0,i<5,i++)//And now we add it as overlays. It's faster than creating an icon and then merging it. - var/image/I = image("icon" = opacity_icon, "icon_state" = A.icon_state, "layer" = layer+0.8)//So it's above other stuff but below weapons and the like. - switch(i)//Now to determine offset so the result is somewhat blurred. - if(1) - I.pixel_x-- - if(2) - I.pixel_x++ - if(3) - I.pixel_y-- - if(4) - I.pixel_y++ - add_overlay(I)//And finally add the overlay. - -/proc/getHologramIcon(icon/A, safety = TRUE)//If safety is on, a new icon is not created. - var/icon/flat_icon = safety ? A : new(A)//Has to be a new icon to not constantly change the same icon. - flat_icon.ColorTone(rgb(125,180,225))//Let's make it bluish. - flat_icon.ChangeOpacity(0.5)//Make it half transparent. - var/icon/alpha_mask = new('icons/effects/effects.dmi', "scanline")//Scanline effect. - flat_icon.AddAlphaMask(alpha_mask)//Finally, let's mix in a distortion effect. - return flat_icon - -/proc/getPAIHologramIcon(icon/A, safety = TRUE) - var/icon/flat_icon = safety? A : new(A) - flat_icon.SetIntensity(0.75, 1, 0.75) - flat_icon.ChangeOpacity(0.7) - var/icon/alpha_mask = new('icons/effects/effects.dmi', "scanlineslow")//Scanline effect. - flat_icon.AddAlphaMask(alpha_mask)//Finally, let's mix in a distortion effect. - return flat_icon - -//What the mob looks like as animated static -//By vg's ComicIronic -/proc/getStaticIcon(icon/A, safety = TRUE) - var/icon/flat_icon = safety ? A : new(A) - flat_icon.Blend(rgb(255,255,255)) - flat_icon.BecomeAlphaMask() - var/icon/static_icon = icon('icons/effects/effects.dmi', "static_base") - static_icon.AddAlphaMask(flat_icon) - return static_icon - -//What the mob looks like as a pitch black outline -//By vg's ComicIronic -/proc/getBlankIcon(icon/A, safety=1) - var/icon/flat_icon = safety ? A : new(A) - flat_icon.Blend(rgb(255,255,255)) - flat_icon.BecomeAlphaMask() - var/icon/blank_icon = new/icon('icons/effects/effects.dmi', "blank_base") - blank_icon.AddAlphaMask(flat_icon) - return blank_icon - - -//Dwarf fortress style icons based on letters (defaults to the first letter of the Atom's name) -//By vg's ComicIronic -/proc/getLetterImage(atom/A, letter= "", uppercase = 0) - if(!A) - return - - var/icon/atom_icon = new(A.icon, A.icon_state) - - if(!letter) - letter = copytext(A.name, 1, 2) - if(uppercase == 1) - letter = uppertext(letter) - else if(uppercase == -1) - letter = lowertext(letter) - - var/image/text_image = new(loc = A) - text_image.maptext = "[letter]" - text_image.pixel_x = 7 - text_image.pixel_y = 5 - qdel(atom_icon) - return text_image - -GLOBAL_LIST_EMPTY(friendly_animal_types) - -// Pick a random animal instead of the icon, and use that instead -/proc/getRandomAnimalImage(atom/A) - if(!GLOB.friendly_animal_types.len) - for(var/T in typesof(/mob/living/simple_animal)) - var/mob/living/simple_animal/SA = T - if(initial(SA.gold_core_spawnable) == FRIENDLY_SPAWN) - GLOB.friendly_animal_types += SA - - - var/mob/living/simple_animal/SA = pick(GLOB.friendly_animal_types) - - var/icon = initial(SA.icon) - var/icon_state = initial(SA.icon_state) - - var/image/final_image = image(icon, icon_state=icon_state, loc = A) - - if(ispath(SA, /mob/living/simple_animal/butterfly)) - final_image.color = rgb(rand(0,255), rand(0,255), rand(0,255)) - - // For debugging - final_image.text = initial(SA.name) - return final_image - -//Interface for using DrawBox() to draw 1 pixel on a coordinate. -//Returns the same icon specifed in the argument, but with the pixel drawn -/proc/DrawPixel(icon/I,colour,drawX,drawY) - if(!I) - return 0 - - var/Iwidth = I.Width() - var/Iheight = I.Height() - - if(drawX > Iwidth || drawX <= 0) - return 0 - if(drawY > Iheight || drawY <= 0) - return 0 - - I.DrawBox(colour,drawX, drawY) - return I - - -//Interface for easy drawing of one pixel on an atom. -/atom/proc/DrawPixelOn(colour, drawX, drawY) - var/icon/I = new(icon) - var/icon/J = DrawPixel(I, colour, drawX, drawY) - if(J) //Only set the icon if it succeeded, the icon without the pixel is 1000x better than a black square. - icon = J - return J - return 0 - -//For creating consistent icons for human looking simple animals -/proc/get_flat_human_icon(icon_id, datum/job/J, datum/preferences/prefs, dummy_key, showDirs = GLOB.cardinals, outfit_override = null) - var/static/list/humanoid_icon_cache = list() - if(!icon_id || !humanoid_icon_cache[icon_id]) - var/mob/living/carbon/human/dummy/body = generate_or_wait_for_human_dummy(dummy_key) - - if(prefs) - prefs.copy_to(body,TRUE,FALSE) - if(J) - J.equip(body, TRUE, FALSE, outfit_override = outfit_override) - else if (outfit_override) - body.equipOutfit(outfit_override,visualsOnly = TRUE) - - - var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing") - for(var/D in showDirs) - body.setDir(D) - COMPILE_OVERLAYS(body) - var/icon/partial = getFlatIcon(body) - out_icon.Insert(partial,dir=D) - - humanoid_icon_cache[icon_id] = out_icon - dummy_key? unset_busy_human_dummy(dummy_key) : qdel(body) - return out_icon - else - return humanoid_icon_cache[icon_id] - -//Hook, override to run code on- wait this is images -//Images have dir without being an atom, so they get their own definition. -//Lame. -/image/proc/setDir(newdir) - dir = newdir - -GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0,0,0))) - -/obj/proc/make_frozen_visual() - // Used to make the frozen item visuals for Freon. - if(resistance_flags & FREEZE_PROOF) - return - if(!(obj_flags & FROZEN)) - name = "frozen [name]" - add_atom_colour(GLOB.freon_color_matrix, TEMPORARY_COLOUR_PRIORITY) - alpha -= 25 - obj_flags |= FROZEN - -//Assumes already frozed -/obj/proc/make_unfrozen() - if(obj_flags & FROZEN) - name = replacetext(name, "frozen ", "") - remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, GLOB.freon_color_matrix) - alpha += 25 - obj_flags &= ~FROZEN - - -//Converts an icon to base64. Operates by putting the icon in the iconCache savefile, -// exporting it as text, and then parsing the base64 from that. -// (This relies on byond automatically storing icons in savefiles as base64) -/proc/icon2base64(icon/icon, iconKey = "misc") - if (!isicon(icon)) - return FALSE - WRITE_FILE(GLOB.iconCache[iconKey], icon) - var/iconData = GLOB.iconCache.ExportText(iconKey) - var/list/partial = splittext(iconData, "{") - return replacetext(copytext(partial[2], 3, -5), "\n", "") - -/proc/icon2html(thing, target, icon_state, dir, frame = 1, moving = FALSE) - if (!thing) - return - - var/key - var/icon/I = thing - if (!target) - return - if (target == world) - target = GLOB.clients - - var/list/targets - if (!islist(target)) - targets = list(target) - else - targets = target - if (!targets.len) - return - if (!isicon(I)) - if (isfile(thing)) //special snowflake - var/name = sanitize_filename("[generate_asset_name(thing)].png") - register_asset(name, thing) - for (var/thing2 in targets) - send_asset(thing2, key, FALSE) - return "" - var/atom/A = thing - if (isnull(dir)) - dir = A.dir - if (isnull(icon_state)) - icon_state = A.icon_state - I = A.icon - if (ishuman(thing)) // Shitty workaround for a BYOND issue. - var/icon/temp = I - I = icon() - I.Insert(temp, dir = SOUTH) - dir = SOUTH - else - if (isnull(dir)) - dir = SOUTH - if (isnull(icon_state)) - icon_state = "" - - I = icon(I, icon_state, dir, frame, moving) - - key = "[generate_asset_name(I)].png" - register_asset(key, I) - for (var/thing2 in targets) - send_asset(thing2, key, FALSE) - - return "" - -/proc/icon2base64html(thing) - if (!thing) - return - var/static/list/bicon_cache = list() - if (isicon(thing)) - var/icon/I = thing - var/icon_base64 = icon2base64(I) - - if (I.Height() > world.icon_size || I.Width() > world.icon_size) - var/icon_md5 = md5(icon_base64) - icon_base64 = bicon_cache[icon_md5] - if (!icon_base64) // Doesn't exist yet, make it. - bicon_cache[icon_md5] = icon_base64 = icon2base64(I) - - - return "" - - // Either an atom or somebody fucked up and is gonna get a runtime, which I'm fine with. - var/atom/A = thing - var/key = "[istype(A.icon, /icon) ? "[REF(A.icon)]" : A.icon]:[A.icon_state]" - - - if (!bicon_cache[key]) // Doesn't exist, make it. - var/icon/I = icon(A.icon, A.icon_state, SOUTH, 1) - if (ishuman(thing)) // Shitty workaround for a BYOND issue. - var/icon/temp = I - I = icon() - I.Insert(temp, dir = SOUTH) - - bicon_cache[key] = icon2base64(I, key) - - return "" - -//Costlier version of icon2html() that uses getFlatIcon() to account for overlays, underlays, etc. Use with extreme moderation, ESPECIALLY on mobs. -/proc/costly_icon2html(thing, target) - if (!thing) - return - - if (isicon(thing)) - return icon2html(thing, target) - - var/icon/I = getFlatIcon(thing) - return icon2html(I, target) +/* +IconProcs README + +A BYOND library for manipulating icons and colors + +by Lummox JR + +version 1.0 + +The IconProcs library was made to make a lot of common icon operations much easier. BYOND's icon manipulation +routines are very capable but some of the advanced capabilities like using alpha transparency can be unintuitive to beginners. + +CHANGING ICONS + +Several new procs have been added to the /icon datum to simplify working with icons. To use them, +remember you first need to setup an /icon var like so: + +GLOBAL_DATUM_INIT(my_icon, /icon, new('iconfile.dmi')) + +icon/ChangeOpacity(amount = 1) + A very common operation in DM is to try to make an icon more or less transparent. Making an icon more + transparent is usually much easier than making it less so, however. This proc basically is a frontend + for MapColors() which can change opacity any way you like, in much the same way that SetIntensity() + can make an icon lighter or darker. If amount is 0.5, the opacity of the icon will be cut in half. + If amount is 2, opacity is doubled and anything more than half-opaque will become fully opaque. +icon/GrayScale() + Converts the icon to grayscale instead of a fully colored icon. Alpha values are left intact. +icon/ColorTone(tone) + Similar to GrayScale(), this proc converts the icon to a range of black -> tone -> white, where tone is an + RGB color (its alpha is ignored). This can be used to create a sepia tone or similar effect. + See also the global ColorTone() proc. +icon/MinColors(icon) + The icon is blended with a second icon where the minimum of each RGB pixel is the result. + Transparency may increase, as if the icons were blended with ICON_ADD. You may supply a color in place of an icon. +icon/MaxColors(icon) + The icon is blended with a second icon where the maximum of each RGB pixel is the result. + Opacity may increase, as if the icons were blended with ICON_OR. You may supply a color in place of an icon. +icon/Opaque(background = "#000000") + All alpha values are set to 255 throughout the icon. Transparent pixels become black, or whatever background color you specify. +icon/BecomeAlphaMask() + You can convert a simple grayscale icon into an alpha mask to use with other icons very easily with this proc. + The black parts become transparent, the white parts stay white, and anything in between becomes a translucent shade of white. +icon/AddAlphaMask(mask) + The alpha values of the mask icon will be blended with the current icon. Anywhere the mask is opaque, + the current icon is untouched. Anywhere the mask is transparent, the current icon becomes transparent. + Where the mask is translucent, the current icon becomes more transparent. +icon/UseAlphaMask(mask, mode) + Sometimes you may want to take the alpha values from one icon and use them on a different icon. + This proc will do that. Just supply the icon whose alpha mask you want to use, and src will change + so it has the same colors as before but uses the mask for opacity. + +COLOR MANAGEMENT AND HSV + +RGB isn't the only way to represent color. Sometimes it's more useful to work with a model called HSV, which stands for hue, saturation, and value. + + * The hue of a color describes where it is along the color wheel. It goes from red to yellow to green to + cyan to blue to magenta and back to red. + * The saturation of a color is how much color is in it. A color with low saturation will be more gray, + and with no saturation at all it is a shade of gray. + * The value of a color determines how bright it is. A high-value color is vivid, moderate value is dark, + and no value at all is black. + +Just as BYOND uses "#rrggbb" to represent RGB values, a similar format is used for HSV: "#hhhssvv". The hue is three +hex digits because it ranges from 0 to 0x5FF. + + * 0 to 0xFF - red to yellow + * 0x100 to 0x1FF - yellow to green + * 0x200 to 0x2FF - green to cyan + * 0x300 to 0x3FF - cyan to blue + * 0x400 to 0x4FF - blue to magenta + * 0x500 to 0x5FF - magenta to red + +Knowing this, you can figure out that red is "#000ffff" in HSV format, which is hue 0 (red), saturation 255 (as colorful as possible), +value 255 (as bright as possible). Green is "#200ffff" and blue is "#400ffff". + +More than one HSV color can match the same RGB color. + +Here are some procs you can use for color management: + +ReadRGB(rgb) + Takes an RGB string like "#ffaa55" and converts it to a list such as list(255,170,85). If an RGBA format is used + that includes alpha, the list will have a fourth item for the alpha value. +hsv(hue, sat, val, apha) + Counterpart to rgb(), this takes the values you input and converts them to a string in "#hhhssvv" or "#hhhssvvaa" + format. Alpha is not included in the result if null. +ReadHSV(rgb) + Takes an HSV string like "#100FF80" and converts it to a list such as list(256,255,128). If an HSVA format is used that + includes alpha, the list will have a fourth item for the alpha value. +RGBtoHSV(rgb) + Takes an RGB or RGBA string like "#ffaa55" and converts it into an HSV or HSVA color such as "#080aaff". +HSVtoRGB(hsv) + Takes an HSV or HSVA string like "#080aaff" and converts it into an RGB or RGBA color such as "#ff55aa". +BlendRGB(rgb1, rgb2, amount) + Blends between two RGB or RGBA colors using regular RGB blending. If amount is 0, the first color is the result; + if 1, the second color is the result. 0.5 produces an average of the two. Values outside the 0 to 1 range are allowed as well. + The returned value is an RGB or RGBA color. +BlendHSV(hsv1, hsv2, amount) + Blends between two HSV or HSVA colors using HSV blending, which tends to produce nicer results than regular RGB + blending because the brightness of the color is left intact. If amount is 0, the first color is the result; if 1, + the second color is the result. 0.5 produces an average of the two. Values outside the 0 to 1 range are allowed as well. + The returned value is an HSV or HSVA color. +BlendRGBasHSV(rgb1, rgb2, amount) + Like BlendHSV(), but the colors used and the return value are RGB or RGBA colors. The blending is done in HSV form. +HueToAngle(hue) + Converts a hue to an angle range of 0 to 360. Angle 0 is red, 120 is green, and 240 is blue. +AngleToHue(hue) + Converts an angle to a hue in the valid range. +RotateHue(hsv, angle) + Takes an HSV or HSVA value and rotates the hue forward through red, green, and blue by an angle from 0 to 360. + (Rotating red by 60° produces yellow.) The result is another HSV or HSVA color with the same saturation and value + as the original, but a different hue. +GrayScale(rgb) + Takes an RGB or RGBA color and converts it to grayscale. Returns an RGB or RGBA string. +ColorTone(rgb, tone) + Similar to GrayScale(), this proc converts an RGB or RGBA color to a range of black -> tone -> white instead of + using strict shades of gray. The tone value is an RGB color; any alpha value is ignored. +*/ + +/* +Get Flat Icon DEMO by DarkCampainger + +This is a test for the get flat icon proc, modified approprietly for icons and their states. +Probably not a good idea to run this unless you want to see how the proc works in detail. +mob + icon = 'old_or_unused.dmi' + icon_state = "green" + + Login() + // Testing image underlays + underlays += image(icon='old_or_unused.dmi',icon_state="red") + underlays += image(icon='old_or_unused.dmi',icon_state="red", pixel_x = 32) + underlays += image(icon='old_or_unused.dmi',icon_state="red", pixel_x = -32) + + // Testing image overlays + add_overlay(image(icon='old_or_unused.dmi',icon_state="green", pixel_x = 32, pixel_y = -32)) + add_overlay(image(icon='old_or_unused.dmi',icon_state="green", pixel_x = 32, pixel_y = 32)) + add_overlay(image(icon='old_or_unused.dmi',icon_state="green", pixel_x = -32, pixel_y = -32)) + + // Testing icon file overlays (defaults to mob's state) + add_overlay('_flat_demoIcons2.dmi') + + // Testing icon_state overlays (defaults to mob's icon) + add_overlay("white") + + // Testing dynamic icon overlays + var/icon/I = icon('old_or_unused.dmi', icon_state="aqua") + I.Shift(NORTH,16,1) + add_overlay(I) + + // Testing dynamic image overlays + I=image(icon=I,pixel_x = -32, pixel_y = 32) + add_overlay(I) + + // Testing object types (and layers) + add_overlay(/obj/effect/overlayTest) + + loc = locate (10,10,1) + verb + Browse_Icon() + set name = "1. Browse Icon" + // Give it a name for the cache + var/iconName = "[ckey(src.name)]_flattened.dmi" + // Send the icon to src's local cache + src<

      ") + + Output_Icon() + set name = "2. Output Icon" + to_chat(src, "Icon is: [icon2base64html(getFlatIcon(src))]") + + Label_Icon() + set name = "3. Label Icon" + // Give it a name for the cache + var/iconName = "[ckey(src.name)]_flattened.dmi" + // Copy the file to the rsc manually + var/icon/I = fcopy_rsc(getFlatIcon(src)) + // Send the icon to src's local cache + src< transparent, gray -> translucent white, white -> solid white +/icon/proc/BecomeAlphaMask() + SwapColor(null, "#000000ff") // don't let transparent become gray + MapColors(0,0,0,0.3, 0,0,0,0.59, 0,0,0,0.11, 0,0,0,0, 1,1,1,0) + +/icon/proc/UseAlphaMask(mask) + Opaque() + AddAlphaMask(mask) + +/icon/proc/AddAlphaMask(mask) + var/icon/M = new(mask) + M.Blend("#ffffff", ICON_SUBTRACT) + // apply mask + Blend(M, ICON_ADD) + +/* + HSV format is represented as "#hhhssvv" or "#hhhssvvaa" + + Hue ranges from 0 to 0x5ff (1535) + + 0x000 = red + 0x100 = yellow + 0x200 = green + 0x300 = cyan + 0x400 = blue + 0x500 = magenta + + Saturation is from 0 to 0xff (255) + + More saturation = more color + Less saturation = more gray + + Value ranges from 0 to 0xff (255) + + Higher value means brighter color + */ + +/proc/ReadRGB(rgb) + if(!rgb) + return + + // interpret the HSV or HSVA value + var/i=1,start=1 + if(text2ascii(rgb) == 35) ++start // skip opening # + var/ch,which=0,r=0,g=0,b=0,alpha=0,usealpha + var/digits=0 + for(i=start, i<=length(rgb), ++i) + ch = text2ascii(rgb, i) + if(ch < 48 || (ch > 57 && ch < 65) || (ch > 70 && ch < 97) || ch > 102) + break + ++digits + if(digits == 8) + break + + var/single = digits < 6 + if(digits != 3 && digits != 4 && digits != 6 && digits != 8) + return + if(digits == 4 || digits == 8) + usealpha = 1 + for(i=start, digits>0, ++i) + ch = text2ascii(rgb, i) + if(ch >= 48 && ch <= 57) + ch -= 48 + else if(ch >= 65 && ch <= 70) + ch -= 55 + else if(ch >= 97 && ch <= 102) + ch -= 87 + else + break + --digits + switch(which) + if(0) + r = (r << 4) | ch + if(single) + r |= r << 4 + ++which + else if(!(digits & 1)) + ++which + if(1) + g = (g << 4) | ch + if(single) + g |= g << 4 + ++which + else if(!(digits & 1)) + ++which + if(2) + b = (b << 4) | ch + if(single) + b |= b << 4 + ++which + else if(!(digits & 1)) + ++which + if(3) + alpha = (alpha << 4) | ch + if(single) + alpha |= alpha << 4 + + . = list(r, g, b) + if(usealpha) + . += alpha + +/proc/ReadHSV(hsv) + if(!hsv) + return + + // interpret the HSV or HSVA value + var/i=1,start=1 + if(text2ascii(hsv) == 35) + ++start // skip opening # + var/ch,which=0,hue=0,sat=0,val=0,alpha=0,usealpha + var/digits=0 + for(i=start, i<=length(hsv), ++i) + ch = text2ascii(hsv, i) + if(ch < 48 || (ch > 57 && ch < 65) || (ch > 70 && ch < 97) || ch > 102) + break + ++digits + if(digits == 9) + break + if(digits > 7) + usealpha = 1 + if(digits <= 4) + ++which + if(digits <= 2) + ++which + for(i=start, digits>0, ++i) + ch = text2ascii(hsv, i) + if(ch >= 48 && ch <= 57) + ch -= 48 + else if(ch >= 65 && ch <= 70) + ch -= 55 + else if(ch >= 97 && ch <= 102) + ch -= 87 + else + break + --digits + switch(which) + if(0) + hue = (hue << 4) | ch + if(digits == (usealpha ? 6 : 4)) + ++which + if(1) + sat = (sat << 4) | ch + if(digits == (usealpha ? 4 : 2)) + ++which + if(2) + val = (val << 4) | ch + if(digits == (usealpha ? 2 : 0)) + ++which + if(3) + alpha = (alpha << 4) | ch + + . = list(hue, sat, val) + if(usealpha) + . += alpha + +/proc/HSVtoRGB(hsv) + if(!hsv) + return "#000000" + var/list/HSV = ReadHSV(hsv) + if(!HSV) + return "#000000" + + var/hue = HSV[1] + var/sat = HSV[2] + var/val = HSV[3] + + // Compress hue into easier-to-manage range + hue -= hue >> 8 + if(hue >= 0x5fa) + hue -= 0x5fa + + var/hi,mid,lo,r,g,b + hi = val + lo = round((255 - sat) * val / 255, 1) + mid = lo + round(abs(round(hue, 510) - hue) * (hi - lo) / 255, 1) + if(hue >= 765) + if(hue >= 1275) {r=hi; g=lo; b=mid} + else if(hue >= 1020) {r=mid; g=lo; b=hi } + else {r=lo; g=mid; b=hi } + else + if(hue >= 510) {r=lo; g=hi; b=mid} + else if(hue >= 255) {r=mid; g=hi; b=lo } + else {r=hi; g=mid; b=lo } + + return (HSV.len > 3) ? rgb(r,g,b,HSV[4]) : rgb(r,g,b) + +/proc/RGBtoHSV(rgb) + if(!rgb) + return "#0000000" + var/list/RGB = ReadRGB(rgb) + if(!RGB) + return "#0000000" + + var/r = RGB[1] + var/g = RGB[2] + var/b = RGB[3] + var/hi = max(r,g,b) + var/lo = min(r,g,b) + + var/val = hi + var/sat = hi ? round((hi-lo) * 255 / hi, 1) : 0 + var/hue = 0 + + if(sat) + var/dir + var/mid + if(hi == r) + if(lo == b) {hue=0; dir=1; mid=g} + else {hue=1535; dir=-1; mid=b} + else if(hi == g) + if(lo == r) {hue=512; dir=1; mid=b} + else {hue=511; dir=-1; mid=r} + else if(hi == b) + if(lo == g) {hue=1024; dir=1; mid=r} + else {hue=1023; dir=-1; mid=g} + hue += dir * round((mid-lo) * 255 / (hi-lo), 1) + + return hsv(hue, sat, val, (RGB.len>3 ? RGB[4] : null)) + +/proc/hsv(hue, sat, val, alpha) + if(hue < 0 || hue >= 1536) + hue %= 1536 + if(hue < 0) + hue += 1536 + if((hue & 0xFF) == 0xFF) + ++hue + if(hue >= 1536) + hue = 0 + if(sat < 0) + sat = 0 + if(sat > 255) + sat = 255 + if(val < 0) + val = 0 + if(val > 255) + val = 255 + . = "#" + . += TO_HEX_DIGIT(hue >> 8) + . += TO_HEX_DIGIT(hue >> 4) + . += TO_HEX_DIGIT(hue) + . += TO_HEX_DIGIT(sat >> 4) + . += TO_HEX_DIGIT(sat) + . += TO_HEX_DIGIT(val >> 4) + . += TO_HEX_DIGIT(val) + if(!isnull(alpha)) + if(alpha < 0) + alpha = 0 + if(alpha > 255) + alpha = 255 + . += TO_HEX_DIGIT(alpha >> 4) + . += TO_HEX_DIGIT(alpha) + +/* + Smooth blend between HSV colors + + amount=0 is the first color + amount=1 is the second color + amount=0.5 is directly between the two colors + + amount<0 or amount>1 are allowed + */ +/proc/BlendHSV(hsv1, hsv2, amount) + var/list/HSV1 = ReadHSV(hsv1) + var/list/HSV2 = ReadHSV(hsv2) + + // add missing alpha if needed + if(HSV1.len < HSV2.len) + HSV1 += 255 + else if(HSV2.len < HSV1.len) + HSV2 += 255 + var/usealpha = HSV1.len > 3 + + // normalize hsv values in case anything is screwy + if(HSV1[1] > 1536) + HSV1[1] %= 1536 + if(HSV2[1] > 1536) + HSV2[1] %= 1536 + if(HSV1[1] < 0) + HSV1[1] += 1536 + if(HSV2[1] < 0) + HSV2[1] += 1536 + if(!HSV1[3]) {HSV1[1] = 0; HSV1[2] = 0} + if(!HSV2[3]) {HSV2[1] = 0; HSV2[2] = 0} + + // no value for one color means don't change saturation + if(!HSV1[3]) + HSV1[2] = HSV2[2] + if(!HSV2[3]) + HSV2[2] = HSV1[2] + // no saturation for one color means don't change hues + if(!HSV1[2]) + HSV1[1] = HSV2[1] + if(!HSV2[2]) + HSV2[1] = HSV1[1] + + // Compress hues into easier-to-manage range + HSV1[1] -= HSV1[1] >> 8 + HSV2[1] -= HSV2[1] >> 8 + + var/hue_diff = HSV2[1] - HSV1[1] + if(hue_diff > 765) + hue_diff -= 1530 + else if(hue_diff <= -765) + hue_diff += 1530 + + var/hue = round(HSV1[1] + hue_diff * amount, 1) + var/sat = round(HSV1[2] + (HSV2[2] - HSV1[2]) * amount, 1) + var/val = round(HSV1[3] + (HSV2[3] - HSV1[3]) * amount, 1) + var/alpha = usealpha ? round(HSV1[4] + (HSV2[4] - HSV1[4]) * amount, 1) : null + + // normalize hue + if(hue < 0 || hue >= 1530) + hue %= 1530 + if(hue < 0) + hue += 1530 + // decompress hue + hue += round(hue / 255) + + return hsv(hue, sat, val, alpha) + +/* + Smooth blend between RGB colors + + amount=0 is the first color + amount=1 is the second color + amount=0.5 is directly between the two colors + + amount<0 or amount>1 are allowed + */ +/proc/BlendRGB(rgb1, rgb2, amount) + var/list/RGB1 = ReadRGB(rgb1) + var/list/RGB2 = ReadRGB(rgb2) + + // add missing alpha if needed + if(RGB1.len < RGB2.len) + RGB1 += 255 + else if(RGB2.len < RGB1.len) + RGB2 += 255 + var/usealpha = RGB1.len > 3 + + var/r = round(RGB1[1] + (RGB2[1] - RGB1[1]) * amount, 1) + var/g = round(RGB1[2] + (RGB2[2] - RGB1[2]) * amount, 1) + var/b = round(RGB1[3] + (RGB2[3] - RGB1[3]) * amount, 1) + var/alpha = usealpha ? round(RGB1[4] + (RGB2[4] - RGB1[4]) * amount, 1) : null + + return isnull(alpha) ? rgb(r, g, b) : rgb(r, g, b, alpha) + +/proc/BlendRGBasHSV(rgb1, rgb2, amount) + return HSVtoRGB(RGBtoHSV(rgb1), RGBtoHSV(rgb2), amount) + +/proc/HueToAngle(hue) + // normalize hsv in case anything is screwy + if(hue < 0 || hue >= 1536) + hue %= 1536 + if(hue < 0) + hue += 1536 + // Compress hue into easier-to-manage range + hue -= hue >> 8 + return hue / (1530/360) + +/proc/AngleToHue(angle) + // normalize hsv in case anything is screwy + if(angle < 0 || angle >= 360) + angle -= 360 * round(angle / 360) + var/hue = angle * (1530/360) + // Decompress hue + hue += round(hue / 255) + return hue + + +// positive angle rotates forward through red->green->blue +/proc/RotateHue(hsv, angle) + var/list/HSV = ReadHSV(hsv) + + // normalize hsv in case anything is screwy + if(HSV[1] >= 1536) + HSV[1] %= 1536 + if(HSV[1] < 0) + HSV[1] += 1536 + + // Compress hue into easier-to-manage range + HSV[1] -= HSV[1] >> 8 + + if(angle < 0 || angle >= 360) + angle -= 360 * round(angle / 360) + HSV[1] = round(HSV[1] + angle * (1530/360), 1) + + // normalize hue + if(HSV[1] < 0 || HSV[1] >= 1530) + HSV[1] %= 1530 + if(HSV[1] < 0) + HSV[1] += 1530 + // decompress hue + HSV[1] += round(HSV[1] / 255) + + return hsv(HSV[1], HSV[2], HSV[3], (HSV.len > 3 ? HSV[4] : null)) + +// Convert an rgb color to grayscale +/proc/GrayScale(rgb) + var/list/RGB = ReadRGB(rgb) + var/gray = RGB[1]*0.3 + RGB[2]*0.59 + RGB[3]*0.11 + return (RGB.len > 3) ? rgb(gray, gray, gray, RGB[4]) : rgb(gray, gray, gray) + +// Change grayscale color to black->tone->white range +/proc/ColorTone(rgb, tone) + var/list/RGB = ReadRGB(rgb) + var/list/TONE = ReadRGB(tone) + + var/gray = RGB[1]*0.3 + RGB[2]*0.59 + RGB[3]*0.11 + var/tone_gray = TONE[1]*0.3 + TONE[2]*0.59 + TONE[3]*0.11 + + if(gray <= tone_gray) + return BlendRGB("#000000", tone, gray/(tone_gray || 1)) + else + return BlendRGB(tone, "#ffffff", (gray-tone_gray)/((255-tone_gray) || 1)) + + +//Used in the OLD chem colour mixing algorithm +/proc/GetColors(hex) + hex = uppertext(hex) + // No alpha set? Default to full alpha. + if(length(hex) == 7) + hex += "FF" + var/hi1 = text2ascii(hex, 2) // R + var/lo1 = text2ascii(hex, 3) // R + var/hi2 = text2ascii(hex, 4) // G + var/lo2 = text2ascii(hex, 5) // G + var/hi3 = text2ascii(hex, 6) // B + var/lo3 = text2ascii(hex, 7) // B + var/hi4 = text2ascii(hex, 8) // A + var/lo4 = text2ascii(hex, 9) // A + return list(((hi1>= 65 ? hi1-55 : hi1-48)<<4) | (lo1 >= 65 ? lo1-55 : lo1-48), + ((hi2 >= 65 ? hi2-55 : hi2-48)<<4) | (lo2 >= 65 ? lo2-55 : lo2-48), + ((hi3 >= 65 ? hi3-55 : hi3-48)<<4) | (lo3 >= 65 ? lo3-55 : lo3-48), + ((hi4 >= 65 ? hi4-55 : hi4-48)<<4) | (lo4 >= 65 ? lo4-55 : lo4-48)) + +// Creates a single icon from a given /atom or /image. Only the first argument is required. +/proc/getFlatIcon(image/A, defdir, deficon, defstate, defblend, start = TRUE, no_anim = FALSE) + //Define... defines. + var/static/icon/flat_template = icon('icons/effects/effects.dmi', "nothing") + + #define BLANK icon(flat_template) + #define SET_SELF(SETVAR) do { \ + var/icon/SELF_ICON=icon(icon(curicon, curstate, base_icon_dir),"",SOUTH,no_anim?1:null); \ + if(A.alpha<255) { \ + SELF_ICON.Blend(rgb(255,255,255,A.alpha),ICON_MULTIPLY);\ + } \ + if(A.color) { \ + if(islist(A.color)){ \ + SELF_ICON.MapColors(arglist(A.color))} \ + else{ \ + SELF_ICON.Blend(A.color,ICON_MULTIPLY)} \ + } \ + ##SETVAR=SELF_ICON;\ + } while (0) + + #define INDEX_X_LOW 1 + #define INDEX_X_HIGH 2 + #define INDEX_Y_LOW 3 + #define INDEX_Y_HIGH 4 + + #define flatX1 flat_size[INDEX_X_LOW] + #define flatX2 flat_size[INDEX_X_HIGH] + #define flatY1 flat_size[INDEX_Y_LOW] + #define flatY2 flat_size[INDEX_Y_HIGH] + #define addX1 add_size[INDEX_X_LOW] + #define addX2 add_size[INDEX_X_HIGH] + #define addY1 add_size[INDEX_Y_LOW] + #define addY2 add_size[INDEX_Y_HIGH] + + if(!A || A.alpha <= 0) + return BLANK + + var/noIcon = FALSE + if(start) + if(!defdir) + defdir = A.dir + if(!deficon) + deficon = A.icon + if(!defstate) + defstate = A.icon_state + if(!defblend) + defblend = A.blend_mode + + var/curicon = A.icon || deficon + var/curstate = A.icon_state || defstate + + if(!((noIcon = (!curicon)))) + var/curstates = icon_states(curicon) + if(!(curstate in curstates)) + if("" in curstates) + curstate = "" + else + noIcon = TRUE // Do not render this object. + + var/curdir + var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have + + //These should use the parent's direction (most likely) + if(!A.dir || A.dir == SOUTH) + curdir = defdir + else + curdir = A.dir + + //Try to remove/optimize this section ASAP, CPU hog. + //Determines if there's directionals. + if(!noIcon && curdir != SOUTH) + var/exist = FALSE + var/static/list/checkdirs = list(NORTH, EAST, WEST) + for(var/i in checkdirs) //Not using GLOB for a reason. + if(length(icon_states(icon(curicon, curstate, i)))) + exist = TRUE + break + if(!exist) + base_icon_dir = SOUTH + // + + if(!base_icon_dir) + base_icon_dir = curdir + + ASSERT(!BLEND_DEFAULT) //I might just be stupid but lets make sure this define is 0. + + var/curblend = A.blend_mode || defblend + + if(A.overlays.len || A.underlays.len) + var/icon/flat = BLANK + // Layers will be a sorted list of icons/overlays, based on the order in which they are displayed + var/list/layers = list() + var/image/copy + // Add the atom's icon itself, without pixel_x/y offsets. + if(!noIcon) + copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=base_icon_dir) + copy.color = A.color + copy.alpha = A.alpha + copy.blend_mode = curblend + layers[copy] = A.layer + + // Loop through the underlays, then overlays, sorting them into the layers list + for(var/process_set in 0 to 1) + var/list/process = process_set? A.overlays : A.underlays + for(var/i in 1 to process.len) + var/image/current = process[i] + if(!current) + continue + if(current.plane != FLOAT_PLANE && current.plane != A.plane) + continue + var/current_layer = current.layer + if(current_layer < 0) + if(current_layer <= -1000) + return flat + current_layer = process_set + A.layer + current_layer / 1000 + + for(var/p in 1 to layers.len) + var/image/cmp = layers[p] + if(current_layer < layers[cmp]) + layers.Insert(p, current) + break + layers[current] = current_layer + + //sortTim(layers, /proc/cmp_image_layer_asc) + + var/icon/add // Icon of overlay being added + + // Current dimensions of flattened icon + var/list/flat_size = list(1, flat.Width(), 1, flat.Height()) + // Dimensions of overlay being added + var/list/add_size[4] + + for(var/V in layers) + var/image/I = V + if(I.alpha == 0) + continue + + if(I == copy) // 'I' is an /image based on the object being flattened. + curblend = BLEND_OVERLAY + add = icon(I.icon, I.icon_state, base_icon_dir) + else // 'I' is an appearance object. + add = getFlatIcon(image(I), curdir, curicon, curstate, curblend, FALSE, no_anim) + if(!add) + continue + // Find the new dimensions of the flat icon to fit the added overlay + add_size = list( + min(flatX1, I.pixel_x+1), + max(flatX2, I.pixel_x+add.Width()), + min(flatY1, I.pixel_y+1), + max(flatY2, I.pixel_y+add.Height()) + ) + + if(flat_size ~! add_size) + // Resize the flattened icon so the new icon fits + flat.Crop( + addX1 - flatX1 + 1, + addY1 - flatY1 + 1, + addX2 - flatX1 + 1, + addY2 - flatY1 + 1 + ) + flat_size = add_size.Copy() + + // Blend the overlay into the flattened icon + flat.Blend(add, blendMode2iconMode(curblend), I.pixel_x + 2 - flatX1, I.pixel_y + 2 - flatY1) + + if(A.color) + if(islist(A.color)) + flat.MapColors(arglist(A.color)) + else + flat.Blend(A.color, ICON_MULTIPLY) + + if(A.alpha < 255) + flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY) + + if(no_anim) + //Clean up repeated frames + var/icon/cleaned = new /icon() + cleaned.Insert(flat, "", SOUTH, 1, 0) + . = cleaned + else + . = icon(flat, "", SOUTH) + else //There's no overlays. + if(!noIcon) + SET_SELF(.) + + //Clear defines + #undef flatX1 + #undef flatX2 + #undef flatY1 + #undef flatY2 + #undef addX1 + #undef addX2 + #undef addY1 + #undef addY2 + + #undef INDEX_X_LOW + #undef INDEX_X_HIGH + #undef INDEX_Y_LOW + #undef INDEX_Y_HIGH + + #undef BLANK + #undef SET_SELF + +/proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N + var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A. + for(var/V in A.overlays)//For every image in overlays. var/image/I will not work, don't try it. + var/image/I = V + if(I.layer>A.layer) + continue//If layer is greater than what we need, skip it. + var/icon/image_overlay = new(I.icon,I.icon_state)//Blend only works with icon objects. + //Also, icons cannot directly set icon_state. Slower than changing variables but whatever. + alpha_mask.Blend(image_overlay,ICON_OR)//OR so they are lumped together in a nice overlay. + return alpha_mask//And now return the mask. + +/mob/proc/AddCamoOverlay(atom/A)//A is the atom which we are using as the overlay. + var/icon/opacity_icon = new(A.icon, A.icon_state)//Don't really care for overlays/underlays. + //Now we need to culculate overlays+underlays and add them together to form an image for a mask. + var/icon/alpha_mask = getIconMask(src)//getFlatIcon(src) is accurate but SLOW. Not designed for running each tick. This is also a little slow since it's blending a bunch of icons together but good enough. + opacity_icon.AddAlphaMask(alpha_mask)//Likely the main source of lag for this proc. Probably not designed to run each tick. + opacity_icon.ChangeOpacity(0.4)//Front end for MapColors so it's fast. 0.5 means half opacity and looks the best in my opinion. + for(var/i=0,i<5,i++)//And now we add it as overlays. It's faster than creating an icon and then merging it. + var/image/I = image("icon" = opacity_icon, "icon_state" = A.icon_state, "layer" = layer+0.8)//So it's above other stuff but below weapons and the like. + switch(i)//Now to determine offset so the result is somewhat blurred. + if(1) + I.pixel_x-- + if(2) + I.pixel_x++ + if(3) + I.pixel_y-- + if(4) + I.pixel_y++ + add_overlay(I)//And finally add the overlay. + +/proc/getHologramIcon(icon/A, safety = TRUE)//If safety is on, a new icon is not created. + var/icon/flat_icon = safety ? A : new(A)//Has to be a new icon to not constantly change the same icon. + flat_icon.ColorTone(rgb(125,180,225))//Let's make it bluish. + flat_icon.ChangeOpacity(0.5)//Make it half transparent. + var/icon/alpha_mask = new('icons/effects/effects.dmi', "scanline")//Scanline effect. + flat_icon.AddAlphaMask(alpha_mask)//Finally, let's mix in a distortion effect. + return flat_icon + +/proc/getPAIHologramIcon(icon/A, safety = TRUE) + var/icon/flat_icon = safety? A : new(A) + flat_icon.SetIntensity(0.75, 1, 0.75) + flat_icon.ChangeOpacity(0.7) + var/icon/alpha_mask = new('icons/effects/effects.dmi', "scanlineslow")//Scanline effect. + flat_icon.AddAlphaMask(alpha_mask)//Finally, let's mix in a distortion effect. + return flat_icon + +//What the mob looks like as animated static +//By vg's ComicIronic +/proc/getStaticIcon(icon/A, safety = TRUE) + var/icon/flat_icon = safety ? A : new(A) + flat_icon.Blend(rgb(255,255,255)) + flat_icon.BecomeAlphaMask() + var/icon/static_icon = icon('icons/effects/effects.dmi', "static_base") + static_icon.AddAlphaMask(flat_icon) + return static_icon + +//What the mob looks like as a pitch black outline +//By vg's ComicIronic +/proc/getBlankIcon(icon/A, safety=1) + var/icon/flat_icon = safety ? A : new(A) + flat_icon.Blend(rgb(255,255,255)) + flat_icon.BecomeAlphaMask() + var/icon/blank_icon = new/icon('icons/effects/effects.dmi', "blank_base") + blank_icon.AddAlphaMask(flat_icon) + return blank_icon + + +//Dwarf fortress style icons based on letters (defaults to the first letter of the Atom's name) +//By vg's ComicIronic +/proc/getLetterImage(atom/A, letter= "", uppercase = 0) + if(!A) + return + + var/icon/atom_icon = new(A.icon, A.icon_state) + + if(!letter) + letter = copytext(A.name, 1, 2) + if(uppercase == 1) + letter = uppertext(letter) + else if(uppercase == -1) + letter = lowertext(letter) + + var/image/text_image = new(loc = A) + text_image.maptext = "[letter]" + text_image.pixel_x = 7 + text_image.pixel_y = 5 + qdel(atom_icon) + return text_image + +GLOBAL_LIST_EMPTY(friendly_animal_types) + +// Pick a random animal instead of the icon, and use that instead +/proc/getRandomAnimalImage(atom/A) + if(!GLOB.friendly_animal_types.len) + for(var/T in typesof(/mob/living/simple_animal)) + var/mob/living/simple_animal/SA = T + if(initial(SA.gold_core_spawnable) == FRIENDLY_SPAWN) + GLOB.friendly_animal_types += SA + + + var/mob/living/simple_animal/SA = pick(GLOB.friendly_animal_types) + + var/icon = initial(SA.icon) + var/icon_state = initial(SA.icon_state) + + var/image/final_image = image(icon, icon_state=icon_state, loc = A) + + if(ispath(SA, /mob/living/simple_animal/butterfly)) + final_image.color = rgb(rand(0,255), rand(0,255), rand(0,255)) + + // For debugging + final_image.text = initial(SA.name) + return final_image + +//Interface for using DrawBox() to draw 1 pixel on a coordinate. +//Returns the same icon specifed in the argument, but with the pixel drawn +/proc/DrawPixel(icon/I,colour,drawX,drawY) + if(!I) + return 0 + + var/Iwidth = I.Width() + var/Iheight = I.Height() + + if(drawX > Iwidth || drawX <= 0) + return 0 + if(drawY > Iheight || drawY <= 0) + return 0 + + I.DrawBox(colour,drawX, drawY) + return I + + +//Interface for easy drawing of one pixel on an atom. +/atom/proc/DrawPixelOn(colour, drawX, drawY) + var/icon/I = new(icon) + var/icon/J = DrawPixel(I, colour, drawX, drawY) + if(J) //Only set the icon if it succeeded, the icon without the pixel is 1000x better than a black square. + icon = J + return J + return 0 + +//For creating consistent icons for human looking simple animals +/proc/get_flat_human_icon(icon_id, datum/job/J, datum/preferences/prefs, dummy_key, showDirs = GLOB.cardinals, outfit_override = null) + var/static/list/humanoid_icon_cache = list() + if(!icon_id || !humanoid_icon_cache[icon_id]) + var/mob/living/carbon/human/dummy/body = generate_or_wait_for_human_dummy(dummy_key) + + if(prefs) + prefs.copy_to(body,TRUE,FALSE) + if(J) + J.equip(body, TRUE, FALSE, outfit_override = outfit_override) + else if (outfit_override) + body.equipOutfit(outfit_override,visualsOnly = TRUE) + + + var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing") + for(var/D in showDirs) + body.setDir(D) + COMPILE_OVERLAYS(body) + var/icon/partial = getFlatIcon(body) + out_icon.Insert(partial,dir=D) + + humanoid_icon_cache[icon_id] = out_icon + dummy_key? unset_busy_human_dummy(dummy_key) : qdel(body) + return out_icon + else + return humanoid_icon_cache[icon_id] + +//Hook, override to run code on- wait this is images +//Images have dir without being an atom, so they get their own definition. +//Lame. +/image/proc/setDir(newdir) + dir = newdir + +GLOBAL_LIST_INIT(freon_color_matrix, list("#2E5E69", "#60A2A8", "#A1AFB1", rgb(0,0,0))) + +/obj/proc/make_frozen_visual() + // Used to make the frozen item visuals for Freon. + if(resistance_flags & FREEZE_PROOF) + return + if(!(obj_flags & FROZEN)) + name = "frozen [name]" + add_atom_colour(GLOB.freon_color_matrix, TEMPORARY_COLOUR_PRIORITY) + alpha -= 25 + obj_flags |= FROZEN + +//Assumes already frozed +/obj/proc/make_unfrozen() + if(obj_flags & FROZEN) + name = replacetext(name, "frozen ", "") + remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, GLOB.freon_color_matrix) + alpha += 25 + obj_flags &= ~FROZEN + + +//Converts an icon to base64. Operates by putting the icon in the iconCache savefile, +// exporting it as text, and then parsing the base64 from that. +// (This relies on byond automatically storing icons in savefiles as base64) +/proc/icon2base64(icon/icon, iconKey = "misc") + if (!isicon(icon)) + return FALSE + WRITE_FILE(GLOB.iconCache[iconKey], icon) + var/iconData = GLOB.iconCache.ExportText(iconKey) + var/list/partial = splittext(iconData, "{") + return replacetext(copytext(partial[2], 3, -5), "\n", "") + +/proc/icon2html(thing, target, icon_state, dir, frame = 1, moving = FALSE) + if (!thing) + return + + var/key + var/icon/I = thing + if (!target) + return + if (target == world) + target = GLOB.clients + + var/list/targets + if (!islist(target)) + targets = list(target) + else + targets = target + if (!targets.len) + return + if (!isicon(I)) + if (isfile(thing)) //special snowflake + var/name = sanitize_filename("[generate_asset_name(thing)].png") + register_asset(name, thing) + for (var/thing2 in targets) + send_asset(thing2, key, FALSE) + return "" + var/atom/A = thing + if (isnull(dir)) + dir = A.dir + if (isnull(icon_state)) + icon_state = A.icon_state + I = A.icon + if (ishuman(thing)) // Shitty workaround for a BYOND issue. + var/icon/temp = I + I = icon() + I.Insert(temp, dir = SOUTH) + dir = SOUTH + else + if (isnull(dir)) + dir = SOUTH + if (isnull(icon_state)) + icon_state = "" + + I = icon(I, icon_state, dir, frame, moving) + + key = "[generate_asset_name(I)].png" + register_asset(key, I) + for (var/thing2 in targets) + send_asset(thing2, key, FALSE) + + return "" + +/proc/icon2base64html(thing) + if (!thing) + return + var/static/list/bicon_cache = list() + if (isicon(thing)) + var/icon/I = thing + var/icon_base64 = icon2base64(I) + + if (I.Height() > world.icon_size || I.Width() > world.icon_size) + var/icon_md5 = md5(icon_base64) + icon_base64 = bicon_cache[icon_md5] + if (!icon_base64) // Doesn't exist yet, make it. + bicon_cache[icon_md5] = icon_base64 = icon2base64(I) + + + return "" + + // Either an atom or somebody fucked up and is gonna get a runtime, which I'm fine with. + var/atom/A = thing + var/key = "[istype(A.icon, /icon) ? "[REF(A.icon)]" : A.icon]:[A.icon_state]" + + + if (!bicon_cache[key]) // Doesn't exist, make it. + var/icon/I = icon(A.icon, A.icon_state, SOUTH, 1) + if (ishuman(thing)) // Shitty workaround for a BYOND issue. + var/icon/temp = I + I = icon() + I.Insert(temp, dir = SOUTH) + + bicon_cache[key] = icon2base64(I, key) + + return "" + +//Costlier version of icon2html() that uses getFlatIcon() to account for overlays, underlays, etc. Use with extreme moderation, ESPECIALLY on mobs. +/proc/costly_icon2html(thing, target) + if (!thing) + return + + if (isicon(thing)) + return icon2html(thing, target) + + var/icon/I = getFlatIcon(thing) + return icon2html(I, target) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index cdf0f604b8..339069a364 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -1,584 +1,584 @@ -/proc/random_blood_type() - return pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+") - -/proc/random_eye_color() - switch(pick(20;"brown",20;"hazel",20;"grey",15;"blue",15;"green",1;"amber",1;"albino")) - if("brown") - return "630" - if("hazel") - return "542" - if("grey") - return pick("666","777","888","999","aaa","bbb","ccc") - if("blue") - return "36c" - if("green") - return "060" - if("amber") - return "fc0" - if("albino") - return pick("c","d","e","f") + pick("0","1","2","3","4","5","6","7","8","9") + pick("0","1","2","3","4","5","6","7","8","9") - else - return "000" - -/proc/random_underwear(gender) - if(!GLOB.underwear_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/bottom, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f) - switch(gender) - if(MALE) - return pick(GLOB.underwear_m) - if(FEMALE) - return pick(GLOB.underwear_f) - else - return pick(GLOB.underwear_list) - -/proc/random_undershirt(gender) - if(!GLOB.undershirt_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/top, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f) - switch(gender) - if(MALE) - return pick(GLOB.undershirt_m) - if(FEMALE) - return pick(GLOB.undershirt_f) - else - return pick(GLOB.undershirt_list) - -/proc/random_socks() - if(!GLOB.socks_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/socks, GLOB.socks_list) - return pick(GLOB.socks_list) - -/proc/random_features() - if(!GLOB.tails_list_human.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, GLOB.tails_list_human) - if(!GLOB.tails_list_lizard.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, GLOB.tails_list_lizard) - if(!GLOB.snouts_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts, GLOB.snouts_list) - if(!GLOB.horns_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/horns, GLOB.horns_list) - if(!GLOB.ears_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, GLOB.ears_list) - if(!GLOB.frills_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, GLOB.frills_list) - if(!GLOB.spines_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, GLOB.spines_list) - if(!GLOB.legs_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/legs, GLOB.legs_list) - if(!GLOB.body_markings_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.body_markings_list) - if(!GLOB.wings_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.wings_list) - if(!GLOB.deco_wings_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/deco_wings, GLOB.deco_wings_list) - if(!GLOB.insect_wings_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/insect_wings, GLOB.insect_wings_list) - if(!GLOB.insect_fluffs_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/insect_fluff, GLOB.insect_fluffs_list) - if(!GLOB.insect_markings_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/insect_markings, GLOB.insect_markings_list) - - //CIT CHANGES - genitals and such - if(!GLOB.cock_shapes_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list) - if(!GLOB.balls_shapes_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/testicles, GLOB.balls_shapes_list) - if(!GLOB.vagina_shapes_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list) - if(!GLOB.breasts_shapes_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list) - if(!GLOB.ipc_screens_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/screen, GLOB.ipc_screens_list) - if(!GLOB.ipc_antennas_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/antenna, GLOB.ipc_antennas_list) - if(!GLOB.mam_body_markings_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_body_markings, GLOB.mam_body_markings_list) - if(!GLOB.mam_tails_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails, GLOB.mam_tails_list) - if(!GLOB.mam_ears_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_ears, GLOB.mam_ears_list) - if(!GLOB.mam_snouts_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_snouts, GLOB.mam_snouts_list) - - //snowflake check so people's ckey features don't get randomly put on unmonkeys/spawns - var/list/snowflake_mam_tails_list = list() - for(var/mtpath in GLOB.mam_tails_list) - var/datum/sprite_accessory/mam_tails/instance = GLOB.mam_tails_list[mtpath] - if(istype(instance, /datum/sprite_accessory)) - var/datum/sprite_accessory/S = instance - if(!S.ckeys_allowed) - snowflake_mam_tails_list[S.name] = mtpath - var/list/snowflake_markings_list = list() - for(var/mmpath in GLOB.mam_body_markings_list) - var/datum/sprite_accessory/mam_body_markings/instance = GLOB.mam_body_markings_list[mmpath] - if(istype(instance, /datum/sprite_accessory)) - var/datum/sprite_accessory/S = instance - if(!S.ckeys_allowed) - snowflake_markings_list[S.name] = mmpath - var/list/snowflake_ears_list = list() - for(var/mepath in GLOB.mam_ears_list) - var/datum/sprite_accessory/mam_ears/instance = GLOB.mam_ears_list[mepath] - if(istype(instance, /datum/sprite_accessory)) - var/datum/sprite_accessory/S = instance - if(!S.ckeys_allowed) - snowflake_ears_list[S.name] = mepath - var/list/snowflake_mam_snouts_list = list() - for(var/mspath in GLOB.mam_snouts_list) - var/datum/sprite_accessory/mam_snouts/instance = GLOB.mam_snouts_list[mspath] - if(istype(instance, /datum/sprite_accessory)) - var/datum/sprite_accessory/S = instance - if(!S.ckeys_allowed) - snowflake_mam_snouts_list[S.name] = mspath - var/color1 = random_short_color() - var/color2 = random_short_color() - var/color3 = random_short_color() - - //CIT CHANGE - changes this entire return to support cit's snowflake parts - return(list( - "mcolor" = color1, - "mcolor2" = color2, - "mcolor3" = color3, - "tail_lizard" = pick(GLOB.tails_list_lizard), - "tail_human" = "None", - "wings" = "None", - "deco_wings" = "None", - "snout" = pick(GLOB.snouts_list), - "horns" = pick(GLOB.horns_list), - "ears" = "None", - "frills" = pick(GLOB.frills_list), - "spines" = pick(GLOB.spines_list), - "body_markings" = pick(GLOB.body_markings_list), - "legs" = pick("Plantigrade","Digitigrade"), - "caps" = pick(GLOB.caps_list), - "insect_wings" = pick(GLOB.insect_wings_list), - "insect_fluff" = "None", - "insect_markings" = pick(GLOB.insect_markings_list), - "taur" = "None", - "mam_body_markings" = pick(snowflake_markings_list), - "mam_ears" = pick(snowflake_ears_list), - "mam_snouts" = pick(snowflake_mam_snouts_list), - "mam_tail" = pick(snowflake_mam_tails_list), - "mam_tail_animated" = "None", - "xenodorsal" = "Standard", - "xenohead" = "Standard", - "xenotail" = "Xenomorph Tail", - "genitals_use_skintone" = FALSE, - "has_cock" = FALSE, - "cock_shape" = pick(GLOB.cock_shapes_list), - "cock_length" = 6, - "cock_girth_ratio" = COCK_GIRTH_RATIO_DEF, - "cock_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), - "has_sheath" = FALSE, - "sheath_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), - "has_balls" = FALSE, - "balls_internal" = FALSE, - "balls_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), - "balls_amount" = 2, - "balls_sack_size" = BALLS_SACK_SIZE_DEF, - "balls_size" = BALLS_SIZE_DEF, - "balls_shape" = "Single", - "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" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), - "has_eggsack" = FALSE, - "eggsack_internal" = TRUE, - "eggsack_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), - "eggsack_size" = BALLS_SACK_SIZE_DEF, - "eggsack_egg_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), - "eggsack_egg_size" = EGG_GIRTH_DEF, - "has_breasts" = FALSE, - "breasts_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), - "breasts_size" = pick(GLOB.breasts_size_list), - "breasts_shape" = "Pair", - "breasts_fluid" = "milk", - "breasts_producing" = FALSE, - "has_vag" = FALSE, - "vag_shape" = pick(GLOB.vagina_shapes_list), - "vag_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), - "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", - "ipc_screen" = "Sunburst", - "ipc_antenna" = "None", - "flavor_text" = "", - "meat_type" = "Mammalian" - )) - -/proc/random_hair_style(gender) - switch(gender) - if(MALE) - return pick(GLOB.hair_styles_male_list) - if(FEMALE) - return pick(GLOB.hair_styles_female_list) - else - return pick(GLOB.hair_styles_list) - -/proc/random_facial_hair_style(gender) - switch(gender) - if(MALE) - return pick(GLOB.facial_hair_styles_male_list) - if(FEMALE) - return pick(GLOB.facial_hair_styles_female_list) - else - return pick(GLOB.facial_hair_styles_list) - -/proc/random_unique_name(gender, attempts_to_find_unique_name=10) - for(var/i in 1 to attempts_to_find_unique_name) - if(gender==FEMALE) - . = capitalize(pick(GLOB.first_names_female)) + " " + capitalize(pick(GLOB.last_names)) - else - . = capitalize(pick(GLOB.first_names_male)) + " " + capitalize(pick(GLOB.last_names)) - - if(!findname(.)) - break - -/proc/random_unique_lizard_name(gender, attempts_to_find_unique_name=10) - for(var/i in 1 to attempts_to_find_unique_name) - . = capitalize(lizard_name(gender)) - - if(!findname(.)) - break - -/proc/random_unique_plasmaman_name(attempts_to_find_unique_name=10) - for(var/i in 1 to attempts_to_find_unique_name) - . = capitalize(plasmaman_name()) - - if(!findname(.)) - break - -/proc/random_unique_moth_name(attempts_to_find_unique_name=10) - for(var/i in 1 to attempts_to_find_unique_name) - . = capitalize(pick(GLOB.moth_first)) + " " + capitalize(pick(GLOB.moth_last)) - - if(!findname(.)) - break - -/proc/random_skin_tone() - return pick(GLOB.skin_tones) - -GLOBAL_LIST_INIT(skin_tones, list( - "albino", - "caucasian1", - "caucasian2", - "caucasian3", - "latino", - "mediterranean", - "asian1", - "asian2", - "arab", - "indian", - "african1", - "african2" - )) - -GLOBAL_LIST_EMPTY(species_list) - -/proc/age2agedescription(age) - switch(age) - if(0 to 1) - return "infant" - if(1 to 3) - return "toddler" - if(3 to 13) - return "child" - if(13 to 19) - return "teenager" - if(19 to 30) - return "young adult" - if(30 to 45) - return "adult" - if(45 to 60) - return "middle-aged" - if(60 to 70) - return "aging" - if(70 to INFINITY) - return "elderly" - else - return "unknown" - -/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks = null, ignorehelditem = 0) - if(!user || !target) - return 0 - var/user_loc = user.loc - - var/drifting = 0 - if(!user.Process_Spacemove(0) && user.inertia_dir) - drifting = 1 - - var/target_loc = target.loc - - var/holding = user.get_active_held_item() - var/datum/progressbar/progbar - if (progress) - progbar = new(user, time, target) - - var/endtime = world.time+time - var/starttime = world.time - . = 1 - while (world.time < endtime) - stoplag(1) - if (progress) - progbar.update(world.time - starttime) - if(QDELETED(user) || QDELETED(target)) - . = 0 - break - if(uninterruptible) - continue - - if(drifting && !user.inertia_dir) - drifting = 0 - user_loc = user.loc - - if((!drifting && user.loc != user_loc) || target.loc != target_loc || (!ignorehelditem && user.get_active_held_item() != holding) || user.incapacitated() || user.lying || (extra_checks && !extra_checks.Invoke())) - . = 0 - break - if (progress) - 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 ..() - -/proc/do_after(mob/user, var/delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null) - if(!user) - return 0 - var/atom/Tloc = null - if(target && !isturf(target)) - Tloc = target.loc - - var/atom/Uloc = user.loc - - var/drifting = 0 - if(!user.Process_Spacemove(0) && user.inertia_dir) - drifting = 1 - - var/holding = user.get_active_held_item() - - var/holdingnull = 1 //User's hand started out empty, check for an empty hand - if(holding) - holdingnull = 0 //Users hand started holding something, check to see if it's still holding that - - delay *= user.do_after_coefficent() - - var/datum/progressbar/progbar - if (progress) - progbar = new(user, delay, target) - - var/endtime = world.time + delay - var/starttime = world.time - . = 1 - while (world.time < endtime) - stoplag(1) - if (progress) - progbar.update(world.time - starttime) - - if(drifting && !user.inertia_dir) - drifting = 0 - Uloc = user.loc - - if(QDELETED(user) || user.stat || user.IsKnockdown() || user.IsStun() || (!drifting && user.loc != Uloc) || (extra_checks && !extra_checks.Invoke())) - . = 0 - break - - if(isliving(user)) - var/mob/living/L = user - if(L.recoveringstam) - . = 0 - break - - if(!QDELETED(Tloc) && (QDELETED(target) || Tloc != target.loc)) - if((Uloc != Tloc || Tloc != user) && !drifting) - . = 0 - break - - if(needhand) - //This might seem like an odd check, but you can still need a hand even when it's empty - //i.e the hand is used to pull some item/tool out of the construction - if(!holdingnull) - if(!holding) - . = 0 - break - if(user.get_active_held_item() != holding) - . = 0 - break - if (progress) - qdel(progbar) - -/mob/proc/do_after_coefficent() // This gets added to the delay on a do_after, default 1 - . = 1 - return - -/proc/do_after_mob(mob/user, var/list/targets, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks) - if(!user || !targets) - return 0 - if(!islist(targets)) - targets = list(targets) - var/user_loc = user.loc - - var/drifting = 0 - if(!user.Process_Spacemove(0) && user.inertia_dir) - drifting = 1 - - var/list/originalloc = list() - for(var/atom/target in targets) - originalloc[target] = target.loc - - var/holding = user.get_active_held_item() - var/datum/progressbar/progbar - if(progress) - progbar = new(user, time, targets[1]) - - var/endtime = world.time + time - var/starttime = world.time - . = 1 - mainloop: - while(world.time < endtime) - stoplag(1) - if(progress) - progbar.update(world.time - starttime) - if(QDELETED(user) || !targets) - . = 0 - break - if(uninterruptible) - continue - - if(drifting && !user.inertia_dir) - drifting = 0 - user_loc = user.loc - - for(var/atom/target in targets) - if((!drifting && user_loc != user.loc) || QDELETED(target) || originalloc[target] != target.loc || user.get_active_held_item() != holding || user.incapacitated() || user.lying || (extra_checks && !extra_checks.Invoke())) - . = 0 - break mainloop - if(progbar) - qdel(progbar) - -/proc/is_species(A, species_datum) - . = FALSE - if(ishuman(A)) - var/mob/living/carbon/human/H = A - if(H.dna && istype(H.dna.species, species_datum)) - . = TRUE - -/proc/spawn_atom_to_turf(spawn_type, target, amount, admin_spawn=FALSE, list/extra_args) - var/turf/T = get_turf(target) - if(!T) - CRASH("attempt to spawn atom type: [spawn_type] in nullspace") - - var/list/new_args = list(T) - if(extra_args) - new_args += extra_args - - for(var/j in 1 to amount) - var/atom/X = new spawn_type(arglist(new_args)) - if (admin_spawn) - X.flags_1 |= ADMIN_SPAWNED_1 - -/proc/spawn_and_random_walk(spawn_type, target, amount, walk_chance=100, max_walk=3, always_max_walk=FALSE, admin_spawn=FALSE) - var/turf/T = get_turf(target) - var/step_count = 0 - if(!T) - CRASH("attempt to spawn atom type: [spawn_type] in nullspace") - - for(var/j in 1 to amount) - var/atom/movable/X = new spawn_type(T) - if (admin_spawn) - X.flags_1 |= ADMIN_SPAWNED_1 - - if(always_max_walk || prob(walk_chance)) - if(always_max_walk) - step_count = max_walk - else - step_count = rand(1, max_walk) - - for(var/i in 1 to step_count) - step(X, pick(NORTH, SOUTH, EAST, WEST)) - -/proc/deadchat_broadcast(message, mob/follow_target=null, turf/turf_target=null, speaker_key=null, message_type=DEADCHAT_REGULAR) - message = "[message]" - for(var/mob/M in GLOB.player_list) - var/datum/preferences/prefs - if(M.client && M.client.prefs) - prefs = M.client.prefs - else - prefs = new - - var/override = FALSE - if(M.client && M.client.holder && (prefs.chat_toggles & CHAT_DEAD)) - override = TRUE - if(HAS_TRAIT(M, TRAIT_SIXTHSENSE)) - override = TRUE - if(isnewplayer(M) && !override) - continue - if(M.stat != DEAD && !override) - continue - if(speaker_key && speaker_key in prefs.ignoring) - continue - - switch(message_type) - if(DEADCHAT_DEATHRATTLE) - if(prefs.toggles & DISABLE_DEATHRATTLE) - continue - if(DEADCHAT_ARRIVALRATTLE) - if(prefs.toggles & DISABLE_ARRIVALRATTLE) - continue - - if(isobserver(M)) - var/rendered_message = message - - if(follow_target) - var/F - if(turf_target) - F = FOLLOW_OR_TURF_LINK(M, follow_target, turf_target) - else - F = FOLLOW_LINK(M, follow_target) - rendered_message = "[F] [message]" - else if(turf_target) - var/turf_link = TURF_LINK(M, turf_target) - rendered_message = "[turf_link] [message]" - - to_chat(M, rendered_message) - else - to_chat(M, message) - -//Used in chemical_mob_spawn. Generates a random mob based on a given gold_core_spawnable value. -/proc/create_random_mob(spawn_location, mob_class = HOSTILE_SPAWN) - var/static/list/mob_spawn_meancritters = list() // list of possible hostile mobs - var/static/list/mob_spawn_nicecritters = list() // and possible friendly mobs - - if(mob_spawn_meancritters.len <= 0 || mob_spawn_nicecritters.len <= 0) - for(var/T in typesof(/mob/living/simple_animal)) - var/mob/living/simple_animal/SA = T - switch(initial(SA.gold_core_spawnable)) - if(HOSTILE_SPAWN) - mob_spawn_meancritters += T - if(FRIENDLY_SPAWN) - mob_spawn_nicecritters += T - - var/chosen - if(mob_class == FRIENDLY_SPAWN) - chosen = pick(mob_spawn_nicecritters) - else - chosen = pick(mob_spawn_meancritters) - var/mob/living/simple_animal/C = new chosen(spawn_location) - return C +/proc/random_blood_type() + return pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+") + +/proc/random_eye_color() + switch(pick(20;"brown",20;"hazel",20;"grey",15;"blue",15;"green",1;"amber",1;"albino")) + if("brown") + return "630" + if("hazel") + return "542" + if("grey") + return pick("666","777","888","999","aaa","bbb","ccc") + if("blue") + return "36c" + if("green") + return "060" + if("amber") + return "fc0" + if("albino") + return pick("c","d","e","f") + pick("0","1","2","3","4","5","6","7","8","9") + pick("0","1","2","3","4","5","6","7","8","9") + else + return "000" + +/proc/random_underwear(gender) + if(!GLOB.underwear_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/bottom, GLOB.underwear_list, GLOB.underwear_m, GLOB.underwear_f) + switch(gender) + if(MALE) + return pick(GLOB.underwear_m) + if(FEMALE) + return pick(GLOB.underwear_f) + else + return pick(GLOB.underwear_list) + +/proc/random_undershirt(gender) + if(!GLOB.undershirt_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/top, GLOB.undershirt_list, GLOB.undershirt_m, GLOB.undershirt_f) + switch(gender) + if(MALE) + return pick(GLOB.undershirt_m) + if(FEMALE) + return pick(GLOB.undershirt_f) + else + return pick(GLOB.undershirt_list) + +/proc/random_socks() + if(!GLOB.socks_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/socks, GLOB.socks_list) + return pick(GLOB.socks_list) + +/proc/random_features() + if(!GLOB.tails_list_human.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, GLOB.tails_list_human) + if(!GLOB.tails_list_lizard.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, GLOB.tails_list_lizard) + if(!GLOB.snouts_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts, GLOB.snouts_list) + if(!GLOB.horns_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/horns, GLOB.horns_list) + if(!GLOB.ears_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, GLOB.ears_list) + if(!GLOB.frills_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, GLOB.frills_list) + if(!GLOB.spines_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, GLOB.spines_list) + if(!GLOB.legs_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/legs, GLOB.legs_list) + if(!GLOB.body_markings_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, GLOB.body_markings_list) + if(!GLOB.wings_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, GLOB.wings_list) + if(!GLOB.deco_wings_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/deco_wings, GLOB.deco_wings_list) + if(!GLOB.insect_wings_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/insect_wings, GLOB.insect_wings_list) + if(!GLOB.insect_fluffs_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/insect_fluff, GLOB.insect_fluffs_list) + if(!GLOB.insect_markings_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/insect_markings, GLOB.insect_markings_list) + + //CIT CHANGES - genitals and such + if(!GLOB.cock_shapes_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, GLOB.cock_shapes_list) + if(!GLOB.balls_shapes_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/testicles, GLOB.balls_shapes_list) + if(!GLOB.vagina_shapes_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list) + if(!GLOB.breasts_shapes_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list) + if(!GLOB.ipc_screens_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/screen, GLOB.ipc_screens_list) + if(!GLOB.ipc_antennas_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/antenna, GLOB.ipc_antennas_list) + if(!GLOB.mam_body_markings_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_body_markings, GLOB.mam_body_markings_list) + if(!GLOB.mam_tails_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails, GLOB.mam_tails_list) + if(!GLOB.mam_ears_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_ears, GLOB.mam_ears_list) + if(!GLOB.mam_snouts_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_snouts, GLOB.mam_snouts_list) + + //snowflake check so people's ckey features don't get randomly put on unmonkeys/spawns + var/list/snowflake_mam_tails_list = list() + for(var/mtpath in GLOB.mam_tails_list) + var/datum/sprite_accessory/mam_tails/instance = GLOB.mam_tails_list[mtpath] + if(istype(instance, /datum/sprite_accessory)) + var/datum/sprite_accessory/S = instance + if(!S.ckeys_allowed) + snowflake_mam_tails_list[S.name] = mtpath + var/list/snowflake_markings_list = list() + for(var/mmpath in GLOB.mam_body_markings_list) + var/datum/sprite_accessory/mam_body_markings/instance = GLOB.mam_body_markings_list[mmpath] + if(istype(instance, /datum/sprite_accessory)) + var/datum/sprite_accessory/S = instance + if(!S.ckeys_allowed) + snowflake_markings_list[S.name] = mmpath + var/list/snowflake_ears_list = list() + for(var/mepath in GLOB.mam_ears_list) + var/datum/sprite_accessory/mam_ears/instance = GLOB.mam_ears_list[mepath] + if(istype(instance, /datum/sprite_accessory)) + var/datum/sprite_accessory/S = instance + if(!S.ckeys_allowed) + snowflake_ears_list[S.name] = mepath + var/list/snowflake_mam_snouts_list = list() + for(var/mspath in GLOB.mam_snouts_list) + var/datum/sprite_accessory/mam_snouts/instance = GLOB.mam_snouts_list[mspath] + if(istype(instance, /datum/sprite_accessory)) + var/datum/sprite_accessory/S = instance + if(!S.ckeys_allowed) + snowflake_mam_snouts_list[S.name] = mspath + var/color1 = random_short_color() + var/color2 = random_short_color() + var/color3 = random_short_color() + + //CIT CHANGE - changes this entire return to support cit's snowflake parts + return(list( + "mcolor" = color1, + "mcolor2" = color2, + "mcolor3" = color3, + "tail_lizard" = pick(GLOB.tails_list_lizard), + "tail_human" = "None", + "wings" = "None", + "deco_wings" = "None", + "snout" = pick(GLOB.snouts_list), + "horns" = pick(GLOB.horns_list), + "ears" = "None", + "frills" = pick(GLOB.frills_list), + "spines" = pick(GLOB.spines_list), + "body_markings" = pick(GLOB.body_markings_list), + "legs" = pick("Plantigrade","Digitigrade"), + "caps" = pick(GLOB.caps_list), + "insect_wings" = pick(GLOB.insect_wings_list), + "insect_fluff" = "None", + "insect_markings" = pick(GLOB.insect_markings_list), + "taur" = "None", + "mam_body_markings" = pick(snowflake_markings_list), + "mam_ears" = pick(snowflake_ears_list), + "mam_snouts" = pick(snowflake_mam_snouts_list), + "mam_tail" = pick(snowflake_mam_tails_list), + "mam_tail_animated" = "None", + "xenodorsal" = "Standard", + "xenohead" = "Standard", + "xenotail" = "Xenomorph Tail", + "genitals_use_skintone" = FALSE, + "has_cock" = FALSE, + "cock_shape" = pick(GLOB.cock_shapes_list), + "cock_length" = 6, + "cock_girth_ratio" = COCK_GIRTH_RATIO_DEF, + "cock_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + "has_sheath" = FALSE, + "sheath_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + "has_balls" = FALSE, + "balls_internal" = FALSE, + "balls_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + "balls_amount" = 2, + "balls_sack_size" = BALLS_SACK_SIZE_DEF, + "balls_size" = BALLS_SIZE_DEF, + "balls_shape" = "Single", + "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" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + "has_eggsack" = FALSE, + "eggsack_internal" = TRUE, + "eggsack_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + "eggsack_size" = BALLS_SACK_SIZE_DEF, + "eggsack_egg_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + "eggsack_egg_size" = EGG_GIRTH_DEF, + "has_breasts" = FALSE, + "breasts_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + "breasts_size" = pick(GLOB.breasts_size_list), + "breasts_shape" = "Pair", + "breasts_fluid" = "milk", + "breasts_producing" = FALSE, + "has_vag" = FALSE, + "vag_shape" = pick(GLOB.vagina_shapes_list), + "vag_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + "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", + "ipc_screen" = "Sunburst", + "ipc_antenna" = "None", + "flavor_text" = "", + "meat_type" = "Mammalian" + )) + +/proc/random_hair_style(gender) + switch(gender) + if(MALE) + return pick(GLOB.hair_styles_male_list) + if(FEMALE) + return pick(GLOB.hair_styles_female_list) + else + return pick(GLOB.hair_styles_list) + +/proc/random_facial_hair_style(gender) + switch(gender) + if(MALE) + return pick(GLOB.facial_hair_styles_male_list) + if(FEMALE) + return pick(GLOB.facial_hair_styles_female_list) + else + return pick(GLOB.facial_hair_styles_list) + +/proc/random_unique_name(gender, attempts_to_find_unique_name=10) + for(var/i in 1 to attempts_to_find_unique_name) + if(gender==FEMALE) + . = capitalize(pick(GLOB.first_names_female)) + " " + capitalize(pick(GLOB.last_names)) + else + . = capitalize(pick(GLOB.first_names_male)) + " " + capitalize(pick(GLOB.last_names)) + + if(!findname(.)) + break + +/proc/random_unique_lizard_name(gender, attempts_to_find_unique_name=10) + for(var/i in 1 to attempts_to_find_unique_name) + . = capitalize(lizard_name(gender)) + + if(!findname(.)) + break + +/proc/random_unique_plasmaman_name(attempts_to_find_unique_name=10) + for(var/i in 1 to attempts_to_find_unique_name) + . = capitalize(plasmaman_name()) + + if(!findname(.)) + break + +/proc/random_unique_moth_name(attempts_to_find_unique_name=10) + for(var/i in 1 to attempts_to_find_unique_name) + . = capitalize(pick(GLOB.moth_first)) + " " + capitalize(pick(GLOB.moth_last)) + + if(!findname(.)) + break + +/proc/random_skin_tone() + return pick(GLOB.skin_tones) + +GLOBAL_LIST_INIT(skin_tones, list( + "albino", + "caucasian1", + "caucasian2", + "caucasian3", + "latino", + "mediterranean", + "asian1", + "asian2", + "arab", + "indian", + "african1", + "african2" + )) + +GLOBAL_LIST_EMPTY(species_list) + +/proc/age2agedescription(age) + switch(age) + if(0 to 1) + return "infant" + if(1 to 3) + return "toddler" + if(3 to 13) + return "child" + if(13 to 19) + return "teenager" + if(19 to 30) + return "young adult" + if(30 to 45) + return "adult" + if(45 to 60) + return "middle-aged" + if(60 to 70) + return "aging" + if(70 to INFINITY) + return "elderly" + else + return "unknown" + +/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks = null, ignorehelditem = 0) + if(!user || !target) + return 0 + var/user_loc = user.loc + + var/drifting = 0 + if(!user.Process_Spacemove(0) && user.inertia_dir) + drifting = 1 + + var/target_loc = target.loc + + var/holding = user.get_active_held_item() + var/datum/progressbar/progbar + if (progress) + progbar = new(user, time, target) + + var/endtime = world.time+time + var/starttime = world.time + . = 1 + while (world.time < endtime) + stoplag(1) + if (progress) + progbar.update(world.time - starttime) + if(QDELETED(user) || QDELETED(target)) + . = 0 + break + if(uninterruptible) + continue + + if(drifting && !user.inertia_dir) + drifting = 0 + user_loc = user.loc + + if((!drifting && user.loc != user_loc) || target.loc != target_loc || (!ignorehelditem && user.get_active_held_item() != holding) || user.incapacitated() || user.lying || (extra_checks && !extra_checks.Invoke())) + . = 0 + break + if (progress) + 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 ..() + +/proc/do_after(mob/user, var/delay, needhand = 1, atom/target = null, progress = 1, datum/callback/extra_checks = null) + if(!user) + return 0 + var/atom/Tloc = null + if(target && !isturf(target)) + Tloc = target.loc + + var/atom/Uloc = user.loc + + var/drifting = 0 + if(!user.Process_Spacemove(0) && user.inertia_dir) + drifting = 1 + + var/holding = user.get_active_held_item() + + var/holdingnull = 1 //User's hand started out empty, check for an empty hand + if(holding) + holdingnull = 0 //Users hand started holding something, check to see if it's still holding that + + delay *= user.do_after_coefficent() + + var/datum/progressbar/progbar + if (progress) + progbar = new(user, delay, target) + + var/endtime = world.time + delay + var/starttime = world.time + . = 1 + while (world.time < endtime) + stoplag(1) + if (progress) + progbar.update(world.time - starttime) + + if(drifting && !user.inertia_dir) + drifting = 0 + Uloc = user.loc + + if(QDELETED(user) || user.stat || user.IsKnockdown() || user.IsStun() || (!drifting && user.loc != Uloc) || (extra_checks && !extra_checks.Invoke())) + . = 0 + break + + if(isliving(user)) + var/mob/living/L = user + if(L.recoveringstam) + . = 0 + break + + if(!QDELETED(Tloc) && (QDELETED(target) || Tloc != target.loc)) + if((Uloc != Tloc || Tloc != user) && !drifting) + . = 0 + break + + if(needhand) + //This might seem like an odd check, but you can still need a hand even when it's empty + //i.e the hand is used to pull some item/tool out of the construction + if(!holdingnull) + if(!holding) + . = 0 + break + if(user.get_active_held_item() != holding) + . = 0 + break + if (progress) + qdel(progbar) + +/mob/proc/do_after_coefficent() // This gets added to the delay on a do_after, default 1 + . = 1 + return + +/proc/do_after_mob(mob/user, var/list/targets, time = 30, uninterruptible = 0, progress = 1, datum/callback/extra_checks) + if(!user || !targets) + return 0 + if(!islist(targets)) + targets = list(targets) + var/user_loc = user.loc + + var/drifting = 0 + if(!user.Process_Spacemove(0) && user.inertia_dir) + drifting = 1 + + var/list/originalloc = list() + for(var/atom/target in targets) + originalloc[target] = target.loc + + var/holding = user.get_active_held_item() + var/datum/progressbar/progbar + if(progress) + progbar = new(user, time, targets[1]) + + var/endtime = world.time + time + var/starttime = world.time + . = 1 + mainloop: + while(world.time < endtime) + stoplag(1) + if(progress) + progbar.update(world.time - starttime) + if(QDELETED(user) || !targets) + . = 0 + break + if(uninterruptible) + continue + + if(drifting && !user.inertia_dir) + drifting = 0 + user_loc = user.loc + + for(var/atom/target in targets) + if((!drifting && user_loc != user.loc) || QDELETED(target) || originalloc[target] != target.loc || user.get_active_held_item() != holding || user.incapacitated() || user.lying || (extra_checks && !extra_checks.Invoke())) + . = 0 + break mainloop + if(progbar) + qdel(progbar) + +/proc/is_species(A, species_datum) + . = FALSE + if(ishuman(A)) + var/mob/living/carbon/human/H = A + if(H.dna && istype(H.dna.species, species_datum)) + . = TRUE + +/proc/spawn_atom_to_turf(spawn_type, target, amount, admin_spawn=FALSE, list/extra_args) + var/turf/T = get_turf(target) + if(!T) + CRASH("attempt to spawn atom type: [spawn_type] in nullspace") + + var/list/new_args = list(T) + if(extra_args) + new_args += extra_args + + for(var/j in 1 to amount) + var/atom/X = new spawn_type(arglist(new_args)) + if (admin_spawn) + X.flags_1 |= ADMIN_SPAWNED_1 + +/proc/spawn_and_random_walk(spawn_type, target, amount, walk_chance=100, max_walk=3, always_max_walk=FALSE, admin_spawn=FALSE) + var/turf/T = get_turf(target) + var/step_count = 0 + if(!T) + CRASH("attempt to spawn atom type: [spawn_type] in nullspace") + + for(var/j in 1 to amount) + var/atom/movable/X = new spawn_type(T) + if (admin_spawn) + X.flags_1 |= ADMIN_SPAWNED_1 + + if(always_max_walk || prob(walk_chance)) + if(always_max_walk) + step_count = max_walk + else + step_count = rand(1, max_walk) + + for(var/i in 1 to step_count) + step(X, pick(NORTH, SOUTH, EAST, WEST)) + +/proc/deadchat_broadcast(message, mob/follow_target=null, turf/turf_target=null, speaker_key=null, message_type=DEADCHAT_REGULAR) + message = "[message]" + for(var/mob/M in GLOB.player_list) + var/datum/preferences/prefs + if(M.client && M.client.prefs) + prefs = M.client.prefs + else + prefs = new + + var/override = FALSE + if(M.client && M.client.holder && (prefs.chat_toggles & CHAT_DEAD)) + override = TRUE + if(HAS_TRAIT(M, TRAIT_SIXTHSENSE)) + override = TRUE + if(isnewplayer(M) && !override) + continue + if(M.stat != DEAD && !override) + continue + if(speaker_key && speaker_key in prefs.ignoring) + continue + + switch(message_type) + if(DEADCHAT_DEATHRATTLE) + if(prefs.toggles & DISABLE_DEATHRATTLE) + continue + if(DEADCHAT_ARRIVALRATTLE) + if(prefs.toggles & DISABLE_ARRIVALRATTLE) + continue + + if(isobserver(M)) + var/rendered_message = message + + if(follow_target) + var/F + if(turf_target) + F = FOLLOW_OR_TURF_LINK(M, follow_target, turf_target) + else + F = FOLLOW_LINK(M, follow_target) + rendered_message = "[F] [message]" + else if(turf_target) + var/turf_link = TURF_LINK(M, turf_target) + rendered_message = "[turf_link] [message]" + + to_chat(M, rendered_message) + else + to_chat(M, message) + +//Used in chemical_mob_spawn. Generates a random mob based on a given gold_core_spawnable value. +/proc/create_random_mob(spawn_location, mob_class = HOSTILE_SPAWN) + var/static/list/mob_spawn_meancritters = list() // list of possible hostile mobs + var/static/list/mob_spawn_nicecritters = list() // and possible friendly mobs + + if(mob_spawn_meancritters.len <= 0 || mob_spawn_nicecritters.len <= 0) + for(var/T in typesof(/mob/living/simple_animal)) + var/mob/living/simple_animal/SA = T + switch(initial(SA.gold_core_spawnable)) + if(HOSTILE_SPAWN) + mob_spawn_meancritters += T + if(FRIENDLY_SPAWN) + mob_spawn_nicecritters += T + + var/chosen + if(mob_class == FRIENDLY_SPAWN) + chosen = pick(mob_spawn_nicecritters) + else + chosen = pick(mob_spawn_meancritters) + var/mob/living/simple_animal/C = new chosen(spawn_location) + return C diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm index db2eba2422..8b699e3eee 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -1,248 +1,248 @@ -/proc/lizard_name(gender) - if(gender == MALE) - return "[pick(GLOB.lizard_names_male)]-[pick(GLOB.lizard_names_male)]" - else - return "[pick(GLOB.lizard_names_female)]-[pick(GLOB.lizard_names_female)]" - -/proc/plasmaman_name() - return "[pick(GLOB.plasmaman_names)] \Roman[rand(1,99)]" - -/proc/moth_name() - return "[pick(GLOB.moth_first)] [pick(GLOB.moth_last)]" - -/proc/church_name() - var/static/church_name - if (church_name) - return church_name - - var/name = "" - - name += pick("Holy", "United", "First", "Second", "Last") - - if (prob(20)) - name += " Space" - - name += " " + pick("Church", "Cathedral", "Body", "Worshippers", "Movement", "Witnesses") - name += " of [religion_name()]" - - return name - -GLOBAL_VAR(command_name) -/proc/command_name() - if (GLOB.command_name) - return GLOB.command_name - - var/name = "Central Command" - - GLOB.command_name = name - return name - -/proc/change_command_name(name) - - GLOB.command_name = name - - return name - -/proc/religion_name() - var/static/religion_name - if (religion_name) - return religion_name - - var/name = "" - - name += pick("bee", "science", "edu", "captain", "assistant", "monkey", "alien", "space", "unit", "sprocket", "gadget", "bomb", "revolution", "beyond", "station", "goon", "robot", "ivor", "hobnob") - name += pick("ism", "ia", "ology", "istism", "ites", "ick", "ian", "ity") - - return capitalize(name) - -/proc/station_name() - if(!GLOB.station_name) - var/newname - var/config_station_name = CONFIG_GET(string/stationname) - if(config_station_name) - newname = config_station_name - else - newname = new_station_name() - - set_station_name(newname) - - return GLOB.station_name - -/proc/set_station_name(newname) - GLOB.station_name = newname - - var/config_server_name = CONFIG_GET(string/servername) - if(config_server_name) - world.name = "[config_server_name][config_server_name == GLOB.station_name ? "" : ": [GLOB.station_name]"]" - else - world.name = GLOB.station_name - - -/proc/new_station_name() - var/random = rand(1,5) - var/name = "" - var/new_station_name = "" - - //Rare: Pre-Prefix - if (prob(10)) - name = pick(GLOB.station_prefixes) - new_station_name = name + " " - name = "" - - // Prefix - for(var/holiday_name in SSevents.holidays) - if(holiday_name == "Friday the 13th") - random = 13 - var/datum/holiday/holiday = SSevents.holidays[holiday_name] - name = holiday.getStationPrefix() - //get normal name - if(!name) - name = pick(GLOB.station_names) - if(name) - new_station_name += name + " " - - // Suffix - name = pick(GLOB.station_suffixes) - new_station_name += name + " " - - // ID Number - switch(random) - if(1) - new_station_name += "[rand(1, 99)]" - if(2) - new_station_name += pick(GLOB.greek_letters) - if(3) - new_station_name += "\Roman[rand(1,99)]" - if(4) - new_station_name += pick(GLOB.phonetic_alphabet) - if(5) - new_station_name += pick(GLOB.numbers_as_words) - if(13) - new_station_name += pick("13","XIII","Thirteen") - return new_station_name - -/proc/syndicate_name() - var/name = "" - - // Prefix - name += pick("Clandestine", "Prima", "Blue", "Zero-G", "Max", "Blasto", "Waffle", "North", "Omni", "Newton", "Cyber", "Bonk", "Gene", "Gib") - - // Suffix - if (prob(80)) - name += " " - - // Full - if (prob(60)) - name += pick("Syndicate", "Consortium", "Collective", "Corporation", "Group", "Holdings", "Biotech", "Industries", "Systems", "Products", "Chemicals", "Enterprises", "Family", "Creations", "International", "Intergalactic", "Interplanetary", "Foundation", "Positronics", "Hive") - // Broken - else - name += pick("Syndi", "Corp", "Bio", "System", "Prod", "Chem", "Inter", "Hive") - name += pick("", "-") - name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Code") - // Small - else - name += pick("-", "*", "") - name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Gen", "Star", "Dyne", "Code", "Hive") - - return name - - -//Traitors and traitor silicons will get these. Revs will not. -GLOBAL_VAR(syndicate_code_phrase) //Code phrase for traitors. -GLOBAL_VAR(syndicate_code_response) //Code response for traitors. - -//Cached regex search - for checking if codewords are used. -GLOBAL_DATUM(syndicate_code_phrase_regex, /regex) -GLOBAL_DATUM(syndicate_code_response_regex, /regex) - - /* - Should be expanded. - How this works: - Instead of "I'm looking for James Smith," the traitor would say "James Smith" as part of a conversation. - Another traitor may then respond with: "They enjoy running through the void-filled vacuum of the derelict." - The phrase should then have the words: James Smith. - The response should then have the words: run, void, and derelict. - This way assures that the code is suited to the conversation and is unpredicatable. - Obviously, some people will be better at this than others but in theory, everyone should be able to do it and it only enhances roleplay. - Can probably be done through "{ }" but I don't really see the practical benefit. - One example of an earlier system is commented below. - /N - */ - -/proc/generate_code_phrase(return_list=FALSE)//Proc is used for phrase and response in master_controller.dm - - if(!return_list) - . = "" - else - . = list() - - var/words = pick(//How many words there will be. Minimum of two. 2, 4 and 5 have a lesser chance of being selected. 3 is the most likely. - 50; 2, - 200; 3, - 50; 4, - 25; 5 - ) - - var/list/safety = list(1,2,3)//Tells the proc which options to remove later on. - var/nouns = strings(ION_FILE, "ionabstract") - var/objects = strings(ION_FILE, "ionobjects") - var/adjectives = strings(ION_FILE, "ionadjectives") - var/threats = strings(ION_FILE, "ionthreats") - var/foods = strings(ION_FILE, "ionfood") - var/drinks = strings(ION_FILE, "iondrinks") - var/list/locations = GLOB.teleportlocs.len ? GLOB.teleportlocs : drinks //if null, defaults to drinks instead. - - var/list/names = list() - for(var/datum/data/record/t in GLOB.data_core.general)//Picks from crew manifest. - names += t.fields["name"] - - var/maxwords = words//Extra var to check for duplicates. - - for(words,words>0,words--)//Randomly picks from one of the choices below. - - if(words==1&&(1 in safety)&&(2 in safety))//If there is only one word remaining and choice 1 or 2 have not been selected. - safety = list(pick(1,2))//Select choice 1 or 2. - else if(words==1&&maxwords==2)//Else if there is only one word remaining (and there were two originally), and 1 or 2 were chosen, - safety = list(3)//Default to list 3 - - switch(pick(safety))//Chance based on the safety list. - if(1)//1 and 2 can only be selected once each to prevent more than two specific names/places/etc. - switch(rand(1,2))//Mainly to add more options later. - if(1) - if(names.len&&prob(70)) - . += pick(names) - else - if(prob(10)) - . += pick(lizard_name(MALE),lizard_name(FEMALE)) - else - var/new_name = pick(pick(GLOB.first_names_male,GLOB.first_names_female)) - new_name += " " - new_name += pick(GLOB.last_names) - . += new_name - if(2) - . += pick(get_all_jobs())//Returns a job. - safety -= 1 - if(2) - switch(rand(1,3))//Food, drinks, or things. Only selectable once. - if(1) - . += lowertext(pick(drinks)) - if(2) - . += lowertext(pick(foods)) - if(3) - . += lowertext(pick(locations)) - safety -= 2 - if(3) - switch(rand(1,4))//Abstract nouns, objects, adjectives, threats. Can be selected more than once. - if(1) - . += lowertext(pick(nouns)) - if(2) - . += lowertext(pick(objects)) - if(3) - . += lowertext(pick(adjectives)) - if(4) - . += lowertext(pick(threats)) - if(!return_list) - if(words==1) - . += "." - else - . += ", " +/proc/lizard_name(gender) + if(gender == MALE) + return "[pick(GLOB.lizard_names_male)]-[pick(GLOB.lizard_names_male)]" + else + return "[pick(GLOB.lizard_names_female)]-[pick(GLOB.lizard_names_female)]" + +/proc/plasmaman_name() + return "[pick(GLOB.plasmaman_names)] \Roman[rand(1,99)]" + +/proc/moth_name() + return "[pick(GLOB.moth_first)] [pick(GLOB.moth_last)]" + +/proc/church_name() + var/static/church_name + if (church_name) + return church_name + + var/name = "" + + name += pick("Holy", "United", "First", "Second", "Last") + + if (prob(20)) + name += " Space" + + name += " " + pick("Church", "Cathedral", "Body", "Worshippers", "Movement", "Witnesses") + name += " of [religion_name()]" + + return name + +GLOBAL_VAR(command_name) +/proc/command_name() + if (GLOB.command_name) + return GLOB.command_name + + var/name = "Central Command" + + GLOB.command_name = name + return name + +/proc/change_command_name(name) + + GLOB.command_name = name + + return name + +/proc/religion_name() + var/static/religion_name + if (religion_name) + return religion_name + + var/name = "" + + name += pick("bee", "science", "edu", "captain", "assistant", "monkey", "alien", "space", "unit", "sprocket", "gadget", "bomb", "revolution", "beyond", "station", "goon", "robot", "ivor", "hobnob") + name += pick("ism", "ia", "ology", "istism", "ites", "ick", "ian", "ity") + + return capitalize(name) + +/proc/station_name() + if(!GLOB.station_name) + var/newname + var/config_station_name = CONFIG_GET(string/stationname) + if(config_station_name) + newname = config_station_name + else + newname = new_station_name() + + set_station_name(newname) + + return GLOB.station_name + +/proc/set_station_name(newname) + GLOB.station_name = newname + + var/config_server_name = CONFIG_GET(string/servername) + if(config_server_name) + world.name = "[config_server_name][config_server_name == GLOB.station_name ? "" : ": [GLOB.station_name]"]" + else + world.name = GLOB.station_name + + +/proc/new_station_name() + var/random = rand(1,5) + var/name = "" + var/new_station_name = "" + + //Rare: Pre-Prefix + if (prob(10)) + name = pick(GLOB.station_prefixes) + new_station_name = name + " " + name = "" + + // Prefix + for(var/holiday_name in SSevents.holidays) + if(holiday_name == "Friday the 13th") + random = 13 + var/datum/holiday/holiday = SSevents.holidays[holiday_name] + name = holiday.getStationPrefix() + //get normal name + if(!name) + name = pick(GLOB.station_names) + if(name) + new_station_name += name + " " + + // Suffix + name = pick(GLOB.station_suffixes) + new_station_name += name + " " + + // ID Number + switch(random) + if(1) + new_station_name += "[rand(1, 99)]" + if(2) + new_station_name += pick(GLOB.greek_letters) + if(3) + new_station_name += "\Roman[rand(1,99)]" + if(4) + new_station_name += pick(GLOB.phonetic_alphabet) + if(5) + new_station_name += pick(GLOB.numbers_as_words) + if(13) + new_station_name += pick("13","XIII","Thirteen") + return new_station_name + +/proc/syndicate_name() + var/name = "" + + // Prefix + name += pick("Clandestine", "Prima", "Blue", "Zero-G", "Max", "Blasto", "Waffle", "North", "Omni", "Newton", "Cyber", "Bonk", "Gene", "Gib") + + // Suffix + if (prob(80)) + name += " " + + // Full + if (prob(60)) + name += pick("Syndicate", "Consortium", "Collective", "Corporation", "Group", "Holdings", "Biotech", "Industries", "Systems", "Products", "Chemicals", "Enterprises", "Family", "Creations", "International", "Intergalactic", "Interplanetary", "Foundation", "Positronics", "Hive") + // Broken + else + name += pick("Syndi", "Corp", "Bio", "System", "Prod", "Chem", "Inter", "Hive") + name += pick("", "-") + name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Code") + // Small + else + name += pick("-", "*", "") + name += pick("Tech", "Sun", "Co", "Tek", "X", "Inc", "Gen", "Star", "Dyne", "Code", "Hive") + + return name + + +//Traitors and traitor silicons will get these. Revs will not. +GLOBAL_VAR(syndicate_code_phrase) //Code phrase for traitors. +GLOBAL_VAR(syndicate_code_response) //Code response for traitors. + +//Cached regex search - for checking if codewords are used. +GLOBAL_DATUM(syndicate_code_phrase_regex, /regex) +GLOBAL_DATUM(syndicate_code_response_regex, /regex) + + /* + Should be expanded. + How this works: + Instead of "I'm looking for James Smith," the traitor would say "James Smith" as part of a conversation. + Another traitor may then respond with: "They enjoy running through the void-filled vacuum of the derelict." + The phrase should then have the words: James Smith. + The response should then have the words: run, void, and derelict. + This way assures that the code is suited to the conversation and is unpredicatable. + Obviously, some people will be better at this than others but in theory, everyone should be able to do it and it only enhances roleplay. + Can probably be done through "{ }" but I don't really see the practical benefit. + One example of an earlier system is commented below. + /N + */ + +/proc/generate_code_phrase(return_list=FALSE)//Proc is used for phrase and response in master_controller.dm + + if(!return_list) + . = "" + else + . = list() + + var/words = pick(//How many words there will be. Minimum of two. 2, 4 and 5 have a lesser chance of being selected. 3 is the most likely. + 50; 2, + 200; 3, + 50; 4, + 25; 5 + ) + + var/list/safety = list(1,2,3)//Tells the proc which options to remove later on. + var/nouns = strings(ION_FILE, "ionabstract") + var/objects = strings(ION_FILE, "ionobjects") + var/adjectives = strings(ION_FILE, "ionadjectives") + var/threats = strings(ION_FILE, "ionthreats") + var/foods = strings(ION_FILE, "ionfood") + var/drinks = strings(ION_FILE, "iondrinks") + var/list/locations = GLOB.teleportlocs.len ? GLOB.teleportlocs : drinks //if null, defaults to drinks instead. + + var/list/names = list() + for(var/datum/data/record/t in GLOB.data_core.general)//Picks from crew manifest. + names += t.fields["name"] + + var/maxwords = words//Extra var to check for duplicates. + + for(words,words>0,words--)//Randomly picks from one of the choices below. + + if(words==1&&(1 in safety)&&(2 in safety))//If there is only one word remaining and choice 1 or 2 have not been selected. + safety = list(pick(1,2))//Select choice 1 or 2. + else if(words==1&&maxwords==2)//Else if there is only one word remaining (and there were two originally), and 1 or 2 were chosen, + safety = list(3)//Default to list 3 + + switch(pick(safety))//Chance based on the safety list. + if(1)//1 and 2 can only be selected once each to prevent more than two specific names/places/etc. + switch(rand(1,2))//Mainly to add more options later. + if(1) + if(names.len&&prob(70)) + . += pick(names) + else + if(prob(10)) + . += pick(lizard_name(MALE),lizard_name(FEMALE)) + else + var/new_name = pick(pick(GLOB.first_names_male,GLOB.first_names_female)) + new_name += " " + new_name += pick(GLOB.last_names) + . += new_name + if(2) + . += pick(get_all_jobs())//Returns a job. + safety -= 1 + if(2) + switch(rand(1,3))//Food, drinks, or things. Only selectable once. + if(1) + . += lowertext(pick(drinks)) + if(2) + . += lowertext(pick(foods)) + if(3) + . += lowertext(pick(locations)) + safety -= 2 + if(3) + switch(rand(1,4))//Abstract nouns, objects, adjectives, threats. Can be selected more than once. + if(1) + . += lowertext(pick(nouns)) + if(2) + . += lowertext(pick(objects)) + if(3) + . += lowertext(pick(adjectives)) + if(4) + . += lowertext(pick(threats)) + if(!return_list) + if(words==1) + . += "." + else + . += ", " diff --git a/code/__HELPERS/qdel.dm b/code/__HELPERS/qdel.dm index 9bd0d4c95f..0d2bf89152 100644 --- a/code/__HELPERS/qdel.dm +++ b/code/__HELPERS/qdel.dm @@ -1,10 +1,10 @@ -#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE) -#define QDEL_IN_CLIENT_TIME(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME) -#define QDEL_NULL(item) qdel(item); item = null -#define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); } -#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/______qdel_list_wrapper, L), time, TIMER_STOPPABLE) -#define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); } -#define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); } - -/proc/______qdel_list_wrapper(list/L) //the underscores are to encourage people not to use this directly. - QDEL_LIST(L) +#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE) +#define QDEL_IN_CLIENT_TIME(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE | TIMER_CLIENT_TIME) +#define QDEL_NULL(item) qdel(item); item = null +#define QDEL_LIST(L) if(L) { for(var/I in L) qdel(I); L.Cut(); } +#define QDEL_LIST_IN(L, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/______qdel_list_wrapper, L), time, TIMER_STOPPABLE) +#define QDEL_LIST_ASSOC(L) if(L) { for(var/I in L) { qdel(L[I]); qdel(I); } L.Cut(); } +#define QDEL_LIST_ASSOC_VAL(L) if(L) { for(var/I in L) qdel(L[I]); L.Cut(); } + +/proc/______qdel_list_wrapper(list/L) //the underscores are to encourage people not to use this directly. + QDEL_LIST(L) diff --git a/code/__HELPERS/radio.dm b/code/__HELPERS/radio.dm index c55fb8095d..7ab21d0402 100644 --- a/code/__HELPERS/radio.dm +++ b/code/__HELPERS/radio.dm @@ -1,19 +1,19 @@ -// Ensure the frequency is within bounds of what it should be sending/receiving at -/proc/sanitize_frequency(frequency, free = FALSE) - . = round(frequency) - if(free) - . = CLAMP(frequency, MIN_FREE_FREQ, MAX_FREE_FREQ) - else - . = CLAMP(frequency, MIN_FREQ, MAX_FREQ) - if(!(. % 2)) // Ensure the last digit is an odd number - . += 1 - -// Format frequency by moving the decimal. -/proc/format_frequency(frequency) - frequency = text2num(frequency) - return "[round(frequency / 10)].[frequency % 10]" - -//Opposite of format, returns as a number -/proc/unformat_frequency(frequency) - frequency = text2num(frequency) - return frequency * 10 +// Ensure the frequency is within bounds of what it should be sending/receiving at +/proc/sanitize_frequency(frequency, free = FALSE) + . = round(frequency) + if(free) + . = CLAMP(frequency, MIN_FREE_FREQ, MAX_FREE_FREQ) + else + . = CLAMP(frequency, MIN_FREQ, MAX_FREQ) + if(!(. % 2)) // Ensure the last digit is an odd number + . += 1 + +// Format frequency by moving the decimal. +/proc/format_frequency(frequency) + frequency = text2num(frequency) + return "[round(frequency / 10)].[frequency % 10]" + +//Opposite of format, returns as a number +/proc/unformat_frequency(frequency) + frequency = text2num(frequency) + return frequency * 10 diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 8494bbb7a9..60c43b0869 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -1,796 +1,796 @@ -/* - * Holds procs designed to help with filtering text - * Contains groups: - * SQL sanitization/formating - * Text sanitization - * Text searches - * Text modification - * Misc - */ - - -/* - * SQL sanitization - */ - -// Run all strings to be used in an SQL query through this proc first to properly escape out injection attempts. -/proc/sanitizeSQL(t) - return SSdbcore.Quote("[t]") - -/proc/format_table_name(table as text) - return CONFIG_GET(string/feedback_tableprefix) + table - -/* - * Text sanitization - */ - -//Simply removes < and > and limits the length of the message -/proc/strip_html_simple(t,limit=MAX_MESSAGE_LEN) - var/list/strip_chars = list("<",">") - t = copytext(t,1,limit) - for(var/char in strip_chars) - var/index = findtext(t, char) - while(index) - t = copytext(t, 1, index) + copytext(t, index+1) - index = findtext(t, char) - return t - -//Removes a few problematic characters -/proc/sanitize_simple(t,list/repl_chars = list("\n"="#","\t"="#")) - for(var/char in repl_chars) - var/index = findtext(t, char) - while(index) - t = copytext(t, 1, index) + repl_chars[char] + copytext(t, index+1) - index = findtext(t, char, index+1) - return t - -/proc/sanitize_filename(t) - return sanitize_simple(t, list("\n"="", "\t"="", "/"="", "\\"="", "?"="", "%"="", "*"="", ":"="", "|"="", "\""="", "<"="", ">"="")) - -//Runs byond's sanitization proc along-side sanitize_simple -/proc/sanitize(t,list/repl_chars = null) - return html_encode(sanitize_simple(t,repl_chars)) - -//Runs sanitize and strip_html_simple -//I believe strip_html_simple() is required to run first to prevent '<' from displaying as '<' after sanitize() calls byond's html_encode() -/proc/strip_html(t,limit=MAX_MESSAGE_LEN) - return copytext((sanitize(strip_html_simple(t))),1,limit) - -//Runs byond's sanitization proc along-side strip_html_simple -//I believe strip_html_simple() is required to run first to prevent '<' from displaying as '<' that html_encode() would cause -/proc/adminscrub(t,limit=MAX_MESSAGE_LEN) - return copytext((html_encode(strip_html_simple(t))),1,limit) - - -//Returns null if there is any bad text in the string -/proc/reject_bad_text(text, max_length=512) - if(length(text) > max_length) - return //message too long - var/non_whitespace = 0 - for(var/i=1, i<=length(text), i++) - switch(text2ascii(text,i)) - if(62,60,92,47) - return //rejects the text if it contains these bad characters: <, >, \ or / - if(127 to 255) - return //rejects weird letters like � - if(0 to 31) - return //more weird stuff - if(32) - continue //whitespace - else - non_whitespace = 1 - if(non_whitespace) - return text //only accepts the text if it has some non-spaces - -// Used to get a properly sanitized input, of max_length -// no_trim is self explanatory but it prevents the input from being trimed if you intend to parse newlines or whitespace. -/proc/stripped_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE) - var/name = input(user, message, title, default) as text|null - if(no_trim) - return copytext(html_encode(name), 1, max_length) - else - return trim(html_encode(name), max_length) //trim is "outside" because html_encode can expand single symbols into multiple symbols (such as turning < into <) - -// Used to get a properly sanitized multiline input, of max_length -/proc/stripped_multiline_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE) - var/name = input(user, message, title, default) as message|null - if(isnull(name)) // Return null if canceled. - return null - if(no_trim) - return copytext(html_encode(name), 1, max_length) - else - return trim(html_encode(name), max_length) - -//Filters out undesirable characters from names -/proc/reject_bad_name(t_in, allow_numbers=0, max_length=MAX_NAME_LEN) - if(!t_in || length(t_in) > max_length) - return //Rejects the input if it is null or if it is longer then the max length allowed - - var/number_of_alphanumeric = 0 - var/last_char_group = 0 - var/t_out = "" - - for(var/i=1, i<=length(t_in), i++) - var/ascii_char = text2ascii(t_in,i) - switch(ascii_char) - // A .. Z - if(65 to 90) //Uppercase Letters - t_out += ascii2text(ascii_char) - number_of_alphanumeric++ - last_char_group = 4 - - // a .. z - if(97 to 122) //Lowercase Letters - if(last_char_group<2) - t_out += ascii2text(ascii_char-32) //Force uppercase first character - else - t_out += ascii2text(ascii_char) - number_of_alphanumeric++ - last_char_group = 4 - - // 0 .. 9 - if(48 to 57) //Numbers - if(!last_char_group) - continue //suppress at start of string - if(!allow_numbers) - continue - t_out += ascii2text(ascii_char) - number_of_alphanumeric++ - last_char_group = 3 - - // ' - . - if(39,45,46) //Common name punctuation - if(!last_char_group) - continue - t_out += ascii2text(ascii_char) - last_char_group = 2 - - // ~ | @ : # $ % & * + - if(126,124,64,58,35,36,37,38,42,43) //Other symbols that we'll allow (mainly for AI) - if(!last_char_group) - continue //suppress at start of string - if(!allow_numbers) - continue - t_out += ascii2text(ascii_char) - last_char_group = 2 - - //Space - if(32) - if(last_char_group <= 1) - continue //suppress double-spaces and spaces at start of string - t_out += ascii2text(ascii_char) - last_char_group = 1 - else - return - - if(number_of_alphanumeric < 2) - return //protects against tiny names like "A" and also names like "' ' ' ' ' ' ' '" - - if(last_char_group == 1) - t_out = copytext(t_out,1,length(t_out)) //removes the last character (in this case a space) - - for(var/bad_name in list("space","floor","wall","r-wall","monkey","unknown","inactive ai")) //prevents these common metagamey names - if(cmptext(t_out,bad_name)) - return //(not case sensitive) - - return t_out - -//html_encode helper proc that returns the smallest non null of two numbers -//or 0 if they're both null (needed because of findtext returning 0 when a value is not present) -/proc/non_zero_min(a, b) - if(!a) - return b - if(!b) - return a - return (a < b ? a : b) - -/* - * Text searches - */ - -//Checks the beginning of a string for a specified sub-string -//Returns the position of the substring or 0 if it was not found -/proc/dd_hasprefix(text, prefix) - var/start = 1 - var/end = length(prefix) + 1 - return findtext(text, prefix, start, end) - -//Checks the beginning of a string for a specified sub-string. This proc is case sensitive -//Returns the position of the substring or 0 if it was not found -/proc/dd_hasprefix_case(text, prefix) - var/start = 1 - var/end = length(prefix) + 1 - return findtextEx(text, prefix, start, end) - -//Checks the end of a string for a specified substring. -//Returns the position of the substring or 0 if it was not found -/proc/dd_hassuffix(text, suffix) - var/start = length(text) - length(suffix) - if(start) - return findtext(text, suffix, start, null) - return - -//Checks the end of a string for a specified substring. This proc is case sensitive -//Returns the position of the substring or 0 if it was not found -/proc/dd_hassuffix_case(text, suffix) - var/start = length(text) - length(suffix) - if(start) - return findtextEx(text, suffix, start, null) - -//Checks if any of a given list of needles is in the haystack -/proc/text_in_list(haystack, list/needle_list, start=1, end=0) - for(var/needle in needle_list) - if(findtext(haystack, needle, start, end)) - return 1 - return 0 - -//Like above, but case sensitive -/proc/text_in_list_case(haystack, list/needle_list, start=1, end=0) - for(var/needle in needle_list) - if(findtextEx(haystack, needle, start, end)) - return 1 - return 0 - -//Adds 'u' number of zeros ahead of the text 't' -/proc/add_zero(t, u) - while (length(t) < u) - t = "0[t]" - return t - -//Adds 'u' number of spaces ahead of the text 't' -/proc/add_lspace(t, u) - while(length(t) < u) - t = " [t]" - return t - -//Adds 'u' number of spaces behind the text 't' -/proc/add_tspace(t, u) - while(length(t) < u) - t = "[t] " - return t - -//Returns a string with reserved characters and spaces before the first letter removed -/proc/trim_left(text) - for (var/i = 1 to length(text)) - if (text2ascii(text, i) > 32) - return copytext(text, i) - return "" - -//Returns a string with reserved characters and spaces after the last letter removed -/proc/trim_right(text) - for (var/i = length(text), i > 0, i--) - if (text2ascii(text, i) > 32) - return copytext(text, 1, i + 1) - - return "" - -//Returns a string with reserved characters and spaces before the first word and after the last word removed. -/proc/trim(text, max_length) - if(max_length) - text = copytext(text, 1, max_length) - return trim_left(trim_right(text)) - -//Returns a string with the first element of the string capitalized. -/proc/capitalize(t as text) - return uppertext(copytext(t, 1, 2)) + copytext(t, 2) - -//Centers text by adding spaces to either side of the string. -/proc/dd_centertext(message, length) - var/new_message = message - var/size = length(message) - var/delta = length - size - if(size == length) - return new_message - if(size > length) - return copytext(new_message, 1, length + 1) - if(delta == 1) - return new_message + " " - if(delta % 2) - new_message = " " + new_message - delta-- - var/spaces = add_lspace("",delta/2-1) - return spaces + new_message + spaces - -//Limits the length of the text. Note: MAX_MESSAGE_LEN and MAX_NAME_LEN are widely used for this purpose -/proc/dd_limittext(message, length) - var/size = length(message) - if(size <= length) - return message - return copytext(message, 1, length + 1) - - -/proc/stringmerge(text,compare,replace = "*") -//This proc fills in all spaces with the "replace" var (* by default) with whatever -//is in the other string at the same spot (assuming it is not a replace char). -//This is used for fingerprints - var/newtext = text - if(length(text) != length(compare)) - return 0 - for(var/i = 1, i < length(text), i++) - var/a = copytext(text,i,i+1) - var/b = copytext(compare,i,i+1) -//if it isn't both the same letter, or if they are both the replacement character -//(no way to know what it was supposed to be) - if(a != b) - if(a == replace) //if A is the replacement char - newtext = copytext(newtext,1,i) + b + copytext(newtext, i+1) - else if(b == replace) //if B is the replacement char - newtext = copytext(newtext,1,i) + a + copytext(newtext, i+1) - else //The lists disagree, Uh-oh! - return 0 - return newtext - -/proc/stringpercent(text,character = "*") -//This proc returns the number of chars of the string that is the character -//This is used for detective work to determine fingerprint completion. - if(!text || !character) - return 0 - var/count = 0 - for(var/i = 1, i <= length(text), i++) - var/a = copytext(text,i,i+1) - if(a == character) - count++ - return count - -/proc/reverse_text(text = "") - var/new_text = "" - for(var/i = length(text); i > 0; i--) - new_text += copytext(text, i, i+1) - return new_text - -GLOBAL_LIST_INIT(zero_character_only, list("0")) -GLOBAL_LIST_INIT(hex_characters, list("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f")) -GLOBAL_LIST_INIT(alphabet, list("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")) -GLOBAL_LIST_INIT(binary, list("0","1")) -/proc/random_string(length, list/characters) - . = "" - for(var/i=1, i<=length, i++) - . += pick(characters) - -/proc/repeat_string(times, string="") - . = "" - for(var/i=1, i<=times, i++) - . += string - -/proc/random_short_color() - return random_string(3, GLOB.hex_characters) - -/proc/random_color() - return random_string(6, GLOB.hex_characters) - -/proc/add_zero2(t, u) - var/temp1 - while (length(t) < u) - t = "0[t]" - temp1 = t - if (length(t) > u) - temp1 = copytext(t,2,u+1) - return temp1 - -//merges non-null characters (3rd argument) from "from" into "into". Returns result -//e.g. into = "Hello World" -// from = "Seeya______" -// returns"Seeya World" -//The returned text is always the same length as into -//This was coded to handle DNA gene-splicing. -/proc/merge_text(into, from, null_char="_") - . = "" - if(!istext(into)) - into = "" - if(!istext(from)) - from = "" - var/null_ascii = istext(null_char) ? text2ascii(null_char,1) : null_char - - var/previous = 0 - var/start = 1 - var/end = length(into) + 1 - - for(var/i=1, i") - t = replacetext(t, "))", "") - t = replacetext(t, regex("(-){3,}", "gm"), "
      ") - t = replacetext(t, regex("^\\((-){3,}\\)$", "gm"), "$1") - - // Parse lists - - var/list/tlist = splittext(t, "\n") - var/tlistlen = tlist.len - var/listlevel = -1 - var/singlespace = -1 // if 0, double spaces are used before asterisks, if 1, single are - for(var/i = 1, i <= tlistlen, i++) - var/line = tlist[i] - var/count_asterisk = length(replacetext(line, regex("\[^\\*\]+", "g"), "")) - if(count_asterisk % 2 == 1 && findtext(line, regex("^\\s*\\*", "g"))) // there is an extra asterisk in the beggining - - var/count_w = length(replacetext(line, regex("^( *)\\*.*$", "g"), "$1")) // whitespace before asterisk - line = replacetext(line, regex("^ *(\\*.*)$", "g"), "$1") - - if(singlespace == -1 && count_w == 2) - if(listlevel == 0) - singlespace = 0 - else - singlespace = 1 - - if(singlespace == 0) - count_w = count_w % 2 ? round(count_w / 2 + 0.25) : count_w / 2 - - line = replacetext(line, regex("\\*", ""), "
    1. ") + while(listlevel < count_w) + line = "
        " + line + listlevel++ + while(listlevel > count_w) + line = "
      " + line + listlevel-- + + else while(listlevel >= 0) + line = "" + line + listlevel-- + + tlist[i] = line + // end for + + t = tlist[1] + for(var/i = 2, i <= tlistlen, i++) + t += "\n" + tlist[i] + + while(listlevel >= 0) + t += "" + listlevel-- + + else + t = replacetext(t, "((", "") + t = replacetext(t, "))", "") + + // Parse headers + + t = replacetext(t, regex("^#(?!#) ?(.+)$", "gm"), "

      $1

      ") + t = replacetext(t, regex("^##(?!#) ?(.+)$", "gm"), "

      $1

      ") + t = replacetext(t, regex("^###(?!#) ?(.+)$", "gm"), "

      $1

      ") + t = replacetext(t, regex("^#### ?(.+)$", "gm"), "
      $1
      ") + + // Parse most rules + + t = replacetext(t, regex("\\*(\[^\\*\]*)\\*", "g"), "$1") + t = replacetext(t, regex("_(\[^_\]*)_", "g"), "$1") + t = replacetext(t, "", "!") + t = replacetext(t, "
      ", "!") + t = replacetext(t, regex("\\!(\[^\\!\]+)\\!", "g"), "$1") + t = replacetext(t, regex("\\^(\[^\\^\]+)\\^", "g"), "$1") + t = replacetext(t, regex("\\|(\[^\\|\]+)\\|", "g"), "
      $1
      ") + t = replacetext(t, "!", "
      ") + + return t + +/proc/parsemarkdown_basic_step2(t) + if(length(t) <= 0) + return + + // Restore the single characters used + + t = replacetext(t, "$a", "!") + + // Redo the escaping + + t = replacetext(t, "$1", "\\") + t = replacetext(t, "$2", "**") + t = replacetext(t, "$3", "*") + t = replacetext(t, "$4", "__") + t = replacetext(t, "$5", "_") + t = replacetext(t, "$6", "^") + t = replacetext(t, "$7", "((") + t = replacetext(t, "$8", "))") + t = replacetext(t, "$9", "|") + t = replacetext(t, "$0", "%") + t = replacetext(t, "$-", "$") + + return t + +/proc/parsemarkdown_basic(t, limited=FALSE) + t = parsemarkdown_basic_step1(t, limited) + t = parsemarkdown_basic_step2(t) + return t + +/proc/parsemarkdown(t, mob/user=null, limited=FALSE) + if(length(t) <= 0) + return + + // Premanage whitespace + + t = replacetext(t, regex("\[^\\S\\r\\n \]", "g"), " ") + + t = parsemarkdown_basic_step1(t) + + t = replacetext(t, regex("%s(?:ign)?(?=\\s|$)", "igm"), user ? "[user.real_name]" : "") + t = replacetext(t, regex("%f(?:ield)?(?=\\s|$)", "igm"), "") + + t = parsemarkdown_basic_step2(t) + + // Manage whitespace + + t = replacetext(t, regex("(?:\\r\\n?|\\n)", "g"), "
      ") + + t = replacetext(t, " ", "  ") + + // Done + + return t + +#define string2charlist(string) (splittext(string, regex("(.)")) - splittext(string, "")) + +/proc/rot13(text = "") + var/list/textlist = string2charlist(text) + var/list/result = list() + for(var/c in textlist) + var/ca = text2ascii(c) + if(ca >= text2ascii("a") && ca <= text2ascii("m")) + ca += 13 + else if(ca >= text2ascii("n") && ca <= text2ascii("z")) + ca -= 13 + else if(ca >= text2ascii("A") && ca <= text2ascii("M")) + ca += 13 + else if(ca >= text2ascii("N") && ca <= text2ascii("Z")) + ca -= 13 + result += ascii2text(ca) + return jointext(result, "") + +//Takes a list of values, sanitizes it down for readability and character count, +//then exports it as a json file at data/npc_saves/[filename].json. +//As far as SS13 is concerned this is write only data. You can't change something +//in the json file and have it be reflected in the in game item/mob it came from. +//(That's what things like savefiles are for) Note that this list is not shuffled. +/proc/twitterize(list/proposed, filename, cullshort = 1, storemax = 1000) + if(!islist(proposed) || !filename || !CONFIG_GET(flag/log_twitter)) + return + + //Regular expressions are, as usual, absolute magic + var/regex/all_invalid_symbols = new("\[^ -~]+") + + var/list/accepted = list() + for(var/string in proposed) + if(findtext(string,GLOB.is_website) || findtext(string,GLOB.is_email) || findtext(string,all_invalid_symbols) || !findtext(string,GLOB.is_alphanumeric)) + continue + var/buffer = "" + var/early_culling = TRUE + for(var/pos = 1, pos <= length(string), pos++) + var/let = copytext(string, pos, (pos + 1) % length(string)) + if(early_culling && !findtext(let,GLOB.is_alphanumeric)) + continue + early_culling = FALSE + buffer += let + if(!findtext(buffer,GLOB.is_alphanumeric)) + continue + var/punctbuffer = "" + var/cutoff = length(buffer) + for(var/pos = length(buffer), pos >= 0, pos--) + var/let = copytext(buffer, pos, (pos + 1) % length(buffer)) + if(findtext(let,GLOB.is_alphanumeric)) + break + if(findtext(let,GLOB.is_punctuation)) + punctbuffer = let + punctbuffer //Note this isn't the same thing as using += + cutoff = pos + if(punctbuffer) //We clip down excessive punctuation to get the letter count lower and reduce repeats. It's not perfect but it helps. + var/exclaim = FALSE + var/question = FALSE + var/periods = 0 + for(var/pos = length(punctbuffer), pos >= 0, pos--) + var/punct = copytext(punctbuffer, pos, (pos + 1) % length(punctbuffer)) + if(!exclaim && findtext(punct,"!")) + exclaim = TRUE + if(!question && findtext(punct,"?")) + question = TRUE + if(!exclaim && !question && findtext(punct,".")) + periods += 1 + if(exclaim) + if(question) + punctbuffer = "?!" + else + punctbuffer = "!" + else if(question) + punctbuffer = "?" + else if(periods) + if(periods > 1) + punctbuffer = "..." + else + punctbuffer = "" //Grammer nazis be damned + buffer = copytext(buffer, 1, cutoff) + punctbuffer + if(!findtext(buffer,GLOB.is_alphanumeric)) + continue + if(!buffer || length(buffer) > 280 || length(buffer) <= cullshort || buffer in accepted) + continue + + accepted += buffer + + var/log = file("data/npc_saves/[filename].json") //If this line ever shows up as changed in a PR be very careful you aren't being memed on + var/list/oldjson = list() + var/list/oldentries = list() + if(fexists(log)) + oldjson = json_decode(file2text(log)) + oldentries = oldjson["data"] + if(!isemptylist(oldentries)) + for(var/string in accepted) + for(var/old in oldentries) + if(string == old) + oldentries.Remove(old) //Line's position in line is "refreshed" until it falls off the in game radar + break + + var/list/finalized = list() + finalized = accepted.Copy() + oldentries.Copy() //we keep old and unreferenced phrases near the bottom for culling + listclearnulls(finalized) + if(!isemptylist(finalized) && length(finalized) > storemax) + finalized.Cut(storemax + 1) + fdel(log) + + var/list/tosend = list() + tosend["data"] = finalized + WRITE_FILE(log, json_encode(tosend)) + +//Used for applying byonds text macros to strings that are loaded at runtime +/proc/apply_text_macros(string) + var/next_backslash = findtext(string, "\\") + if(!next_backslash) + return string + + var/leng = length(string) + + var/next_space = findtext(string, " ", next_backslash + 1) + if(!next_space) + next_space = leng - next_backslash + + if(!next_space) //trailing bs + return string + + var/base = next_backslash == 1 ? "" : copytext(string, 1, next_backslash) + var/macro = lowertext(copytext(string, next_backslash + 1, next_space)) + var/rest = next_backslash > leng ? "" : copytext(string, next_space + 1) + + //See https://secure.byond.com/docs/ref/info.html#/DM/text/macros + switch(macro) + //prefixes/agnostic + if("the") + rest = text("\the []", rest) + if("a") + rest = text("\a []", rest) + if("an") + rest = text("\an []", rest) + if("proper") + rest = text("\proper []", rest) + if("improper") + rest = text("\improper []", rest) + if("roman") + rest = text("\roman []", rest) + //postfixes + if("th") + base = text("[]\th", rest) + if("s") + base = text("[]\s", rest) + if("he") + base = text("[]\he", rest) + if("she") + base = text("[]\she", rest) + if("his") + base = text("[]\his", rest) + if("himself") + base = text("[]\himself", rest) + if("herself") + base = text("[]\herself", rest) + if("hers") + base = text("[]\hers", rest) + + . = base + if(rest) + . += .(rest) + +//Replacement for the \th macro when you want the whole word output as text (first instead of 1st) +/proc/thtotext(number) + if(!isnum(number)) + return + switch(number) + if(1) + return "first" + if(2) + return "second" + if(3) + return "third" + if(4) + return "fourth" + if(5) + return "fifth" + if(6) + return "sixth" + if(7) + return "seventh" + if(8) + return "eighth" + if(9) + return "ninth" + if(10) + return "tenth" + if(11) + return "eleventh" + if(12) + return "twelfth" + else + return "[number]\th" + +/proc/unintelligize(message) + var/prefix=copytext(message,1,2) + if(prefix == ";") + message = copytext(message,2) + else if(prefix in list(":","#")) + prefix += copytext(message,2,3) + message = copytext(message,3) + else + prefix="" + + var/list/words = splittext(message," ") + var/list/rearranged = list() + for(var/i=1;i<=words.len;i++) + var/cword = pick(words) + words.Remove(cword) + var/suffix = copytext(cword,length(cword)-1,length(cword)) + while(length(cword)>0 && suffix in list(".",",",";","!",":","?")) + cword = copytext(cword,1 ,length(cword)-1) + suffix = copytext(cword,length(cword)-1,length(cword) ) + if(length(cword)) + rearranged += cword + message = "[prefix][jointext(rearranged," ")]" + . = message + +#define is_alpha(X) ((text2ascii(X) <= 122) && (text2ascii(X) >= 97)) #define is_digit(X) ((length(X) == 1) && (length(text2num(X)) == 1)) \ No newline at end of file diff --git a/code/__HELPERS/time.dm b/code/__HELPERS/time.dm index f0d5a7b252..52fe90ed2d 100644 --- a/code/__HELPERS/time.dm +++ b/code/__HELPERS/time.dm @@ -1,83 +1,83 @@ -/proc/station_time_debug(force_set) - if(isnum(force_set)) - SSticker.gametime_offset = force_set - return - SSticker.gametime_offset = rand(0, 864000) //hours in day * minutes in hour * seconds in minute * deciseconds in second - if(prob(50)) - SSticker.gametime_offset = FLOOR(SSticker.gametime_offset, 3600) - else - SSticker.gametime_offset = CEILING(SSticker.gametime_offset, 3600) - -/* Returns 1 if it is the selected month and day */ -/proc/isDay(month, day) - if(isnum(month) && isnum(day)) - var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month - var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day - if(month == MM && day == DD) - return 1 - -//returns timestamp in a sql and a not-quite-compliant ISO 8601 friendly format -/proc/SQLtime(timevar) - return time2text(timevar || world.timeofday, "YYYY-MM-DD hh:mm:ss") - - -GLOBAL_VAR_INIT(midnight_rollovers, 0) -GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0) -/proc/update_midnight_rollover() - if (world.timeofday < GLOB.rollovercheck_last_timeofday) //TIME IS GOING BACKWARDS! - return GLOB.midnight_rollovers++ - return GLOB.midnight_rollovers - -/proc/weekdayofthemonth() - var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day - switch(DD) - if(8 to 13) - return 2 - if(14 to 20) - return 3 - if(21 to 27) - return 4 - if(28 to INFINITY) - return 5 - else - return 1 - -//Takes a value of time in deciseconds. -//Returns a text value of that number in hours, minutes, or seconds. -/proc/DisplayTimeText(time_value, round_seconds_to = 0.1) - var/second = FLOOR(time_value * 0.1, round_seconds_to) - if(!second) - return "right now" - if(second < 60) - return "[second] second[(second != 1)? "s":""]" - var/minute = FLOOR(second / 60, 1) - second = FLOOR(MODULUS(second, 60), round_seconds_to) - var/secondT - if(second) - secondT = " and [second] second[(second != 1)? "s":""]" - if(minute < 60) - return "[minute] minute[(minute != 1)? "s":""][secondT]" - var/hour = FLOOR(minute / 60, 1) - minute = MODULUS(minute, 60) - var/minuteT - if(minute) - minuteT = " and [minute] minute[(minute != 1)? "s":""]" - if(hour < 24) - return "[hour] hour[(hour != 1)? "s":""][minuteT][secondT]" - var/day = FLOOR(hour / 24, 1) - hour = MODULUS(hour, 24) - var/hourT - if(hour) - hourT = " and [hour] hour[(hour != 1)? "s":""]" - return "[day] day[(day != 1)? "s":""][hourT][minuteT][secondT]" - -/proc/daysSince(realtimev) - return round((world.realtime - realtimev) / (24 HOURS)) - -/proc/worldtime2text() - return gameTimestamp("hh:mm:ss", world.time) - -/proc/gameTimestamp(format = "hh:mm:ss", wtime=null) - if(!wtime) - wtime = world.time - return time2text(wtime - GLOB.timezoneOffset, format) +/proc/station_time_debug(force_set) + if(isnum(force_set)) + SSticker.gametime_offset = force_set + return + SSticker.gametime_offset = rand(0, 864000) //hours in day * minutes in hour * seconds in minute * deciseconds in second + if(prob(50)) + SSticker.gametime_offset = FLOOR(SSticker.gametime_offset, 3600) + else + SSticker.gametime_offset = CEILING(SSticker.gametime_offset, 3600) + +/* Returns 1 if it is the selected month and day */ +/proc/isDay(month, day) + if(isnum(month) && isnum(day)) + var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month + var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day + if(month == MM && day == DD) + return 1 + +//returns timestamp in a sql and a not-quite-compliant ISO 8601 friendly format +/proc/SQLtime(timevar) + return time2text(timevar || world.timeofday, "YYYY-MM-DD hh:mm:ss") + + +GLOBAL_VAR_INIT(midnight_rollovers, 0) +GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0) +/proc/update_midnight_rollover() + if (world.timeofday < GLOB.rollovercheck_last_timeofday) //TIME IS GOING BACKWARDS! + return GLOB.midnight_rollovers++ + return GLOB.midnight_rollovers + +/proc/weekdayofthemonth() + var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day + switch(DD) + if(8 to 13) + return 2 + if(14 to 20) + return 3 + if(21 to 27) + return 4 + if(28 to INFINITY) + return 5 + else + return 1 + +//Takes a value of time in deciseconds. +//Returns a text value of that number in hours, minutes, or seconds. +/proc/DisplayTimeText(time_value, round_seconds_to = 0.1) + var/second = FLOOR(time_value * 0.1, round_seconds_to) + if(!second) + return "right now" + if(second < 60) + return "[second] second[(second != 1)? "s":""]" + var/minute = FLOOR(second / 60, 1) + second = FLOOR(MODULUS(second, 60), round_seconds_to) + var/secondT + if(second) + secondT = " and [second] second[(second != 1)? "s":""]" + if(minute < 60) + return "[minute] minute[(minute != 1)? "s":""][secondT]" + var/hour = FLOOR(minute / 60, 1) + minute = MODULUS(minute, 60) + var/minuteT + if(minute) + minuteT = " and [minute] minute[(minute != 1)? "s":""]" + if(hour < 24) + return "[hour] hour[(hour != 1)? "s":""][minuteT][secondT]" + var/day = FLOOR(hour / 24, 1) + hour = MODULUS(hour, 24) + var/hourT + if(hour) + hourT = " and [hour] hour[(hour != 1)? "s":""]" + return "[day] day[(day != 1)? "s":""][hourT][minuteT][secondT]" + +/proc/daysSince(realtimev) + return round((world.realtime - realtimev) / (24 HOURS)) + +/proc/worldtime2text() + return gameTimestamp("hh:mm:ss", world.time) + +/proc/gameTimestamp(format = "hh:mm:ss", wtime=null) + if(!wtime) + wtime = world.time + return time2text(wtime - GLOB.timezoneOffset, format) diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index d6942f1c40..823e893670 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -1,631 +1,631 @@ -/* - * Holds procs designed to change one type of value, into another. - * Contains: - * hex2num & num2hex - * file2list - * angle2dir - * angle2text - * worldtime2text - * text2dir_extended & dir2text_short - */ - -//Returns an integer given a hex input, supports negative values "-ff" -//skips preceding invalid characters -//breaks when hittin invalid characters thereafter -// If safe=TRUE, returns null on incorrect input strings instead of CRASHing -/proc/hex2num(hex, safe=FALSE) - . = 0 - var/place = 1 - for(var/i in length(hex) to 1 step -1) - var/num = text2ascii(hex, i) - switch(num) - if(48 to 57) - num -= 48 //0-9 - if(97 to 102) - num -= 87 //a-f - if(65 to 70) - num -= 55 //A-F - if(45) - return . * -1 // - - else - if(safe) - return null - else - CRASH("Malformed hex number") - - . += num * place - place *= 16 - -//Returns the hex value of a decimal number -//len == length of returned string -//if len < 0 then the returned string will be as long as it needs to be to contain the data -//Only supports positive numbers -//if an invalid number is provided, it assumes num==0 -//Note, unlike previous versions, this one works from low to high <-- that way -/proc/num2hex(num, len=2) - if(!isnum(num)) - num = 0 - num = round(abs(num)) - . = "" - var/i=0 - while(1) - if(len<=0) - if(!num) - break - else - if(i>=len) - break - var/remainder = num/16 - num = round(remainder) - remainder = (remainder - num) * 16 - switch(remainder) - if(9,8,7,6,5,4,3,2,1) - . = "[remainder]" + . - if(10,11,12,13,14,15) - . = ascii2text(remainder+87) + . - else - . = "0" + . - i++ - return . - -//Splits the text of a file at seperator and returns them in a list. -//returns an empty list if the file doesn't exist -/world/proc/file2list(filename, seperator="\n", trim = TRUE) - if (trim) - return splittext(trim(file2text(filename)),seperator) - return splittext(file2text(filename),seperator) - -//Turns a direction into text -/proc/dir2text(direction) - switch(direction) - if(1) - return "north" - if(2) - return "south" - if(4) - return "east" - if(8) - return "west" - if(5) - return "northeast" - if(6) - return "southeast" - if(9) - return "northwest" - if(10) - return "southwest" - else - return - -//Turns text into proper directions -/proc/text2dir(direction) - switch(uppertext(direction)) - if("NORTH") - return 1 - if("SOUTH") - return 2 - if("EAST") - return 4 - if("WEST") - return 8 - if("NORTHEAST") - return 5 - if("NORTHWEST") - return 9 - if("SOUTHEAST") - return 6 - if("SOUTHWEST") - return 10 - else - return - -//Converts an angle (degrees) into an ss13 direction -/proc/angle2dir(degree) - - degree = SIMPLIFY_DEGREES(degree) - switch(degree) - if(0 to 22.5) //north requires two angle ranges - return NORTH - if(22.5 to 67.5) //each range covers 45 degrees - return NORTHEAST - if(67.5 to 112.5) - return EAST - if(112.5 to 157.5) - return SOUTHEAST - if(157.5 to 202.5) - return SOUTH - if(202.5 to 247.5) - return SOUTHWEST - if(247.5 to 292.5) - return WEST - if(292.5 to 337.5) - return NORTHWEST - if(337.5 to 360) - return NORTH - -/proc/angle2dir_cardinal(angle) - switch(round(angle, 0.1)) - if(315.5 to 360, 0 to 45.5) - return NORTH - if(45.6 to 135.5) - return EAST - if(135.6 to 225.5) - return SOUTH - if(225.6 to 315.5) - return WEST - -//returns the north-zero clockwise angle in degrees, given a direction -/proc/dir2angle(D) - switch(D) - if(NORTH) - return 0 - if(SOUTH) - return 180 - if(EAST) - return 90 - if(WEST) - return 270 - if(NORTHEAST) - return 45 - if(SOUTHEAST) - return 135 - if(NORTHWEST) - return 315 - if(SOUTHWEST) - return 225 - else - return null - -//Returns the angle in english -/proc/angle2text(degree) - return dir2text(angle2dir(degree)) - -//Converts a blend_mode constant to one acceptable to icon.Blend() -/proc/blendMode2iconMode(blend_mode) - switch(blend_mode) - if(BLEND_MULTIPLY) - return ICON_MULTIPLY - if(BLEND_ADD) - return ICON_ADD - if(BLEND_SUBTRACT) - return ICON_SUBTRACT - else - return ICON_OVERLAY - -//Converts a rights bitfield into a string -/proc/rights2text(rights, seperator="", prefix = "+") - seperator += prefix - if(rights & R_BUILDMODE) - . += "[seperator]BUILDMODE" - if(rights & R_ADMIN) - . += "[seperator]ADMIN" - if(rights & R_BAN) - . += "[seperator]BAN" - if(rights & R_FUN) - . += "[seperator]FUN" - if(rights & R_SERVER) - . += "[seperator]SERVER" - if(rights & R_DEBUG) - . += "[seperator]DEBUG" - if(rights & R_POSSESS) - . += "[seperator]POSSESS" - if(rights & R_PERMISSIONS) - . += "[seperator]PERMISSIONS" - if(rights & R_STEALTH) - . += "[seperator]STEALTH" - if(rights & R_POLL) - . += "[seperator]POLL" - if(rights & R_VAREDIT) - . += "[seperator]VAREDIT" - if(rights & R_SOUNDS) - . += "[seperator]SOUND" - if(rights & R_SPAWN) - . += "[seperator]SPAWN" - if(rights & R_AUTOLOGIN) - . += "[seperator]AUTOLOGIN" - if(rights & R_DBRANKS) - . += "[seperator]DBRANKS" - if(!.) - . = "NONE" - return . - -//colour formats -/proc/rgb2hsl(red, green, blue) - red /= 255;green /= 255;blue /= 255; - var/max = max(red,green,blue) - var/min = min(red,green,blue) - var/range = max-min - - var/hue=0;var/saturation=0;var/lightness=0; - lightness = (max + min)/2 - if(range != 0) - if(lightness < 0.5) - saturation = range/(max+min) - else - saturation = range/(2-max-min) - - var/dred = ((max-red)/(6*max)) + 0.5 - var/dgreen = ((max-green)/(6*max)) + 0.5 - var/dblue = ((max-blue)/(6*max)) + 0.5 - - if(max==red) - hue = dblue - dgreen - else if(max==green) - hue = dred - dblue + (1/3) - else - hue = dgreen - dred + (2/3) - if(hue < 0) - hue++ - else if(hue > 1) - hue-- - - return list(hue, saturation, lightness) - -/proc/hsl2rgb(hue, saturation, lightness) - var/red;var/green;var/blue; - if(saturation == 0) - red = lightness * 255 - green = red - blue = red - else - var/a;var/b; - if(lightness < 0.5) - b = lightness*(1+saturation) - else - b = (lightness+saturation) - (saturation*lightness) - a = 2*lightness - b - - red = round(255 * hue2rgb(a, b, hue+(1/3))) - green = round(255 * hue2rgb(a, b, hue)) - blue = round(255 * hue2rgb(a, b, hue-(1/3))) - - return list(red, green, blue) - -/proc/hue2rgb(a, b, hue) - if(hue < 0) - hue++ - else if(hue > 1) - hue-- - if(6*hue < 1) - return (a+(b-a)*6*hue) - if(2*hue < 1) - return b - if(3*hue < 2) - return (a+(b-a)*((2/3)-hue)*6) - return a - -// Very ugly, BYOND doesn't support unix time and rounding errors make it really hard to convert it to BYOND time. -// returns "YYYY-MM-DD" by default -/proc/unix2date(timestamp, seperator = "-") - - if(timestamp < 0) - return 0 //Do not accept negative values - - var/year = 1970 //Unix Epoc begins 1970-01-01 - var/dayInSeconds = 86400 //60secs*60mins*24hours - var/daysInYear = 365 //Non Leap Year - var/daysInLYear = daysInYear + 1//Leap year - var/days = round(timestamp / dayInSeconds) //Days passed since UNIX Epoc - var/tmpDays = days + 1 //If passed (timestamp < dayInSeconds), it will return 0, so add 1 - var/monthsInDays = list() //Months will be in here ***Taken from the PHP source code*** - var/month = 1 //This will be the returned MONTH NUMBER. - var/day //This will be the returned day number. - - while(tmpDays > daysInYear) //Start adding years to 1970 - year++ - if(isLeap(year)) - tmpDays -= daysInLYear - else - tmpDays -= daysInYear - - if(isLeap(year)) //The year is a leap year - monthsInDays = list(-1,30,59,90,120,151,181,212,243,273,304,334) - else - monthsInDays = list(0,31,59,90,120,151,181,212,243,273,304,334) - - var/mDays = 0; - var/monthIndex = 0; - - for(var/m in monthsInDays) - monthIndex++ - if(tmpDays > m) - mDays = m - month = monthIndex - - day = tmpDays - mDays //Setup the date - - return "[year][seperator][((month < 10) ? "0[month]" : month)][seperator][((day < 10) ? "0[day]" : day)]" - -/proc/isLeap(y) - return ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0)) - - - -//Turns a Body_parts_covered bitfield into a list of organ/limb names. -//(I challenge you to find a use for this) -/proc/body_parts_covered2organ_names(bpc) - var/list/covered_parts = list() - - if(!bpc) - return 0 - - if(bpc & FULL_BODY) - covered_parts |= list(BODY_ZONE_L_ARM,BODY_ZONE_R_ARM,BODY_ZONE_HEAD,BODY_ZONE_CHEST,BODY_ZONE_L_LEG,BODY_ZONE_R_LEG) - - else - if(bpc & HEAD) - covered_parts |= list(BODY_ZONE_HEAD) - if(bpc & CHEST) - covered_parts |= list(BODY_ZONE_CHEST) - if(bpc & GROIN) - covered_parts |= list(BODY_ZONE_CHEST) - - if(bpc & ARMS) - covered_parts |= list(BODY_ZONE_L_ARM,BODY_ZONE_R_ARM) - else - if(bpc & ARM_LEFT) - covered_parts |= list(BODY_ZONE_L_ARM) - if(bpc & ARM_RIGHT) - covered_parts |= list(BODY_ZONE_R_ARM) - - if(bpc & HANDS) - covered_parts |= list(BODY_ZONE_L_ARM,BODY_ZONE_R_ARM) - else - if(bpc & HAND_LEFT) - covered_parts |= list(BODY_ZONE_L_ARM) - if(bpc & HAND_RIGHT) - covered_parts |= list(BODY_ZONE_R_ARM) - - if(bpc & LEGS) - covered_parts |= list(BODY_ZONE_L_LEG,BODY_ZONE_R_LEG) - else - if(bpc & LEG_LEFT) - covered_parts |= list(BODY_ZONE_L_LEG) - if(bpc & LEG_RIGHT) - covered_parts |= list(BODY_ZONE_R_LEG) - - if(bpc & FEET) - covered_parts |= list(BODY_ZONE_L_LEG,BODY_ZONE_R_LEG) - else - if(bpc & FOOT_LEFT) - covered_parts |= list(BODY_ZONE_L_LEG) - if(bpc & FOOT_RIGHT) - covered_parts |= list(BODY_ZONE_R_LEG) - - return covered_parts - -/proc/slot2body_zone(slot) - switch(slot) - if(SLOT_BACK, SLOT_WEAR_SUIT, SLOT_W_UNIFORM, SLOT_BELT, SLOT_WEAR_ID) - return BODY_ZONE_CHEST - - if(SLOT_GLOVES, SLOT_HANDS, SLOT_HANDCUFFED) - return pick(BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND) - - if(SLOT_HEAD, SLOT_NECK, SLOT_NECK, SLOT_EARS) - return BODY_ZONE_HEAD - - if(SLOT_WEAR_MASK) - return BODY_ZONE_PRECISE_MOUTH - - if(SLOT_GLASSES) - return BODY_ZONE_PRECISE_EYES - - if(SLOT_SHOES) - return pick(BODY_ZONE_PRECISE_R_FOOT, BODY_ZONE_PRECISE_L_FOOT) - - if(SLOT_LEGCUFFED) - return pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) - -//adapted from http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/ -/proc/heat2colour(temp) - return rgb(heat2colour_r(temp), heat2colour_g(temp), heat2colour_b(temp)) - - -/proc/heat2colour_r(temp) - temp /= 100 - if(temp <= 66) - . = 255 - else - . = max(0, min(255, 329.698727446 * (temp - 60) ** -0.1332047592)) - - -/proc/heat2colour_g(temp) - temp /= 100 - if(temp <= 66) - . = max(0, min(255, 99.4708025861 * log(temp) - 161.1195681661)) - else - . = max(0, min(255, 288.1221685293 * ((temp - 60) ** -0.075148492))) - - -/proc/heat2colour_b(temp) - temp /= 100 - if(temp >= 66) - . = 255 - else - if(temp <= 16) - . = 0 - else - . = max(0, min(255, 138.5177312231 * log(temp - 10) - 305.0447927307)) - -/proc/fusionpower2text(power) //used when displaying fusion power on analyzers - switch(power) - if(0 to 5) - return "low" - if(5 to 20) - return "mid" - if(20 to 50) - return "high" - if(50 to INFINITY) - return "super" - -/proc/color2hex(color) //web colors - if(!color) - return "#000000" - - switch(color) - if("white") - return "#FFFFFF" - if("black") - return "#000000" - if("gray") - return "#808080" - if("brown") - return "#A52A2A" - if("red") - return "#FF0000" - if("darkred") - return "#8B0000" - if("crimson") - return "#DC143C" - if("orange") - return "#FFA500" - if("yellow") - return "#FFFF00" - if("green") - return "#008000" - if("lime") - return "#00FF00" - if("darkgreen") - return "#006400" - if("cyan") - return "#00FFFF" - if("blue") - return "#0000FF" - if("navy") - return "#000080" - if("teal") - return "#008080" - if("purple") - return "#800080" - if("indigo") - return "#4B0082" - else - return "#FFFFFF" - - -//This is a weird one: -//It returns a list of all var names found in the string -//These vars must be in the [var_name] format -//It's only a proc because it's used in more than one place - -//Takes a string and a datum -//The string is well, obviously the string being checked -//The datum is used as a source for var names, to check validity -//Otherwise every single word could technically be a variable! -/proc/string2listofvars(var/t_string, var/datum/var_source) - if(!t_string || !var_source) - return list() - - . = list() - - var/var_found = findtext(t_string,"\[") //Not the actual variables, just a generic "should we even bother" check - if(var_found) - //Find var names - - // "A dog said hi [name]!" - // splittext() --> list("A dog said hi ","name]!" - // jointext() --> "A dog said hi name]!" - // splittext() --> list("A","dog","said","hi","name]!") - - t_string = replacetext(t_string,"\[","\[ ")//Necessary to resolve "word[var_name]" scenarios - var/list/list_value = splittext(t_string,"\[") - var/intermediate_stage = jointext(list_value, null) - - list_value = splittext(intermediate_stage," ") - for(var/value in list_value) - if(findtext(value,"]")) - value = splittext(value,"]") //"name]!" --> list("name","!") - for(var/A in value) - if(var_source.vars.Find(A)) - . += A - -//assumes format #RRGGBB #rrggbb -/proc/color_hex2num(A) - if(!A) - return 0 - var/R = hex2num(copytext(A,2,4)) - var/G = hex2num(copytext(A,4,6)) - var/B = hex2num(copytext(A,6,0)) - return R+G+B - -//word of warning: using a matrix like this as a color value will simplify it back to a string after being set -/proc/color_hex2color_matrix(string) - var/length = length(string) - if(length != 7 && length != 9) - return color_matrix_identity() - var/r = hex2num(copytext(string, 2, 4))/255 - var/g = hex2num(copytext(string, 4, 6))/255 - var/b = hex2num(copytext(string, 6, 8))/255 - var/a = 1 - if(length == 9) - a = hex2num(copytext(string, 8, 10))/255 - if(!isnum(r) || !isnum(g) || !isnum(b) || !isnum(a)) - return color_matrix_identity() - return list(r,0,0,0, 0,g,0,0, 0,0,b,0, 0,0,0,a, 0,0,0,0) - -//will drop all values not on the diagonal -/proc/color_matrix2color_hex(list/the_matrix) - if(!istype(the_matrix) || the_matrix.len != 20) - return "#ffffffff" - return rgb(the_matrix[1]*255, the_matrix[6]*255, the_matrix[11]*255, the_matrix[16]*255) - -/proc/type2parent(child) - var/string_type = "[child]" - var/last_slash = findlasttext(string_type, "/") - if(last_slash == 1) - switch(child) - if(/datum) - return null - if(/obj || /mob) - return /atom/movable - if(/area || /turf) - return /atom - else - return /datum - return text2path(copytext(string_type, 1, last_slash)) - -//returns a string the last bit of a type, without the preceeding '/' -/proc/type2top(the_type) - //handle the builtins manually - if(!ispath(the_type)) - return - switch(the_type) - if(/datum) - return "datum" - if(/atom) - return "atom" - if(/obj) - return "obj" - if(/mob) - return "mob" - if(/area) - return "area" - if(/turf) - return "turf" - else //regex everything else (works for /proc too) - return lowertext(replacetext("[the_type]", "[type2parent(the_type)]/", "")) - -/proc/strtohex(str) - if(!istext(str)||!str) - return - var/r - var/c - for(var/i = 1 to length(str)) - c= text2ascii(str,i) - r+= num2hex(c) - return r - -// Decodes hex to raw byte string. -// If safe=TRUE, returns null on incorrect input strings instead of CRASHing -/proc/hextostr(str, safe=FALSE) - if(!istext(str)||!str) - return - var/r - var/c - for(var/i = 1 to length(str)/2) - c = hex2num(copytext(str,i*2-1,i*2+1), safe) - if(isnull(c)) - return null - r += ascii2text(c) - return r +/* + * Holds procs designed to change one type of value, into another. + * Contains: + * hex2num & num2hex + * file2list + * angle2dir + * angle2text + * worldtime2text + * text2dir_extended & dir2text_short + */ + +//Returns an integer given a hex input, supports negative values "-ff" +//skips preceding invalid characters +//breaks when hittin invalid characters thereafter +// If safe=TRUE, returns null on incorrect input strings instead of CRASHing +/proc/hex2num(hex, safe=FALSE) + . = 0 + var/place = 1 + for(var/i in length(hex) to 1 step -1) + var/num = text2ascii(hex, i) + switch(num) + if(48 to 57) + num -= 48 //0-9 + if(97 to 102) + num -= 87 //a-f + if(65 to 70) + num -= 55 //A-F + if(45) + return . * -1 // - + else + if(safe) + return null + else + CRASH("Malformed hex number") + + . += num * place + place *= 16 + +//Returns the hex value of a decimal number +//len == length of returned string +//if len < 0 then the returned string will be as long as it needs to be to contain the data +//Only supports positive numbers +//if an invalid number is provided, it assumes num==0 +//Note, unlike previous versions, this one works from low to high <-- that way +/proc/num2hex(num, len=2) + if(!isnum(num)) + num = 0 + num = round(abs(num)) + . = "" + var/i=0 + while(1) + if(len<=0) + if(!num) + break + else + if(i>=len) + break + var/remainder = num/16 + num = round(remainder) + remainder = (remainder - num) * 16 + switch(remainder) + if(9,8,7,6,5,4,3,2,1) + . = "[remainder]" + . + if(10,11,12,13,14,15) + . = ascii2text(remainder+87) + . + else + . = "0" + . + i++ + return . + +//Splits the text of a file at seperator and returns them in a list. +//returns an empty list if the file doesn't exist +/world/proc/file2list(filename, seperator="\n", trim = TRUE) + if (trim) + return splittext(trim(file2text(filename)),seperator) + return splittext(file2text(filename),seperator) + +//Turns a direction into text +/proc/dir2text(direction) + switch(direction) + if(1) + return "north" + if(2) + return "south" + if(4) + return "east" + if(8) + return "west" + if(5) + return "northeast" + if(6) + return "southeast" + if(9) + return "northwest" + if(10) + return "southwest" + else + return + +//Turns text into proper directions +/proc/text2dir(direction) + switch(uppertext(direction)) + if("NORTH") + return 1 + if("SOUTH") + return 2 + if("EAST") + return 4 + if("WEST") + return 8 + if("NORTHEAST") + return 5 + if("NORTHWEST") + return 9 + if("SOUTHEAST") + return 6 + if("SOUTHWEST") + return 10 + else + return + +//Converts an angle (degrees) into an ss13 direction +/proc/angle2dir(degree) + + degree = SIMPLIFY_DEGREES(degree) + switch(degree) + if(0 to 22.5) //north requires two angle ranges + return NORTH + if(22.5 to 67.5) //each range covers 45 degrees + return NORTHEAST + if(67.5 to 112.5) + return EAST + if(112.5 to 157.5) + return SOUTHEAST + if(157.5 to 202.5) + return SOUTH + if(202.5 to 247.5) + return SOUTHWEST + if(247.5 to 292.5) + return WEST + if(292.5 to 337.5) + return NORTHWEST + if(337.5 to 360) + return NORTH + +/proc/angle2dir_cardinal(angle) + switch(round(angle, 0.1)) + if(315.5 to 360, 0 to 45.5) + return NORTH + if(45.6 to 135.5) + return EAST + if(135.6 to 225.5) + return SOUTH + if(225.6 to 315.5) + return WEST + +//returns the north-zero clockwise angle in degrees, given a direction +/proc/dir2angle(D) + switch(D) + if(NORTH) + return 0 + if(SOUTH) + return 180 + if(EAST) + return 90 + if(WEST) + return 270 + if(NORTHEAST) + return 45 + if(SOUTHEAST) + return 135 + if(NORTHWEST) + return 315 + if(SOUTHWEST) + return 225 + else + return null + +//Returns the angle in english +/proc/angle2text(degree) + return dir2text(angle2dir(degree)) + +//Converts a blend_mode constant to one acceptable to icon.Blend() +/proc/blendMode2iconMode(blend_mode) + switch(blend_mode) + if(BLEND_MULTIPLY) + return ICON_MULTIPLY + if(BLEND_ADD) + return ICON_ADD + if(BLEND_SUBTRACT) + return ICON_SUBTRACT + else + return ICON_OVERLAY + +//Converts a rights bitfield into a string +/proc/rights2text(rights, seperator="", prefix = "+") + seperator += prefix + if(rights & R_BUILDMODE) + . += "[seperator]BUILDMODE" + if(rights & R_ADMIN) + . += "[seperator]ADMIN" + if(rights & R_BAN) + . += "[seperator]BAN" + if(rights & R_FUN) + . += "[seperator]FUN" + if(rights & R_SERVER) + . += "[seperator]SERVER" + if(rights & R_DEBUG) + . += "[seperator]DEBUG" + if(rights & R_POSSESS) + . += "[seperator]POSSESS" + if(rights & R_PERMISSIONS) + . += "[seperator]PERMISSIONS" + if(rights & R_STEALTH) + . += "[seperator]STEALTH" + if(rights & R_POLL) + . += "[seperator]POLL" + if(rights & R_VAREDIT) + . += "[seperator]VAREDIT" + if(rights & R_SOUNDS) + . += "[seperator]SOUND" + if(rights & R_SPAWN) + . += "[seperator]SPAWN" + if(rights & R_AUTOLOGIN) + . += "[seperator]AUTOLOGIN" + if(rights & R_DBRANKS) + . += "[seperator]DBRANKS" + if(!.) + . = "NONE" + return . + +//colour formats +/proc/rgb2hsl(red, green, blue) + red /= 255;green /= 255;blue /= 255; + var/max = max(red,green,blue) + var/min = min(red,green,blue) + var/range = max-min + + var/hue=0;var/saturation=0;var/lightness=0; + lightness = (max + min)/2 + if(range != 0) + if(lightness < 0.5) + saturation = range/(max+min) + else + saturation = range/(2-max-min) + + var/dred = ((max-red)/(6*max)) + 0.5 + var/dgreen = ((max-green)/(6*max)) + 0.5 + var/dblue = ((max-blue)/(6*max)) + 0.5 + + if(max==red) + hue = dblue - dgreen + else if(max==green) + hue = dred - dblue + (1/3) + else + hue = dgreen - dred + (2/3) + if(hue < 0) + hue++ + else if(hue > 1) + hue-- + + return list(hue, saturation, lightness) + +/proc/hsl2rgb(hue, saturation, lightness) + var/red;var/green;var/blue; + if(saturation == 0) + red = lightness * 255 + green = red + blue = red + else + var/a;var/b; + if(lightness < 0.5) + b = lightness*(1+saturation) + else + b = (lightness+saturation) - (saturation*lightness) + a = 2*lightness - b + + red = round(255 * hue2rgb(a, b, hue+(1/3))) + green = round(255 * hue2rgb(a, b, hue)) + blue = round(255 * hue2rgb(a, b, hue-(1/3))) + + return list(red, green, blue) + +/proc/hue2rgb(a, b, hue) + if(hue < 0) + hue++ + else if(hue > 1) + hue-- + if(6*hue < 1) + return (a+(b-a)*6*hue) + if(2*hue < 1) + return b + if(3*hue < 2) + return (a+(b-a)*((2/3)-hue)*6) + return a + +// Very ugly, BYOND doesn't support unix time and rounding errors make it really hard to convert it to BYOND time. +// returns "YYYY-MM-DD" by default +/proc/unix2date(timestamp, seperator = "-") + + if(timestamp < 0) + return 0 //Do not accept negative values + + var/year = 1970 //Unix Epoc begins 1970-01-01 + var/dayInSeconds = 86400 //60secs*60mins*24hours + var/daysInYear = 365 //Non Leap Year + var/daysInLYear = daysInYear + 1//Leap year + var/days = round(timestamp / dayInSeconds) //Days passed since UNIX Epoc + var/tmpDays = days + 1 //If passed (timestamp < dayInSeconds), it will return 0, so add 1 + var/monthsInDays = list() //Months will be in here ***Taken from the PHP source code*** + var/month = 1 //This will be the returned MONTH NUMBER. + var/day //This will be the returned day number. + + while(tmpDays > daysInYear) //Start adding years to 1970 + year++ + if(isLeap(year)) + tmpDays -= daysInLYear + else + tmpDays -= daysInYear + + if(isLeap(year)) //The year is a leap year + monthsInDays = list(-1,30,59,90,120,151,181,212,243,273,304,334) + else + monthsInDays = list(0,31,59,90,120,151,181,212,243,273,304,334) + + var/mDays = 0; + var/monthIndex = 0; + + for(var/m in monthsInDays) + monthIndex++ + if(tmpDays > m) + mDays = m + month = monthIndex + + day = tmpDays - mDays //Setup the date + + return "[year][seperator][((month < 10) ? "0[month]" : month)][seperator][((day < 10) ? "0[day]" : day)]" + +/proc/isLeap(y) + return ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0)) + + + +//Turns a Body_parts_covered bitfield into a list of organ/limb names. +//(I challenge you to find a use for this) +/proc/body_parts_covered2organ_names(bpc) + var/list/covered_parts = list() + + if(!bpc) + return 0 + + if(bpc & FULL_BODY) + covered_parts |= list(BODY_ZONE_L_ARM,BODY_ZONE_R_ARM,BODY_ZONE_HEAD,BODY_ZONE_CHEST,BODY_ZONE_L_LEG,BODY_ZONE_R_LEG) + + else + if(bpc & HEAD) + covered_parts |= list(BODY_ZONE_HEAD) + if(bpc & CHEST) + covered_parts |= list(BODY_ZONE_CHEST) + if(bpc & GROIN) + covered_parts |= list(BODY_ZONE_CHEST) + + if(bpc & ARMS) + covered_parts |= list(BODY_ZONE_L_ARM,BODY_ZONE_R_ARM) + else + if(bpc & ARM_LEFT) + covered_parts |= list(BODY_ZONE_L_ARM) + if(bpc & ARM_RIGHT) + covered_parts |= list(BODY_ZONE_R_ARM) + + if(bpc & HANDS) + covered_parts |= list(BODY_ZONE_L_ARM,BODY_ZONE_R_ARM) + else + if(bpc & HAND_LEFT) + covered_parts |= list(BODY_ZONE_L_ARM) + if(bpc & HAND_RIGHT) + covered_parts |= list(BODY_ZONE_R_ARM) + + if(bpc & LEGS) + covered_parts |= list(BODY_ZONE_L_LEG,BODY_ZONE_R_LEG) + else + if(bpc & LEG_LEFT) + covered_parts |= list(BODY_ZONE_L_LEG) + if(bpc & LEG_RIGHT) + covered_parts |= list(BODY_ZONE_R_LEG) + + if(bpc & FEET) + covered_parts |= list(BODY_ZONE_L_LEG,BODY_ZONE_R_LEG) + else + if(bpc & FOOT_LEFT) + covered_parts |= list(BODY_ZONE_L_LEG) + if(bpc & FOOT_RIGHT) + covered_parts |= list(BODY_ZONE_R_LEG) + + return covered_parts + +/proc/slot2body_zone(slot) + switch(slot) + if(SLOT_BACK, SLOT_WEAR_SUIT, SLOT_W_UNIFORM, SLOT_BELT, SLOT_WEAR_ID) + return BODY_ZONE_CHEST + + if(SLOT_GLOVES, SLOT_HANDS, SLOT_HANDCUFFED) + return pick(BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND) + + if(SLOT_HEAD, SLOT_NECK, SLOT_NECK, SLOT_EARS) + return BODY_ZONE_HEAD + + if(SLOT_WEAR_MASK) + return BODY_ZONE_PRECISE_MOUTH + + if(SLOT_GLASSES) + return BODY_ZONE_PRECISE_EYES + + if(SLOT_SHOES) + return pick(BODY_ZONE_PRECISE_R_FOOT, BODY_ZONE_PRECISE_L_FOOT) + + if(SLOT_LEGCUFFED) + return pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) + +//adapted from http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/ +/proc/heat2colour(temp) + return rgb(heat2colour_r(temp), heat2colour_g(temp), heat2colour_b(temp)) + + +/proc/heat2colour_r(temp) + temp /= 100 + if(temp <= 66) + . = 255 + else + . = max(0, min(255, 329.698727446 * (temp - 60) ** -0.1332047592)) + + +/proc/heat2colour_g(temp) + temp /= 100 + if(temp <= 66) + . = max(0, min(255, 99.4708025861 * log(temp) - 161.1195681661)) + else + . = max(0, min(255, 288.1221685293 * ((temp - 60) ** -0.075148492))) + + +/proc/heat2colour_b(temp) + temp /= 100 + if(temp >= 66) + . = 255 + else + if(temp <= 16) + . = 0 + else + . = max(0, min(255, 138.5177312231 * log(temp - 10) - 305.0447927307)) + +/proc/fusionpower2text(power) //used when displaying fusion power on analyzers + switch(power) + if(0 to 5) + return "low" + if(5 to 20) + return "mid" + if(20 to 50) + return "high" + if(50 to INFINITY) + return "super" + +/proc/color2hex(color) //web colors + if(!color) + return "#000000" + + switch(color) + if("white") + return "#FFFFFF" + if("black") + return "#000000" + if("gray") + return "#808080" + if("brown") + return "#A52A2A" + if("red") + return "#FF0000" + if("darkred") + return "#8B0000" + if("crimson") + return "#DC143C" + if("orange") + return "#FFA500" + if("yellow") + return "#FFFF00" + if("green") + return "#008000" + if("lime") + return "#00FF00" + if("darkgreen") + return "#006400" + if("cyan") + return "#00FFFF" + if("blue") + return "#0000FF" + if("navy") + return "#000080" + if("teal") + return "#008080" + if("purple") + return "#800080" + if("indigo") + return "#4B0082" + else + return "#FFFFFF" + + +//This is a weird one: +//It returns a list of all var names found in the string +//These vars must be in the [var_name] format +//It's only a proc because it's used in more than one place + +//Takes a string and a datum +//The string is well, obviously the string being checked +//The datum is used as a source for var names, to check validity +//Otherwise every single word could technically be a variable! +/proc/string2listofvars(var/t_string, var/datum/var_source) + if(!t_string || !var_source) + return list() + + . = list() + + var/var_found = findtext(t_string,"\[") //Not the actual variables, just a generic "should we even bother" check + if(var_found) + //Find var names + + // "A dog said hi [name]!" + // splittext() --> list("A dog said hi ","name]!" + // jointext() --> "A dog said hi name]!" + // splittext() --> list("A","dog","said","hi","name]!") + + t_string = replacetext(t_string,"\[","\[ ")//Necessary to resolve "word[var_name]" scenarios + var/list/list_value = splittext(t_string,"\[") + var/intermediate_stage = jointext(list_value, null) + + list_value = splittext(intermediate_stage," ") + for(var/value in list_value) + if(findtext(value,"]")) + value = splittext(value,"]") //"name]!" --> list("name","!") + for(var/A in value) + if(var_source.vars.Find(A)) + . += A + +//assumes format #RRGGBB #rrggbb +/proc/color_hex2num(A) + if(!A) + return 0 + var/R = hex2num(copytext(A,2,4)) + var/G = hex2num(copytext(A,4,6)) + var/B = hex2num(copytext(A,6,0)) + return R+G+B + +//word of warning: using a matrix like this as a color value will simplify it back to a string after being set +/proc/color_hex2color_matrix(string) + var/length = length(string) + if(length != 7 && length != 9) + return color_matrix_identity() + var/r = hex2num(copytext(string, 2, 4))/255 + var/g = hex2num(copytext(string, 4, 6))/255 + var/b = hex2num(copytext(string, 6, 8))/255 + var/a = 1 + if(length == 9) + a = hex2num(copytext(string, 8, 10))/255 + if(!isnum(r) || !isnum(g) || !isnum(b) || !isnum(a)) + return color_matrix_identity() + return list(r,0,0,0, 0,g,0,0, 0,0,b,0, 0,0,0,a, 0,0,0,0) + +//will drop all values not on the diagonal +/proc/color_matrix2color_hex(list/the_matrix) + if(!istype(the_matrix) || the_matrix.len != 20) + return "#ffffffff" + return rgb(the_matrix[1]*255, the_matrix[6]*255, the_matrix[11]*255, the_matrix[16]*255) + +/proc/type2parent(child) + var/string_type = "[child]" + var/last_slash = findlasttext(string_type, "/") + if(last_slash == 1) + switch(child) + if(/datum) + return null + if(/obj || /mob) + return /atom/movable + if(/area || /turf) + return /atom + else + return /datum + return text2path(copytext(string_type, 1, last_slash)) + +//returns a string the last bit of a type, without the preceeding '/' +/proc/type2top(the_type) + //handle the builtins manually + if(!ispath(the_type)) + return + switch(the_type) + if(/datum) + return "datum" + if(/atom) + return "atom" + if(/obj) + return "obj" + if(/mob) + return "mob" + if(/area) + return "area" + if(/turf) + return "turf" + else //regex everything else (works for /proc too) + return lowertext(replacetext("[the_type]", "[type2parent(the_type)]/", "")) + +/proc/strtohex(str) + if(!istext(str)||!str) + return + var/r + var/c + for(var/i = 1 to length(str)) + c= text2ascii(str,i) + r+= num2hex(c) + return r + +// Decodes hex to raw byte string. +// If safe=TRUE, returns null on incorrect input strings instead of CRASHing +/proc/hextostr(str, safe=FALSE) + if(!istext(str)||!str) + return + var/r + var/c + for(var/i = 1 to length(str)/2) + c = hex2num(copytext(str,i*2-1,i*2+1), safe) + if(isnull(c)) + return null + r += ascii2text(c) + return r diff --git a/code/_compile_options.dm b/code/_compile_options.dm index 3ec2510cc7..af948086df 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -1,57 +1,57 @@ -//#define TESTING //By using the testing("message") proc you can create debug-feedback for people with this - //uncommented, but not visible in the release version) - -//#define DATUMVAR_DEBUGGING_MODE //Enables the ability to cache datum vars and retrieve later for debugging which vars changed. - -// Comment this out if you are debugging problems that might be obscured by custom error handling in world/Error -#ifdef DEBUG -#define USE_CUSTOM_ERROR_HANDLER -#endif - -#ifdef TESTING -#define DATUMVAR_DEBUGGING_MODE - -//#define GC_FAILURE_HARD_LOOKUP //makes paths that fail to GC call find_references before del'ing. - //implies FIND_REF_NO_CHECK_TICK - -//#define FIND_REF_NO_CHECK_TICK //Sets world.loop_checks to false and prevents find references from sleeping - - -//#define VISUALIZE_ACTIVE_TURFS //Highlights atmos active turfs in green -#endif - -//#define UNIT_TESTS //Enables unit tests via TEST_RUN_PARAMETER - -#ifndef PRELOAD_RSC //set to: -#define PRELOAD_RSC 2 // 0 to allow using external resources or on-demand behaviour; -#endif // 1 to use the default behaviour; - // 2 for preloading absolutely everything; - -#ifdef LOWMEMORYMODE -#define FORCE_MAP "_maps/runtimestation.json" -#endif - -//Update this whenever you need to take advantage of more recent byond features -#define MIN_COMPILER_VERSION 512 -#if DM_VERSION < MIN_COMPILER_VERSION -//Don't forget to update this part -#error Your version of BYOND is too out-of-date to compile this project. Go to https://secure.byond.com/download and update. -#error You need version 512 or higher -#endif - -//Additional code for the above flags. -#ifdef TESTING -#warn compiling in TESTING mode. testing() debug messages will be visible. -#endif - -#ifdef GC_FAILURE_HARD_LOOKUP -#define FIND_REF_NO_CHECK_TICK -#endif - -#ifdef TRAVISBUILDING -#define UNIT_TESTS -#endif - -#ifdef TRAVISTESTING -#define TESTING -#endif +//#define TESTING //By using the testing("message") proc you can create debug-feedback for people with this + //uncommented, but not visible in the release version) + +//#define DATUMVAR_DEBUGGING_MODE //Enables the ability to cache datum vars and retrieve later for debugging which vars changed. + +// Comment this out if you are debugging problems that might be obscured by custom error handling in world/Error +#ifdef DEBUG +#define USE_CUSTOM_ERROR_HANDLER +#endif + +#ifdef TESTING +#define DATUMVAR_DEBUGGING_MODE + +//#define GC_FAILURE_HARD_LOOKUP //makes paths that fail to GC call find_references before del'ing. + //implies FIND_REF_NO_CHECK_TICK + +//#define FIND_REF_NO_CHECK_TICK //Sets world.loop_checks to false and prevents find references from sleeping + + +//#define VISUALIZE_ACTIVE_TURFS //Highlights atmos active turfs in green +#endif + +//#define UNIT_TESTS //Enables unit tests via TEST_RUN_PARAMETER + +#ifndef PRELOAD_RSC //set to: +#define PRELOAD_RSC 2 // 0 to allow using external resources or on-demand behaviour; +#endif // 1 to use the default behaviour; + // 2 for preloading absolutely everything; + +#ifdef LOWMEMORYMODE +#define FORCE_MAP "_maps/runtimestation.json" +#endif + +//Update this whenever you need to take advantage of more recent byond features +#define MIN_COMPILER_VERSION 512 +#if DM_VERSION < MIN_COMPILER_VERSION +//Don't forget to update this part +#error Your version of BYOND is too out-of-date to compile this project. Go to https://secure.byond.com/download and update. +#error You need version 512 or higher +#endif + +//Additional code for the above flags. +#ifdef TESTING +#warn compiling in TESTING mode. testing() debug messages will be visible. +#endif + +#ifdef GC_FAILURE_HARD_LOOKUP +#define FIND_REF_NO_CHECK_TICK +#endif + +#ifdef TRAVISBUILDING +#define UNIT_TESTS +#endif + +#ifdef TRAVISTESTING +#define TESTING +#endif diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index bf179760c0..5d95a4eaae 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -1,215 +1,215 @@ -GLOBAL_LIST_INIT(bitfields, list( - "appearance_flags" = list( - "LONG_GLIDE" = LONG_GLIDE, - "RESET_COLOR" = RESET_COLOR, - "RESET_ALPHA" = RESET_ALPHA, - "RESET_TRANSFORM" = RESET_TRANSFORM, - "NO_CLIENT_COLOR" = NO_CLIENT_COLOR, - "KEEP_TOGETHER" = KEEP_TOGETHER, - "KEEP_APART" = KEEP_APART, - "PLANE_MASTER" = PLANE_MASTER, - "TILE_BOUND" = TILE_BOUND, - "PIXEL_SCALE" = PIXEL_SCALE - ), - "sight" = list( - "SEE_INFRA" = SEE_INFRA, - "SEE_SELF" = SEE_SELF, - "SEE_MOBS" = SEE_MOBS, - "SEE_OBJS" = SEE_OBJS, - "SEE_TURFS" = SEE_TURFS, - "SEE_PIXELS" = SEE_PIXELS, - "SEE_THRU" = SEE_THRU, - "SEE_BLACKNESS" = SEE_BLACKNESS, - "BLIND" = BLIND - ), - "obj_flags" = list( - "EMAGGED" = EMAGGED, - "IN_USE" = IN_USE, - "CAN_BE_HIT" = CAN_BE_HIT, - "BEING_SHOCKED" = BEING_SHOCKED, - "DANGEROUS_POSSESSION" = DANGEROUS_POSSESSION, - "ON_BLUEPRINTS" = ON_BLUEPRINTS, - "UNIQUE_RENAME" = UNIQUE_RENAME, - "USES_TGUI" = USES_TGUI, - "FROZEN" = FROZEN, - "SHOVABLE_ONTO" = SHOVABLE_ONTO - ), - "datum_flags" = list( - "DF_USE_TAG" = DF_USE_TAG, - "DF_VAR_EDITED" = DF_VAR_EDITED, - "DF_ISPROCESSING" = DF_ISPROCESSING, - ), - "item_flags" = list( - "BEING_REMOVED" = BEING_REMOVED, - "IN_INVENTORY" = IN_INVENTORY, - "FORCE_STRING_OVERRIDE" = FORCE_STRING_OVERRIDE, - "NEEDS_PERMIT" = NEEDS_PERMIT, - "SLOWS_WHILE_IN_HAND" = SLOWS_WHILE_IN_HAND, - "NO_MAT_REDEMPTION" = NO_MAT_REDEMPTION, - "DROPDEL" = DROPDEL, - "NOBLUDGEON" = NOBLUDGEON, - "ABSTRACT" = ABSTRACT, - ), - "admin_flags" = list( - "BUILDMODE" = R_BUILDMODE, - "ADMIN" = R_ADMIN, - "BAN" = R_BAN, - "FUN" = R_FUN, - "SERVER" = R_SERVER, - "DEBUG" = R_DEBUG, - "POSSESS" = R_POSSESS, - "PERMISSIONS" = R_PERMISSIONS, - "STEALTH" = R_STEALTH, - "POLL" = R_POLL, - "VAREDIT" = R_VAREDIT, - "SOUNDS" = R_SOUNDS, - "SPAWN" = R_SPAWN, - "AUTOLOGIN" = R_AUTOLOGIN, - "DBRANKS" = R_DBRANKS - ), - "interaction_flags_atom" = list( - "INTERACT_ATOM_REQUIRES_ANCHORED" = INTERACT_ATOM_REQUIRES_ANCHORED, - "INTERACT_ATOM_ATTACK_HAND" = INTERACT_ATOM_ATTACK_HAND, - "INTERACT_ATOM_UI_INTERACT" = INTERACT_ATOM_UI_INTERACT, - "INTERACT_ATOM_REQUIRES_DEXTERITY" = INTERACT_ATOM_REQUIRES_DEXTERITY, - "INTERACT_ATOM_IGNORE_INCAPACITATED" = INTERACT_ATOM_IGNORE_INCAPACITATED, - "INTERACT_ATOM_IGNORE_RESTRAINED" = INTERACT_ATOM_IGNORE_RESTRAINED, - "INTERACT_ATOM_CHECK_GRAB" = INTERACT_ATOM_CHECK_GRAB, - "INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND" = INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND, - "INTERACT_ATOM_NO_FINGERPRINT_INTERACT" = INTERACT_ATOM_NO_FINGERPRINT_INTERACT - ), - "interaction_flags_machine" = list( - "INTERACT_MACHINE_OPEN" = INTERACT_MACHINE_OPEN, - "INTERACT_MACHINE_OFFLINE" = INTERACT_MACHINE_OFFLINE, - "INTERACT_MACHINE_WIRES_IF_OPEN" = INTERACT_MACHINE_WIRES_IF_OPEN, - "INTERACT_MACHINE_ALLOW_SILICON" = INTERACT_MACHINE_ALLOW_SILICON, - "INTERACT_MACHINE_OPEN_SILICON" = INTERACT_MACHINE_OPEN_SILICON, - "INTERACT_MACHINE_REQUIRES_SILICON" = INTERACT_MACHINE_REQUIRES_SILICON, - "INTERACT_MACHINE_SET_MACHINE" = INTERACT_MACHINE_SET_MACHINE - ), - "interaction_flags_item" = list( - "INTERACT_ITEM_ATTACK_HAND_PICKUP" = INTERACT_ITEM_ATTACK_HAND_PICKUP, - ), - "pass_flags" = list( - "PASSTABLE" = PASSTABLE, - "PASSGLASS" = PASSGLASS, - "PASSGRILLE" = PASSGRILLE, - "PASSBLOB" = PASSBLOB, - "PASSMOB" = PASSMOB, - "PASSCLOSEDTURF" = PASSCLOSEDTURF, - "LETPASSTHROW" = LETPASSTHROW - ), - "movement_type" = list( - "GROUND" = GROUND, - "FLYING" = FLYING - ), - "resistance_flags" = list( - "LAVA_PROOF" = LAVA_PROOF, - "FIRE_PROOF" = FIRE_PROOF, - "FLAMMABLE" = FLAMMABLE, - "ON_FIRE" = ON_FIRE, - "UNACIDABLE" = UNACIDABLE, - "ACID_PROOF" = ACID_PROOF, - "INDESTRUCTIBLE" = INDESTRUCTIBLE, - "FREEZE_PROOF" = FREEZE_PROOF, - "GOLIATH_RESISTANCE" = GOLIATH_RESISTANCE, - "GOLIATH_WEAKNESS" = GOLIATH_WEAKNESS - ), - "flags_1" = list( - "NOJAUNT_1" = NOJAUNT_1, - "UNUSED_RESERVATION_TURF_1" = UNUSED_RESERVATION_TURF_1, - "CAN_BE_DIRTY_1" = CAN_BE_DIRTY_1, - "HEAR_1" = HEAR_1, - "CHECK_RICOCHET_1" = CHECK_RICOCHET_1, - "CONDUCT_1" = CONDUCT_1, - "NO_LAVA_GEN_1" = NO_LAVA_GEN_1, - "NODECONSTRUCT_1" = NODECONSTRUCT_1, - "OVERLAY_QUEUED_1" = OVERLAY_QUEUED_1, - "ON_BORDER_1" = ON_BORDER_1, - "NO_RUINS_1" = NO_RUINS_1, - "PREVENT_CLICK_UNDER_1" = PREVENT_CLICK_UNDER_1, - "HOLOGRAM_1" = HOLOGRAM_1, - "TESLA_IGNORE_1" = TESLA_IGNORE_1, - "INITIALIZED_1" = INITIALIZED_1, - "ADMIN_SPAWNED_1" = ADMIN_SPAWNED_1, - ), - "clothing_flags" = list( - "LAVAPROTECT" = LAVAPROTECT, - "STOPSPRESSUREDAMAGE" = STOPSPRESSUREDAMAGE, - "BLOCK_GAS_SMOKE_EFFECT" = BLOCK_GAS_SMOKE_EFFECT, - "ALLOWINTERNALS" = ALLOWINTERNALS, - "NOSLIP" = NOSLIP, - "THICKMATERIAL" = THICKMATERIAL, - "VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE, - "VOICEBOX_DISABLED" = VOICEBOX_DISABLED, - "IGNORE_HAT_TOSS" = IGNORE_HAT_TOSS, - "SCAN_REAGENTS" = SCAN_REAGENTS - ), - "tesla_flags" = list( - "TESLA_MOB_DAMAGE" = TESLA_MOB_DAMAGE, - "TESLA_OBJ_DAMAGE" = TESLA_OBJ_DAMAGE, - "TESLA_MOB_STUN" = TESLA_MOB_STUN, - "TESLA_ALLOW_DUPLICATES" = TESLA_ALLOW_DUPLICATES, - "TESLA_MACHINE_EXPLOSIVE" = TESLA_MACHINE_EXPLOSIVE, - ), - "smooth" = list( - "SMOOTH_TRUE" = SMOOTH_TRUE, - "SMOOTH_MORE" = SMOOTH_MORE, - "SMOOTH_DIAGONAL" = SMOOTH_DIAGONAL, - "SMOOTH_BORDER" = SMOOTH_BORDER, - "SMOOTH_QUEUED" = SMOOTH_QUEUED, - ), - "reagents_holder_flags" = list( - "INJECTABLE" = INJECTABLE, - "DRAWABLE" = DRAWABLE, - "REFILLABLE" = REFILLABLE, - "DRAINABLE" = DRAINABLE, - "TRANSPARENT" = TRANSPARENT, - "AMOUNT_VISIBLE" = AMOUNT_VISIBLE, - "NO_REACT" = NO_REACT, - ), - "car_traits" = list( - "CAN_KIDNAP" = CAN_KIDNAP, - ), - "rad_flags" = list( - "RAD_PROTECT_CONTENTS" = RAD_PROTECT_CONTENTS, - "RAD_NO_CONTAMINATE" = RAD_NO_CONTAMINATE, - ), - "disease_flags" = list( - "CURABLE" = CURABLE, - "CAN_CARRY" = CAN_CARRY, - "CAN_RESIST" = CAN_RESIST - ), - "chemical_flags" = list( - "REAGENT_DEAD_PROCESS" = REAGENT_DEAD_PROCESS, - "REAGENT_DONOTSPLIT" = REAGENT_DONOTSPLIT, - "REAGENT_ONLYINVERSE" = REAGENT_ONLYINVERSE, - "REAGENT_ONMOBMERGE" = REAGENT_ONMOBMERGE, - "REAGENT_INVISIBLE" = REAGENT_INVISIBLE, - "REAGENT_FORCEONNEW" = REAGENT_FORCEONNEW, - "REAGENT_SNEAKYNAME" = REAGENT_SNEAKYNAME, - "REAGENT_SPLITRETAINVOL" = REAGENT_SPLITRETAINVOL - ), - "clear_conversion" = list( - "REACTION_CLEAR_IMPURE" = REACTION_CLEAR_IMPURE, - "REACTION_CLEAR_INVERSE" = REACTION_CLEAR_INVERSE - ), - "organ_flags" = list( - "ORGAN_SYNTHETIC" = ORGAN_SYNTHETIC, - "ORGAN_FROZEN" = ORGAN_FROZEN, - "ORGAN_FAILING" = ORGAN_FAILING, - "ORGAN_EXTERNAL" = ORGAN_EXTERNAL, - "ORGAN_VITAL" = ORGAN_VITAL, - "ORGAN_NO_SPOIL" = ORGAN_NO_SPOIL - ), - "genital_flags" = list( - "GENITAL_BLACKLISTED" = GENITAL_BLACKLISTED, - "GENITAL_INTERNAL" = GENITAL_INTERNAL, - "GENITAL_HIDDEN" = GENITAL_HIDDEN, - "GENITAL_THROUGH_CLOTHES" = GENITAL_THROUGH_CLOTHES, - "GENITAL_FUID_PRODUCTION" = GENITAL_FUID_PRODUCTION, - "CAN_MASTURBATE_WITH" = CAN_MASTURBATE_WITH, - "MASTURBATE_LINKED_ORGAN" = MASTURBATE_LINKED_ORGAN, - "CAN_CLIMAX_WITH" = CAN_CLIMAX_WITH - ) +GLOBAL_LIST_INIT(bitfields, list( + "appearance_flags" = list( + "LONG_GLIDE" = LONG_GLIDE, + "RESET_COLOR" = RESET_COLOR, + "RESET_ALPHA" = RESET_ALPHA, + "RESET_TRANSFORM" = RESET_TRANSFORM, + "NO_CLIENT_COLOR" = NO_CLIENT_COLOR, + "KEEP_TOGETHER" = KEEP_TOGETHER, + "KEEP_APART" = KEEP_APART, + "PLANE_MASTER" = PLANE_MASTER, + "TILE_BOUND" = TILE_BOUND, + "PIXEL_SCALE" = PIXEL_SCALE + ), + "sight" = list( + "SEE_INFRA" = SEE_INFRA, + "SEE_SELF" = SEE_SELF, + "SEE_MOBS" = SEE_MOBS, + "SEE_OBJS" = SEE_OBJS, + "SEE_TURFS" = SEE_TURFS, + "SEE_PIXELS" = SEE_PIXELS, + "SEE_THRU" = SEE_THRU, + "SEE_BLACKNESS" = SEE_BLACKNESS, + "BLIND" = BLIND + ), + "obj_flags" = list( + "EMAGGED" = EMAGGED, + "IN_USE" = IN_USE, + "CAN_BE_HIT" = CAN_BE_HIT, + "BEING_SHOCKED" = BEING_SHOCKED, + "DANGEROUS_POSSESSION" = DANGEROUS_POSSESSION, + "ON_BLUEPRINTS" = ON_BLUEPRINTS, + "UNIQUE_RENAME" = UNIQUE_RENAME, + "USES_TGUI" = USES_TGUI, + "FROZEN" = FROZEN, + "SHOVABLE_ONTO" = SHOVABLE_ONTO + ), + "datum_flags" = list( + "DF_USE_TAG" = DF_USE_TAG, + "DF_VAR_EDITED" = DF_VAR_EDITED, + "DF_ISPROCESSING" = DF_ISPROCESSING, + ), + "item_flags" = list( + "BEING_REMOVED" = BEING_REMOVED, + "IN_INVENTORY" = IN_INVENTORY, + "FORCE_STRING_OVERRIDE" = FORCE_STRING_OVERRIDE, + "NEEDS_PERMIT" = NEEDS_PERMIT, + "SLOWS_WHILE_IN_HAND" = SLOWS_WHILE_IN_HAND, + "NO_MAT_REDEMPTION" = NO_MAT_REDEMPTION, + "DROPDEL" = DROPDEL, + "NOBLUDGEON" = NOBLUDGEON, + "ABSTRACT" = ABSTRACT, + ), + "admin_flags" = list( + "BUILDMODE" = R_BUILDMODE, + "ADMIN" = R_ADMIN, + "BAN" = R_BAN, + "FUN" = R_FUN, + "SERVER" = R_SERVER, + "DEBUG" = R_DEBUG, + "POSSESS" = R_POSSESS, + "PERMISSIONS" = R_PERMISSIONS, + "STEALTH" = R_STEALTH, + "POLL" = R_POLL, + "VAREDIT" = R_VAREDIT, + "SOUNDS" = R_SOUNDS, + "SPAWN" = R_SPAWN, + "AUTOLOGIN" = R_AUTOLOGIN, + "DBRANKS" = R_DBRANKS + ), + "interaction_flags_atom" = list( + "INTERACT_ATOM_REQUIRES_ANCHORED" = INTERACT_ATOM_REQUIRES_ANCHORED, + "INTERACT_ATOM_ATTACK_HAND" = INTERACT_ATOM_ATTACK_HAND, + "INTERACT_ATOM_UI_INTERACT" = INTERACT_ATOM_UI_INTERACT, + "INTERACT_ATOM_REQUIRES_DEXTERITY" = INTERACT_ATOM_REQUIRES_DEXTERITY, + "INTERACT_ATOM_IGNORE_INCAPACITATED" = INTERACT_ATOM_IGNORE_INCAPACITATED, + "INTERACT_ATOM_IGNORE_RESTRAINED" = INTERACT_ATOM_IGNORE_RESTRAINED, + "INTERACT_ATOM_CHECK_GRAB" = INTERACT_ATOM_CHECK_GRAB, + "INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND" = INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND, + "INTERACT_ATOM_NO_FINGERPRINT_INTERACT" = INTERACT_ATOM_NO_FINGERPRINT_INTERACT + ), + "interaction_flags_machine" = list( + "INTERACT_MACHINE_OPEN" = INTERACT_MACHINE_OPEN, + "INTERACT_MACHINE_OFFLINE" = INTERACT_MACHINE_OFFLINE, + "INTERACT_MACHINE_WIRES_IF_OPEN" = INTERACT_MACHINE_WIRES_IF_OPEN, + "INTERACT_MACHINE_ALLOW_SILICON" = INTERACT_MACHINE_ALLOW_SILICON, + "INTERACT_MACHINE_OPEN_SILICON" = INTERACT_MACHINE_OPEN_SILICON, + "INTERACT_MACHINE_REQUIRES_SILICON" = INTERACT_MACHINE_REQUIRES_SILICON, + "INTERACT_MACHINE_SET_MACHINE" = INTERACT_MACHINE_SET_MACHINE + ), + "interaction_flags_item" = list( + "INTERACT_ITEM_ATTACK_HAND_PICKUP" = INTERACT_ITEM_ATTACK_HAND_PICKUP, + ), + "pass_flags" = list( + "PASSTABLE" = PASSTABLE, + "PASSGLASS" = PASSGLASS, + "PASSGRILLE" = PASSGRILLE, + "PASSBLOB" = PASSBLOB, + "PASSMOB" = PASSMOB, + "PASSCLOSEDTURF" = PASSCLOSEDTURF, + "LETPASSTHROW" = LETPASSTHROW + ), + "movement_type" = list( + "GROUND" = GROUND, + "FLYING" = FLYING + ), + "resistance_flags" = list( + "LAVA_PROOF" = LAVA_PROOF, + "FIRE_PROOF" = FIRE_PROOF, + "FLAMMABLE" = FLAMMABLE, + "ON_FIRE" = ON_FIRE, + "UNACIDABLE" = UNACIDABLE, + "ACID_PROOF" = ACID_PROOF, + "INDESTRUCTIBLE" = INDESTRUCTIBLE, + "FREEZE_PROOF" = FREEZE_PROOF, + "GOLIATH_RESISTANCE" = GOLIATH_RESISTANCE, + "GOLIATH_WEAKNESS" = GOLIATH_WEAKNESS + ), + "flags_1" = list( + "NOJAUNT_1" = NOJAUNT_1, + "UNUSED_RESERVATION_TURF_1" = UNUSED_RESERVATION_TURF_1, + "CAN_BE_DIRTY_1" = CAN_BE_DIRTY_1, + "HEAR_1" = HEAR_1, + "CHECK_RICOCHET_1" = CHECK_RICOCHET_1, + "CONDUCT_1" = CONDUCT_1, + "NO_LAVA_GEN_1" = NO_LAVA_GEN_1, + "NODECONSTRUCT_1" = NODECONSTRUCT_1, + "OVERLAY_QUEUED_1" = OVERLAY_QUEUED_1, + "ON_BORDER_1" = ON_BORDER_1, + "NO_RUINS_1" = NO_RUINS_1, + "PREVENT_CLICK_UNDER_1" = PREVENT_CLICK_UNDER_1, + "HOLOGRAM_1" = HOLOGRAM_1, + "TESLA_IGNORE_1" = TESLA_IGNORE_1, + "INITIALIZED_1" = INITIALIZED_1, + "ADMIN_SPAWNED_1" = ADMIN_SPAWNED_1, + ), + "clothing_flags" = list( + "LAVAPROTECT" = LAVAPROTECT, + "STOPSPRESSUREDAMAGE" = STOPSPRESSUREDAMAGE, + "BLOCK_GAS_SMOKE_EFFECT" = BLOCK_GAS_SMOKE_EFFECT, + "ALLOWINTERNALS" = ALLOWINTERNALS, + "NOSLIP" = NOSLIP, + "THICKMATERIAL" = THICKMATERIAL, + "VOICEBOX_TOGGLABLE" = VOICEBOX_TOGGLABLE, + "VOICEBOX_DISABLED" = VOICEBOX_DISABLED, + "IGNORE_HAT_TOSS" = IGNORE_HAT_TOSS, + "SCAN_REAGENTS" = SCAN_REAGENTS + ), + "tesla_flags" = list( + "TESLA_MOB_DAMAGE" = TESLA_MOB_DAMAGE, + "TESLA_OBJ_DAMAGE" = TESLA_OBJ_DAMAGE, + "TESLA_MOB_STUN" = TESLA_MOB_STUN, + "TESLA_ALLOW_DUPLICATES" = TESLA_ALLOW_DUPLICATES, + "TESLA_MACHINE_EXPLOSIVE" = TESLA_MACHINE_EXPLOSIVE, + ), + "smooth" = list( + "SMOOTH_TRUE" = SMOOTH_TRUE, + "SMOOTH_MORE" = SMOOTH_MORE, + "SMOOTH_DIAGONAL" = SMOOTH_DIAGONAL, + "SMOOTH_BORDER" = SMOOTH_BORDER, + "SMOOTH_QUEUED" = SMOOTH_QUEUED, + ), + "reagents_holder_flags" = list( + "INJECTABLE" = INJECTABLE, + "DRAWABLE" = DRAWABLE, + "REFILLABLE" = REFILLABLE, + "DRAINABLE" = DRAINABLE, + "TRANSPARENT" = TRANSPARENT, + "AMOUNT_VISIBLE" = AMOUNT_VISIBLE, + "NO_REACT" = NO_REACT, + ), + "car_traits" = list( + "CAN_KIDNAP" = CAN_KIDNAP, + ), + "rad_flags" = list( + "RAD_PROTECT_CONTENTS" = RAD_PROTECT_CONTENTS, + "RAD_NO_CONTAMINATE" = RAD_NO_CONTAMINATE, + ), + "disease_flags" = list( + "CURABLE" = CURABLE, + "CAN_CARRY" = CAN_CARRY, + "CAN_RESIST" = CAN_RESIST + ), + "chemical_flags" = list( + "REAGENT_DEAD_PROCESS" = REAGENT_DEAD_PROCESS, + "REAGENT_DONOTSPLIT" = REAGENT_DONOTSPLIT, + "REAGENT_ONLYINVERSE" = REAGENT_ONLYINVERSE, + "REAGENT_ONMOBMERGE" = REAGENT_ONMOBMERGE, + "REAGENT_INVISIBLE" = REAGENT_INVISIBLE, + "REAGENT_FORCEONNEW" = REAGENT_FORCEONNEW, + "REAGENT_SNEAKYNAME" = REAGENT_SNEAKYNAME, + "REAGENT_SPLITRETAINVOL" = REAGENT_SPLITRETAINVOL + ), + "clear_conversion" = list( + "REACTION_CLEAR_IMPURE" = REACTION_CLEAR_IMPURE, + "REACTION_CLEAR_INVERSE" = REACTION_CLEAR_INVERSE + ), + "organ_flags" = list( + "ORGAN_SYNTHETIC" = ORGAN_SYNTHETIC, + "ORGAN_FROZEN" = ORGAN_FROZEN, + "ORGAN_FAILING" = ORGAN_FAILING, + "ORGAN_EXTERNAL" = ORGAN_EXTERNAL, + "ORGAN_VITAL" = ORGAN_VITAL, + "ORGAN_NO_SPOIL" = ORGAN_NO_SPOIL + ), + "genital_flags" = list( + "GENITAL_BLACKLISTED" = GENITAL_BLACKLISTED, + "GENITAL_INTERNAL" = GENITAL_INTERNAL, + "GENITAL_HIDDEN" = GENITAL_HIDDEN, + "GENITAL_THROUGH_CLOTHES" = GENITAL_THROUGH_CLOTHES, + "GENITAL_FUID_PRODUCTION" = GENITAL_FUID_PRODUCTION, + "CAN_MASTURBATE_WITH" = CAN_MASTURBATE_WITH, + "MASTURBATE_LINKED_ORGAN" = MASTURBATE_LINKED_ORGAN, + "CAN_CLIMAX_WITH" = CAN_CLIMAX_WITH + ) )) \ No newline at end of file diff --git a/code/_globalvars/configuration.dm b/code/_globalvars/configuration.dm index 2334ce6bca..ed58f5779c 100644 --- a/code/_globalvars/configuration.dm +++ b/code/_globalvars/configuration.dm @@ -1,38 +1,38 @@ -GLOBAL_REAL(config, /datum/controller/configuration) - -GLOBAL_DATUM(revdata, /datum/getrev) - -GLOBAL_VAR(host) -GLOBAL_VAR(station_name) -GLOBAL_VAR_INIT(game_version, "/tg/ Station 13") -GLOBAL_VAR_INIT(changelog_hash, "") -GLOBAL_VAR_INIT(hub_visibility, FALSE) - -GLOBAL_VAR_INIT(ooc_allowed, TRUE) // used with admin verbs to disable ooc - not a config option apparently -GLOBAL_VAR_INIT(looc_allowed, TRUE) -GLOBAL_VAR_INIT(dooc_allowed, TRUE) -GLOBAL_VAR_INIT(aooc_allowed, FALSE) -GLOBAL_VAR_INIT(enter_allowed, TRUE) -GLOBAL_VAR_INIT(shuttle_frozen, FALSE) -GLOBAL_VAR_INIT(shuttle_left, FALSE) -GLOBAL_VAR_INIT(tinted_weldhelh, TRUE) - - -// Debug is used exactly once (in living.dm) but is commented out in a lot of places. It is not set anywhere and only checked. -// Debug2 is used in conjunction with a lot of admin verbs and therefore is actually legit. -GLOBAL_VAR_INIT(Debug, FALSE) // global debug switch -GLOBAL_VAR_INIT(Debug2, FALSE) - -//This was a define, but I changed it to a variable so it can be changed in-game.(kept the all-caps definition because... code...) -Errorage -//Protecting these because the proper way to edit them is with the config/secrets -GLOBAL_VAR_INIT(MAX_EX_DEVESTATION_RANGE, 3) -GLOBAL_PROTECT(MAX_EX_DEVESTATION_RANGE) -GLOBAL_VAR_INIT(MAX_EX_HEAVY_RANGE, 7) -GLOBAL_PROTECT(MAX_EX_HEAVY_RANGE) -GLOBAL_VAR_INIT(MAX_EX_LIGHT_RANGE, 14) -GLOBAL_PROTECT(MAX_EX_LIGHT_RANGE) -GLOBAL_VAR_INIT(MAX_EX_FLASH_RANGE, 14) -GLOBAL_PROTECT(MAX_EX_FLASH_RANGE) -GLOBAL_VAR_INIT(MAX_EX_FLAME_RANGE, 14) -GLOBAL_PROTECT(MAX_EX_FLAME_RANGE) -GLOBAL_VAR_INIT(DYN_EX_SCALE, 0.5) +GLOBAL_REAL(config, /datum/controller/configuration) + +GLOBAL_DATUM(revdata, /datum/getrev) + +GLOBAL_VAR(host) +GLOBAL_VAR(station_name) +GLOBAL_VAR_INIT(game_version, "/tg/ Station 13") +GLOBAL_VAR_INIT(changelog_hash, "") +GLOBAL_VAR_INIT(hub_visibility, FALSE) + +GLOBAL_VAR_INIT(ooc_allowed, TRUE) // used with admin verbs to disable ooc - not a config option apparently +GLOBAL_VAR_INIT(looc_allowed, TRUE) +GLOBAL_VAR_INIT(dooc_allowed, TRUE) +GLOBAL_VAR_INIT(aooc_allowed, FALSE) +GLOBAL_VAR_INIT(enter_allowed, TRUE) +GLOBAL_VAR_INIT(shuttle_frozen, FALSE) +GLOBAL_VAR_INIT(shuttle_left, FALSE) +GLOBAL_VAR_INIT(tinted_weldhelh, TRUE) + + +// Debug is used exactly once (in living.dm) but is commented out in a lot of places. It is not set anywhere and only checked. +// Debug2 is used in conjunction with a lot of admin verbs and therefore is actually legit. +GLOBAL_VAR_INIT(Debug, FALSE) // global debug switch +GLOBAL_VAR_INIT(Debug2, FALSE) + +//This was a define, but I changed it to a variable so it can be changed in-game.(kept the all-caps definition because... code...) -Errorage +//Protecting these because the proper way to edit them is with the config/secrets +GLOBAL_VAR_INIT(MAX_EX_DEVESTATION_RANGE, 3) +GLOBAL_PROTECT(MAX_EX_DEVESTATION_RANGE) +GLOBAL_VAR_INIT(MAX_EX_HEAVY_RANGE, 7) +GLOBAL_PROTECT(MAX_EX_HEAVY_RANGE) +GLOBAL_VAR_INIT(MAX_EX_LIGHT_RANGE, 14) +GLOBAL_PROTECT(MAX_EX_LIGHT_RANGE) +GLOBAL_VAR_INIT(MAX_EX_FLASH_RANGE, 14) +GLOBAL_PROTECT(MAX_EX_FLASH_RANGE) +GLOBAL_VAR_INIT(MAX_EX_FLAME_RANGE, 14) +GLOBAL_PROTECT(MAX_EX_FLAME_RANGE) +GLOBAL_VAR_INIT(DYN_EX_SCALE, 0.5) diff --git a/code/_globalvars/game_modes.dm b/code/_globalvars/game_modes.dm index f6022cdd59..01a34c2ab7 100644 --- a/code/_globalvars/game_modes.dm +++ b/code/_globalvars/game_modes.dm @@ -1,12 +1,12 @@ -GLOBAL_VAR_INIT(master_mode, "traitor") //"extended" -GLOBAL_VAR_INIT(secret_force_mode, "secret") // if this is anything but "secret", the secret rotation will forceably choose this mode -GLOBAL_VAR(common_report) //Contains common part of roundend report -GLOBAL_VAR(survivor_report) //Contains shared survivor report for roundend report (part of personal report) - - -GLOBAL_VAR_INIT(wavesecret, 0) // meteor mode, delays wave progression, terrible name -GLOBAL_DATUM(start_state, /datum/station_state) // Used in round-end report - - -//TODO clear this one up too +GLOBAL_VAR_INIT(master_mode, "traitor") //"extended" +GLOBAL_VAR_INIT(secret_force_mode, "secret") // if this is anything but "secret", the secret rotation will forceably choose this mode +GLOBAL_VAR(common_report) //Contains common part of roundend report +GLOBAL_VAR(survivor_report) //Contains shared survivor report for roundend report (part of personal report) + + +GLOBAL_VAR_INIT(wavesecret, 0) // meteor mode, delays wave progression, terrible name +GLOBAL_DATUM(start_state, /datum/station_state) // Used in round-end report + + +//TODO clear this one up too GLOBAL_DATUM(cult_narsie, /obj/singularity/narsie/large/cult) \ No newline at end of file diff --git a/code/_globalvars/genetics.dm b/code/_globalvars/genetics.dm index a0557e8e1b..7016415d48 100644 --- a/code/_globalvars/genetics.dm +++ b/code/_globalvars/genetics.dm @@ -1,28 +1,28 @@ - ////////////// -GLOBAL_VAR_INIT(NEARSIGHTBLOCK, 0) -GLOBAL_VAR_INIT(EPILEPSYBLOCK, 0) -GLOBAL_VAR_INIT(COUGHBLOCK, 0) -GLOBAL_VAR_INIT(TOURETTESBLOCK, 0) -GLOBAL_VAR_INIT(NERVOUSBLOCK, 0) -GLOBAL_VAR_INIT(BLINDBLOCK, 0) -GLOBAL_VAR_INIT(DEAFBLOCK, 0) -GLOBAL_VAR_INIT(HULKBLOCK, 0) -GLOBAL_VAR_INIT(TELEBLOCK, 0) -GLOBAL_VAR_INIT(FIREBLOCK, 0) -GLOBAL_VAR_INIT(XRAYBLOCK, 0) -GLOBAL_VAR_INIT(CLUMSYBLOCK, 0) -GLOBAL_VAR_INIT(STRANGEBLOCK, 0) -GLOBAL_VAR_INIT(RACEBLOCK, 0) - -GLOBAL_LIST(bad_se_blocks) -GLOBAL_LIST(good_se_blocks) -GLOBAL_LIST(op_se_blocks) - -GLOBAL_VAR(NULLED_SE) -GLOBAL_VAR(NULLED_UI) - -GLOBAL_LIST_EMPTY(global_mutations) // list of hidden mutation things - -GLOBAL_LIST_EMPTY(bad_mutations) -GLOBAL_LIST_EMPTY(good_mutations) + ////////////// +GLOBAL_VAR_INIT(NEARSIGHTBLOCK, 0) +GLOBAL_VAR_INIT(EPILEPSYBLOCK, 0) +GLOBAL_VAR_INIT(COUGHBLOCK, 0) +GLOBAL_VAR_INIT(TOURETTESBLOCK, 0) +GLOBAL_VAR_INIT(NERVOUSBLOCK, 0) +GLOBAL_VAR_INIT(BLINDBLOCK, 0) +GLOBAL_VAR_INIT(DEAFBLOCK, 0) +GLOBAL_VAR_INIT(HULKBLOCK, 0) +GLOBAL_VAR_INIT(TELEBLOCK, 0) +GLOBAL_VAR_INIT(FIREBLOCK, 0) +GLOBAL_VAR_INIT(XRAYBLOCK, 0) +GLOBAL_VAR_INIT(CLUMSYBLOCK, 0) +GLOBAL_VAR_INIT(STRANGEBLOCK, 0) +GLOBAL_VAR_INIT(RACEBLOCK, 0) + +GLOBAL_LIST(bad_se_blocks) +GLOBAL_LIST(good_se_blocks) +GLOBAL_LIST(op_se_blocks) + +GLOBAL_VAR(NULLED_SE) +GLOBAL_VAR(NULLED_UI) + +GLOBAL_LIST_EMPTY(global_mutations) // list of hidden mutation things + +GLOBAL_LIST_EMPTY(bad_mutations) +GLOBAL_LIST_EMPTY(good_mutations) GLOBAL_LIST_EMPTY(not_good_mutations) \ No newline at end of file diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index 2391d39b3a..968995e81d 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -1,223 +1,223 @@ -//Preferences stuff - //Hairstyles -GLOBAL_LIST_EMPTY(hair_styles_list) //stores /datum/sprite_accessory/hair indexed by name -GLOBAL_LIST_EMPTY(hair_styles_male_list) //stores only hair names -GLOBAL_LIST_EMPTY(hair_styles_female_list) //stores only hair names -GLOBAL_LIST_EMPTY(facial_hair_styles_list) //stores /datum/sprite_accessory/facial_hair indexed by name -GLOBAL_LIST_EMPTY(facial_hair_styles_male_list) //stores only hair names -GLOBAL_LIST_EMPTY(facial_hair_styles_female_list) //stores only hair names - //Underwear -GLOBAL_LIST_EMPTY_TYPED(underwear_list, /datum/sprite_accessory/underwear/bottom) //stores bottoms indexed by name -GLOBAL_LIST_EMPTY(underwear_m) //stores only underwear name -GLOBAL_LIST_EMPTY(underwear_f) //stores only underwear name - //Undershirts -GLOBAL_LIST_EMPTY_TYPED(undershirt_list, /datum/sprite_accessory/underwear/top) //stores tops indexed by name -GLOBAL_LIST_EMPTY(undershirt_m) //stores only undershirt name -GLOBAL_LIST_EMPTY(undershirt_f) //stores only undershirt name - //Socks -GLOBAL_LIST_EMPTY_TYPED(socks_list, /datum/sprite_accessory/underwear/socks) //stores socks indexed by name - //Lizard Bits (all datum lists indexed by name) -GLOBAL_LIST_EMPTY(body_markings_list) -GLOBAL_LIST_EMPTY(tails_list_lizard) -GLOBAL_LIST_EMPTY(animated_tails_list_lizard) -GLOBAL_LIST_EMPTY(snouts_list) -GLOBAL_LIST_EMPTY(horns_list) -GLOBAL_LIST_EMPTY(frills_list) -GLOBAL_LIST_EMPTY(spines_list) -GLOBAL_LIST_EMPTY(legs_list) -GLOBAL_LIST_EMPTY(animated_spines_list) - - //Mutant Human bits -GLOBAL_LIST_EMPTY(tails_list_human) -GLOBAL_LIST_EMPTY(animated_tails_list_human) -GLOBAL_LIST_EMPTY(ears_list) -GLOBAL_LIST_EMPTY(wings_list) -GLOBAL_LIST_EMPTY(wings_open_list) -GLOBAL_LIST_EMPTY(deco_wings_list) -GLOBAL_LIST_EMPTY(r_wings_list) -GLOBAL_LIST_EMPTY(insect_wings_list) -GLOBAL_LIST_EMPTY(insect_fluffs_list) -GLOBAL_LIST_EMPTY(insect_markings_list) -GLOBAL_LIST_EMPTY(caps_list) - -GLOBAL_LIST_INIT(ghost_forms_with_directions_list, list("ghost")) //stores the ghost forms that support directional sprites -GLOBAL_LIST_INIT(ghost_forms_with_accessories_list, list("ghost")) //stores the ghost forms that support hair and other such things - -GLOBAL_LIST_INIT(ai_core_display_screens, list( - ":thinking:", - "Alien", - "Angel", - "Angryface", - "AtlantisCZE", - "Banned", - "Bliss", - "Blue", - "Boy", - "Boy-Malf", - "Girl", - "Girl-Malf", - "Database", - "Dorf", - "Firewall", - "Fuzzy", - "Gentoo", - "Glitchman", - "Gondola", - "Goon", - "Hades", - "Heartline", - "Helios", - "Hotdog", - "Hourglass", - "House", - "Inverted", - "Jack", - "Matrix", - "Monochrome", - "Mothman", - "Murica", - "Nanotrasen", - "Not Malf", - "Patriot", - "Pirate", - "President", - "Rainbow", - "Clown", - "Random", - "Ravensdale", - "Red October", - "Red", - "Royal", - "Searif", - "Serithi", - "SilveryFerret", - "Smiley", - "Static", - "Syndicat Meow", - "TechDemon", - "Terminal", - "Text", - "Too Deep", - "Triumvirate", - "Triumvirate-M", - "Wasp", - "Weird", - "Xerxes", - "Yes-Man" - )) - -/proc/resolve_ai_icon(input) - if(!input || !(input in GLOB.ai_core_display_screens)) - return "ai" - else - if(input == "Random") - input = pick(GLOB.ai_core_display_screens - "Random") - return "ai-[lowertext(input)]" - -GLOBAL_LIST_INIT(security_depts_prefs, list(SEC_DEPT_RANDOM, SEC_DEPT_NONE, SEC_DEPT_ENGINEERING, SEC_DEPT_MEDICAL, SEC_DEPT_SCIENCE, SEC_DEPT_SUPPLY)) - - //Backpacks -#define GBACKPACK "Grey Backpack" -#define GSATCHEL "Grey Satchel" -#define GDUFFELBAG "Grey Duffel Bag" -#define LSATCHEL "Leather Satchel" -#define DBACKPACK "Department Backpack" -#define DSATCHEL "Department Satchel" -#define DDUFFELBAG "Department Duffel Bag" -GLOBAL_LIST_INIT(backbaglist, list(DBACKPACK, DSATCHEL, DDUFFELBAG, GBACKPACK, GSATCHEL, GDUFFELBAG, LSATCHEL)) - -//Suit/Skirt -#define PREF_SUIT "Jumpsuit" -#define PREF_SKIRT "Jumpskirt" -GLOBAL_LIST_INIT(jumpsuitlist, list(PREF_SUIT, PREF_SKIRT)) - -//Uplink spawn loc -#define UPLINK_PDA "PDA" -#define UPLINK_RADIO "Radio" -#define UPLINK_PEN "Pen" //like a real spy! -GLOBAL_LIST_INIT(uplink_spawn_loc_list, list(UPLINK_PDA, UPLINK_RADIO, UPLINK_PEN)) - - //Female Uniforms -GLOBAL_LIST_EMPTY(female_clothing_icons) - - //radical shit -GLOBAL_LIST_INIT(hit_appends, list("-OOF", "-ACK", "-UGH", "-HRNK", "-HURGH", "-GLORF")) - -GLOBAL_LIST_INIT(scarySounds, list('sound/weapons/thudswoosh.ogg','sound/weapons/taser.ogg','sound/weapons/armbomb.ogg','sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg','sound/voice/hiss5.ogg','sound/voice/hiss6.ogg','sound/effects/glassbr1.ogg','sound/effects/glassbr2.ogg','sound/effects/glassbr3.ogg','sound/items/welder.ogg','sound/items/welder2.ogg','sound/machines/airlock.ogg','sound/effects/clownstep1.ogg','sound/effects/clownstep2.ogg')) - - -// Reference list for disposal sort junctions. Set the sortType variable on disposal sort junctions to -// the index of the sort department that you want. For example, sortType set to 2 will reroute all packages -// tagged for the Cargo Bay. - -/* List of sortType codes for mapping reference -0 Waste -1 Disposals - All unwrapped items and untagged parcels get picked up by a junction with this sortType. Usually leads to the recycler. -2 Cargo Bay -3 QM Office -4 Engineering -5 CE Office -6 Atmospherics -7 Security -8 HoS Office -9 Medbay -10 CMO Office -11 Chemistry -12 Research -13 RD Office -14 Robotics -15 HoP Office -16 Library -17 Chapel -18 Theatre -19 Bar -20 Kitchen -21 Hydroponics -22 Janitor -23 Genetics -24 Circuitry -25 Toxins -26 Dormitories -27 Virology -28 Xenobiology -29 Law Office -30 Detective's Office -*/ - -//The whole system for the sorttype var is determined based on the order of this list, -//disposals must always be 1, since anything that's untagged will automatically go to disposals, or sorttype = 1 --Superxpdude - -//If you don't want to fuck up disposals, add to this list, and don't change the order. -//If you insist on changing the order, you'll have to change every sort junction to reflect the new order. --Pete - -GLOBAL_LIST_INIT(TAGGERLOCATIONS, list("Disposals", - "Cargo Bay", "QM Office", "Engineering", "CE Office", - "Atmospherics", "Security", "HoS Office", "Medbay", - "CMO Office", "Chemistry", "Research", "RD Office", - "Robotics", "HoP Office", "Library", "Chapel", "Theatre", - "Bar", "Kitchen", "Hydroponics", "Janitor Closet","Genetics", - "Circuitry", "Toxins", "Dormitories", "Virology", - "Xenobiology", "Law Office","Detective's Office")) - -GLOBAL_LIST_INIT(station_prefixes, world.file2list("strings/station_prefixes.txt") + "") - -GLOBAL_LIST_INIT(station_names, world.file2list("strings/station_names.txt" + "")) - -GLOBAL_LIST_INIT(station_suffixes, world.file2list("strings/station_suffixes.txt")) - -GLOBAL_LIST_INIT(greek_letters, world.file2list("strings/greek_letters.txt")) - -GLOBAL_LIST_INIT(phonetic_alphabet, world.file2list("strings/phonetic_alphabet.txt")) - -GLOBAL_LIST_INIT(numbers_as_words, world.file2list("strings/numbers_as_words.txt")) - -/proc/generate_number_strings() - var/list/L[198] - for(var/i in 1 to 99) - L += "[i]" - L += "\Roman[i]" - return L - -GLOBAL_LIST_INIT(station_numerals, greek_letters + phonetic_alphabet + numbers_as_words + generate_number_strings()) - -GLOBAL_LIST_INIT(admiral_messages, list("Do you know how expensive these stations are?","Stop wasting my time.","I was sleeping, thanks a lot.","Stand and fight you cowards!","You knew the risks coming in.","Stop being paranoid.","Whatever's broken just build a new one.","No.", "null","Error: No comment given.", "It's a good day to die!")) +//Preferences stuff + //Hairstyles +GLOBAL_LIST_EMPTY(hair_styles_list) //stores /datum/sprite_accessory/hair indexed by name +GLOBAL_LIST_EMPTY(hair_styles_male_list) //stores only hair names +GLOBAL_LIST_EMPTY(hair_styles_female_list) //stores only hair names +GLOBAL_LIST_EMPTY(facial_hair_styles_list) //stores /datum/sprite_accessory/facial_hair indexed by name +GLOBAL_LIST_EMPTY(facial_hair_styles_male_list) //stores only hair names +GLOBAL_LIST_EMPTY(facial_hair_styles_female_list) //stores only hair names + //Underwear +GLOBAL_LIST_EMPTY_TYPED(underwear_list, /datum/sprite_accessory/underwear/bottom) //stores bottoms indexed by name +GLOBAL_LIST_EMPTY(underwear_m) //stores only underwear name +GLOBAL_LIST_EMPTY(underwear_f) //stores only underwear name + //Undershirts +GLOBAL_LIST_EMPTY_TYPED(undershirt_list, /datum/sprite_accessory/underwear/top) //stores tops indexed by name +GLOBAL_LIST_EMPTY(undershirt_m) //stores only undershirt name +GLOBAL_LIST_EMPTY(undershirt_f) //stores only undershirt name + //Socks +GLOBAL_LIST_EMPTY_TYPED(socks_list, /datum/sprite_accessory/underwear/socks) //stores socks indexed by name + //Lizard Bits (all datum lists indexed by name) +GLOBAL_LIST_EMPTY(body_markings_list) +GLOBAL_LIST_EMPTY(tails_list_lizard) +GLOBAL_LIST_EMPTY(animated_tails_list_lizard) +GLOBAL_LIST_EMPTY(snouts_list) +GLOBAL_LIST_EMPTY(horns_list) +GLOBAL_LIST_EMPTY(frills_list) +GLOBAL_LIST_EMPTY(spines_list) +GLOBAL_LIST_EMPTY(legs_list) +GLOBAL_LIST_EMPTY(animated_spines_list) + + //Mutant Human bits +GLOBAL_LIST_EMPTY(tails_list_human) +GLOBAL_LIST_EMPTY(animated_tails_list_human) +GLOBAL_LIST_EMPTY(ears_list) +GLOBAL_LIST_EMPTY(wings_list) +GLOBAL_LIST_EMPTY(wings_open_list) +GLOBAL_LIST_EMPTY(deco_wings_list) +GLOBAL_LIST_EMPTY(r_wings_list) +GLOBAL_LIST_EMPTY(insect_wings_list) +GLOBAL_LIST_EMPTY(insect_fluffs_list) +GLOBAL_LIST_EMPTY(insect_markings_list) +GLOBAL_LIST_EMPTY(caps_list) + +GLOBAL_LIST_INIT(ghost_forms_with_directions_list, list("ghost")) //stores the ghost forms that support directional sprites +GLOBAL_LIST_INIT(ghost_forms_with_accessories_list, list("ghost")) //stores the ghost forms that support hair and other such things + +GLOBAL_LIST_INIT(ai_core_display_screens, list( + ":thinking:", + "Alien", + "Angel", + "Angryface", + "AtlantisCZE", + "Banned", + "Bliss", + "Blue", + "Boy", + "Boy-Malf", + "Girl", + "Girl-Malf", + "Database", + "Dorf", + "Firewall", + "Fuzzy", + "Gentoo", + "Glitchman", + "Gondola", + "Goon", + "Hades", + "Heartline", + "Helios", + "Hotdog", + "Hourglass", + "House", + "Inverted", + "Jack", + "Matrix", + "Monochrome", + "Mothman", + "Murica", + "Nanotrasen", + "Not Malf", + "Patriot", + "Pirate", + "President", + "Rainbow", + "Clown", + "Random", + "Ravensdale", + "Red October", + "Red", + "Royal", + "Searif", + "Serithi", + "SilveryFerret", + "Smiley", + "Static", + "Syndicat Meow", + "TechDemon", + "Terminal", + "Text", + "Too Deep", + "Triumvirate", + "Triumvirate-M", + "Wasp", + "Weird", + "Xerxes", + "Yes-Man" + )) + +/proc/resolve_ai_icon(input) + if(!input || !(input in GLOB.ai_core_display_screens)) + return "ai" + else + if(input == "Random") + input = pick(GLOB.ai_core_display_screens - "Random") + return "ai-[lowertext(input)]" + +GLOBAL_LIST_INIT(security_depts_prefs, list(SEC_DEPT_RANDOM, SEC_DEPT_NONE, SEC_DEPT_ENGINEERING, SEC_DEPT_MEDICAL, SEC_DEPT_SCIENCE, SEC_DEPT_SUPPLY)) + + //Backpacks +#define GBACKPACK "Grey Backpack" +#define GSATCHEL "Grey Satchel" +#define GDUFFELBAG "Grey Duffel Bag" +#define LSATCHEL "Leather Satchel" +#define DBACKPACK "Department Backpack" +#define DSATCHEL "Department Satchel" +#define DDUFFELBAG "Department Duffel Bag" +GLOBAL_LIST_INIT(backbaglist, list(DBACKPACK, DSATCHEL, DDUFFELBAG, GBACKPACK, GSATCHEL, GDUFFELBAG, LSATCHEL)) + +//Suit/Skirt +#define PREF_SUIT "Jumpsuit" +#define PREF_SKIRT "Jumpskirt" +GLOBAL_LIST_INIT(jumpsuitlist, list(PREF_SUIT, PREF_SKIRT)) + +//Uplink spawn loc +#define UPLINK_PDA "PDA" +#define UPLINK_RADIO "Radio" +#define UPLINK_PEN "Pen" //like a real spy! +GLOBAL_LIST_INIT(uplink_spawn_loc_list, list(UPLINK_PDA, UPLINK_RADIO, UPLINK_PEN)) + + //Female Uniforms +GLOBAL_LIST_EMPTY(female_clothing_icons) + + //radical shit +GLOBAL_LIST_INIT(hit_appends, list("-OOF", "-ACK", "-UGH", "-HRNK", "-HURGH", "-GLORF")) + +GLOBAL_LIST_INIT(scarySounds, list('sound/weapons/thudswoosh.ogg','sound/weapons/taser.ogg','sound/weapons/armbomb.ogg','sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg','sound/voice/hiss5.ogg','sound/voice/hiss6.ogg','sound/effects/glassbr1.ogg','sound/effects/glassbr2.ogg','sound/effects/glassbr3.ogg','sound/items/welder.ogg','sound/items/welder2.ogg','sound/machines/airlock.ogg','sound/effects/clownstep1.ogg','sound/effects/clownstep2.ogg')) + + +// Reference list for disposal sort junctions. Set the sortType variable on disposal sort junctions to +// the index of the sort department that you want. For example, sortType set to 2 will reroute all packages +// tagged for the Cargo Bay. + +/* List of sortType codes for mapping reference +0 Waste +1 Disposals - All unwrapped items and untagged parcels get picked up by a junction with this sortType. Usually leads to the recycler. +2 Cargo Bay +3 QM Office +4 Engineering +5 CE Office +6 Atmospherics +7 Security +8 HoS Office +9 Medbay +10 CMO Office +11 Chemistry +12 Research +13 RD Office +14 Robotics +15 HoP Office +16 Library +17 Chapel +18 Theatre +19 Bar +20 Kitchen +21 Hydroponics +22 Janitor +23 Genetics +24 Circuitry +25 Toxins +26 Dormitories +27 Virology +28 Xenobiology +29 Law Office +30 Detective's Office +*/ + +//The whole system for the sorttype var is determined based on the order of this list, +//disposals must always be 1, since anything that's untagged will automatically go to disposals, or sorttype = 1 --Superxpdude + +//If you don't want to fuck up disposals, add to this list, and don't change the order. +//If you insist on changing the order, you'll have to change every sort junction to reflect the new order. --Pete + +GLOBAL_LIST_INIT(TAGGERLOCATIONS, list("Disposals", + "Cargo Bay", "QM Office", "Engineering", "CE Office", + "Atmospherics", "Security", "HoS Office", "Medbay", + "CMO Office", "Chemistry", "Research", "RD Office", + "Robotics", "HoP Office", "Library", "Chapel", "Theatre", + "Bar", "Kitchen", "Hydroponics", "Janitor Closet","Genetics", + "Circuitry", "Toxins", "Dormitories", "Virology", + "Xenobiology", "Law Office","Detective's Office")) + +GLOBAL_LIST_INIT(station_prefixes, world.file2list("strings/station_prefixes.txt") + "") + +GLOBAL_LIST_INIT(station_names, world.file2list("strings/station_names.txt" + "")) + +GLOBAL_LIST_INIT(station_suffixes, world.file2list("strings/station_suffixes.txt")) + +GLOBAL_LIST_INIT(greek_letters, world.file2list("strings/greek_letters.txt")) + +GLOBAL_LIST_INIT(phonetic_alphabet, world.file2list("strings/phonetic_alphabet.txt")) + +GLOBAL_LIST_INIT(numbers_as_words, world.file2list("strings/numbers_as_words.txt")) + +/proc/generate_number_strings() + var/list/L[198] + for(var/i in 1 to 99) + L += "[i]" + L += "\Roman[i]" + return L + +GLOBAL_LIST_INIT(station_numerals, greek_letters + phonetic_alphabet + numbers_as_words + generate_number_strings()) + +GLOBAL_LIST_INIT(admiral_messages, list("Do you know how expensive these stations are?","Stop wasting my time.","I was sleeping, thanks a lot.","Stand and fight you cowards!","You knew the risks coming in.","Stop being paranoid.","Whatever's broken just build a new one.","No.", "null","Error: No comment given.", "It's a good day to die!")) diff --git a/code/_globalvars/lists/mapping.dm b/code/_globalvars/lists/mapping.dm index 7340581d25..fb8863ebe7 100644 --- a/code/_globalvars/lists/mapping.dm +++ b/code/_globalvars/lists/mapping.dm @@ -1,52 +1,52 @@ -GLOBAL_LIST_INIT(cardinals, list(NORTH, SOUTH, EAST, WEST)) -GLOBAL_LIST_INIT(cardinals_multiz, list(NORTH, SOUTH, EAST, WEST, UP, DOWN)) -GLOBAL_LIST_INIT(diagonals, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)) -GLOBAL_LIST_INIT(corners_multiz, list(UP|NORTHEAST, UP|NORTHWEST, UP|SOUTHEAST, UP|SOUTHWEST, DOWN|NORTHEAST, DOWN|NORTHWEST, DOWN|SOUTHEAST, DOWN|SOUTHWEST)) -GLOBAL_LIST_INIT(diagonals_multiz, list( - NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST, - UP|NORTH, UP|SOUTH, UP|EAST, UP|WEST, UP|NORTHEAST, UP|NORTHWEST, UP|SOUTHEAST, UP|SOUTHWEST, - DOWN|NORTH, DOWN|SOUTH, DOWN|EAST, DOWN|WEST, DOWN|NORTHEAST, DOWN|NORTHWEST, DOWN|SOUTHEAST, DOWN|SOUTHWEST)) -GLOBAL_LIST_INIT(alldirs_multiz, list( - NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST, - UP, UP|NORTH, UP|SOUTH, UP|EAST, UP|WEST, UP|NORTHEAST, UP|NORTHWEST, UP|SOUTHEAST, UP|SOUTHWEST, - DOWN, DOWN|NORTH, DOWN|SOUTH, DOWN|EAST, DOWN|WEST, DOWN|NORTHEAST, DOWN|NORTHWEST, DOWN|SOUTHEAST, DOWN|SOUTHWEST)) -GLOBAL_LIST_INIT(alldirs, list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)) - -GLOBAL_LIST_EMPTY(landmarks_list) //list of all landmarks created -GLOBAL_LIST_EMPTY(start_landmarks_list) //list of all spawn points created -GLOBAL_LIST_EMPTY(department_security_spawns) //list of all department security spawns -GLOBAL_LIST_EMPTY(generic_event_spawns) //list of all spawns for events -GLOBAL_LIST_EMPTY(jobspawn_overrides) //These will take precedence over normal spawnpoints if created. - -GLOBAL_LIST_EMPTY(wizardstart) -GLOBAL_LIST_EMPTY(nukeop_start) -GLOBAL_LIST_EMPTY(nukeop_leader_start) -GLOBAL_LIST_EMPTY(newplayer_start) -GLOBAL_LIST_EMPTY(prisonwarp) //prisoners go to these -GLOBAL_LIST_EMPTY(holdingfacility) //captured people go here -GLOBAL_LIST_EMPTY(xeno_spawn)//Aliens spawn at these. -GLOBAL_LIST_EMPTY(tdome1) -GLOBAL_LIST_EMPTY(tdome2) -GLOBAL_LIST_EMPTY(tdomeobserve) -GLOBAL_LIST_EMPTY(tdomeadmin) -GLOBAL_LIST_EMPTY(prisonwarped) //list of players already warped -GLOBAL_LIST_EMPTY(blobstart) -GLOBAL_LIST_EMPTY(secequipment) -GLOBAL_LIST_EMPTY(deathsquadspawn) -GLOBAL_LIST_EMPTY(emergencyresponseteamspawn) -GLOBAL_LIST_EMPTY(servant_spawns) //Servants of Ratvar spawn here -GLOBAL_LIST_EMPTY(city_of_cogs_spawns) //Anyone entering the City of Cogs spawns here -GLOBAL_LIST_EMPTY(ruin_landmarks) - - //away missions -GLOBAL_LIST_EMPTY(awaydestinations) //a list of landmarks that the warpgate can take you to -GLOBAL_LIST_EMPTY(vr_spawnpoints) - - //used by jump-to-area etc. Updated by area/updateName() -GLOBAL_LIST_EMPTY(sortedAreas) -/// An association from typepath to area instance. Only includes areas with `unique` set. -GLOBAL_LIST_EMPTY_TYPED(areas_by_type, /area) - -GLOBAL_LIST_EMPTY(all_abstract_markers) - -GLOBAL_LIST_EMPTY(stationroom_landmarks) //List of all spawns for stationrooms +GLOBAL_LIST_INIT(cardinals, list(NORTH, SOUTH, EAST, WEST)) +GLOBAL_LIST_INIT(cardinals_multiz, list(NORTH, SOUTH, EAST, WEST, UP, DOWN)) +GLOBAL_LIST_INIT(diagonals, list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)) +GLOBAL_LIST_INIT(corners_multiz, list(UP|NORTHEAST, UP|NORTHWEST, UP|SOUTHEAST, UP|SOUTHWEST, DOWN|NORTHEAST, DOWN|NORTHWEST, DOWN|SOUTHEAST, DOWN|SOUTHWEST)) +GLOBAL_LIST_INIT(diagonals_multiz, list( + NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST, + UP|NORTH, UP|SOUTH, UP|EAST, UP|WEST, UP|NORTHEAST, UP|NORTHWEST, UP|SOUTHEAST, UP|SOUTHWEST, + DOWN|NORTH, DOWN|SOUTH, DOWN|EAST, DOWN|WEST, DOWN|NORTHEAST, DOWN|NORTHWEST, DOWN|SOUTHEAST, DOWN|SOUTHWEST)) +GLOBAL_LIST_INIT(alldirs_multiz, list( + NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST, + UP, UP|NORTH, UP|SOUTH, UP|EAST, UP|WEST, UP|NORTHEAST, UP|NORTHWEST, UP|SOUTHEAST, UP|SOUTHWEST, + DOWN, DOWN|NORTH, DOWN|SOUTH, DOWN|EAST, DOWN|WEST, DOWN|NORTHEAST, DOWN|NORTHWEST, DOWN|SOUTHEAST, DOWN|SOUTHWEST)) +GLOBAL_LIST_INIT(alldirs, list(NORTH, SOUTH, EAST, WEST, NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST)) + +GLOBAL_LIST_EMPTY(landmarks_list) //list of all landmarks created +GLOBAL_LIST_EMPTY(start_landmarks_list) //list of all spawn points created +GLOBAL_LIST_EMPTY(department_security_spawns) //list of all department security spawns +GLOBAL_LIST_EMPTY(generic_event_spawns) //list of all spawns for events +GLOBAL_LIST_EMPTY(jobspawn_overrides) //These will take precedence over normal spawnpoints if created. + +GLOBAL_LIST_EMPTY(wizardstart) +GLOBAL_LIST_EMPTY(nukeop_start) +GLOBAL_LIST_EMPTY(nukeop_leader_start) +GLOBAL_LIST_EMPTY(newplayer_start) +GLOBAL_LIST_EMPTY(prisonwarp) //prisoners go to these +GLOBAL_LIST_EMPTY(holdingfacility) //captured people go here +GLOBAL_LIST_EMPTY(xeno_spawn)//Aliens spawn at these. +GLOBAL_LIST_EMPTY(tdome1) +GLOBAL_LIST_EMPTY(tdome2) +GLOBAL_LIST_EMPTY(tdomeobserve) +GLOBAL_LIST_EMPTY(tdomeadmin) +GLOBAL_LIST_EMPTY(prisonwarped) //list of players already warped +GLOBAL_LIST_EMPTY(blobstart) +GLOBAL_LIST_EMPTY(secequipment) +GLOBAL_LIST_EMPTY(deathsquadspawn) +GLOBAL_LIST_EMPTY(emergencyresponseteamspawn) +GLOBAL_LIST_EMPTY(servant_spawns) //Servants of Ratvar spawn here +GLOBAL_LIST_EMPTY(city_of_cogs_spawns) //Anyone entering the City of Cogs spawns here +GLOBAL_LIST_EMPTY(ruin_landmarks) + + //away missions +GLOBAL_LIST_EMPTY(awaydestinations) //a list of landmarks that the warpgate can take you to +GLOBAL_LIST_EMPTY(vr_spawnpoints) + + //used by jump-to-area etc. Updated by area/updateName() +GLOBAL_LIST_EMPTY(sortedAreas) +/// An association from typepath to area instance. Only includes areas with `unique` set. +GLOBAL_LIST_EMPTY_TYPED(areas_by_type, /area) + +GLOBAL_LIST_EMPTY(all_abstract_markers) + +GLOBAL_LIST_EMPTY(stationroom_landmarks) //List of all spawns for stationrooms diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index 3577402b36..ae385339be 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -1,103 +1,103 @@ -GLOBAL_LIST_EMPTY(clients) //all clients -GLOBAL_LIST_EMPTY(admins) //all clients whom are admins -GLOBAL_PROTECT(admins) -GLOBAL_LIST_EMPTY(mentors) //all clients whom are mentors -GLOBAL_PROTECT(mentors) -GLOBAL_LIST_EMPTY(deadmins) //all ckeys who have used the de-admin verb. - -GLOBAL_LIST_EMPTY(directory) //all ckeys with associated client -GLOBAL_LIST_EMPTY(stealthminID) //reference list with IDs that store ckeys, for stealthmins - -GLOBAL_LIST_EMPTY(bunker_passthrough) - -//Since it didn't really belong in any other category, I'm putting this here -//This is for procs to replace all the goddamn 'in world's that are chilling around the code - -GLOBAL_LIST_EMPTY(player_list) //all mobs **with clients attached**. -GLOBAL_LIST_EMPTY(mob_list) //all mobs, including clientless -GLOBAL_LIST_EMPTY(mob_directory) //mob_id -> mob -GLOBAL_LIST_EMPTY(alive_mob_list) //all alive mobs, including clientless. Excludes /mob/dead/new_player -GLOBAL_LIST_EMPTY(drones_list) -GLOBAL_LIST_EMPTY(dead_mob_list) //all dead mobs, including clientless. Excludes /mob/dead/new_player -GLOBAL_LIST_EMPTY(joined_player_list) //all clients that have joined the game at round-start or as a latejoin. -GLOBAL_LIST_EMPTY(silicon_mobs) //all silicon mobs -GLOBAL_LIST_EMPTY(mob_living_list) //all instances of /mob/living and subtypes -GLOBAL_LIST_EMPTY(carbon_list) //all instances of /mob/living/carbon and subtypes, notably does not contain brains or simple animals -GLOBAL_LIST_EMPTY(ai_list) -GLOBAL_LIST_EMPTY(pai_list) -GLOBAL_LIST_EMPTY(available_ai_shells) -GLOBAL_LIST_INIT(simple_animals, list(list(),list(),list(),list())) // One for each AI_* status define -GLOBAL_LIST_EMPTY(spidermobs) //all sentient spider mobs -GLOBAL_LIST_EMPTY(bots_list) -GLOBAL_LIST_EMPTY(living_cameras) -GLOBAL_LIST_EMPTY(aiEyes) - -GLOBAL_LIST_EMPTY(language_datum_instances) -GLOBAL_LIST_EMPTY(all_languages) - -GLOBAL_LIST_EMPTY(sentient_disease_instances) - -GLOBAL_LIST_EMPTY(latejoin_ai_cores) - -GLOBAL_LIST_EMPTY(mob_config_movespeed_type_lookup) - -GLOBAL_LIST_EMPTY(latejoiners) //CIT CHANGE - All latejoining people, for traitor-target purposes. - -/proc/update_config_movespeed_type_lookup(update_mobs = TRUE) - var/list/mob_types = list() - var/list/entry_value = CONFIG_GET(keyed_list/multiplicative_movespeed) - for(var/path in entry_value) - var/value = entry_value[path] - if(!value) - continue - for(var/subpath in typesof(path)) - mob_types[subpath] = value - GLOB.mob_config_movespeed_type_lookup = mob_types - if(update_mobs) - update_mob_config_movespeeds() - -/proc/update_mob_config_movespeeds() - for(var/i in GLOB.mob_list) - var/mob/M = i - M.update_config_movespeed() - - //blood types -GLOBAL_LIST_INIT(regular_bloods,list( - "O-", - "O+", - "A-", - "A+", - "B-", - "B+", - "AB-", - "AB+" - )) - -GLOBAL_LIST_INIT(all_types_bloods,list( - "O-", - "O+", - "A-", - "A+", - "B-", - "B+", - "AB-", - "AB+", - "SY", - "X*", - "HF", - "L", - "U", - "GEL", - "BUG" - )) - -GLOBAL_LIST_INIT(blood_types, list( - "blood", - "jellyblood" - )) - -GLOBAL_LIST_INIT(blood_id_types, list( - "blood" = /datum/reagent/blood, - "jellyblood" = /datum/reagent/blood/jellyblood - )) - +GLOBAL_LIST_EMPTY(clients) //all clients +GLOBAL_LIST_EMPTY(admins) //all clients whom are admins +GLOBAL_PROTECT(admins) +GLOBAL_LIST_EMPTY(mentors) //all clients whom are mentors +GLOBAL_PROTECT(mentors) +GLOBAL_LIST_EMPTY(deadmins) //all ckeys who have used the de-admin verb. + +GLOBAL_LIST_EMPTY(directory) //all ckeys with associated client +GLOBAL_LIST_EMPTY(stealthminID) //reference list with IDs that store ckeys, for stealthmins + +GLOBAL_LIST_EMPTY(bunker_passthrough) + +//Since it didn't really belong in any other category, I'm putting this here +//This is for procs to replace all the goddamn 'in world's that are chilling around the code + +GLOBAL_LIST_EMPTY(player_list) //all mobs **with clients attached**. +GLOBAL_LIST_EMPTY(mob_list) //all mobs, including clientless +GLOBAL_LIST_EMPTY(mob_directory) //mob_id -> mob +GLOBAL_LIST_EMPTY(alive_mob_list) //all alive mobs, including clientless. Excludes /mob/dead/new_player +GLOBAL_LIST_EMPTY(drones_list) +GLOBAL_LIST_EMPTY(dead_mob_list) //all dead mobs, including clientless. Excludes /mob/dead/new_player +GLOBAL_LIST_EMPTY(joined_player_list) //all clients that have joined the game at round-start or as a latejoin. +GLOBAL_LIST_EMPTY(silicon_mobs) //all silicon mobs +GLOBAL_LIST_EMPTY(mob_living_list) //all instances of /mob/living and subtypes +GLOBAL_LIST_EMPTY(carbon_list) //all instances of /mob/living/carbon and subtypes, notably does not contain brains or simple animals +GLOBAL_LIST_EMPTY(ai_list) +GLOBAL_LIST_EMPTY(pai_list) +GLOBAL_LIST_EMPTY(available_ai_shells) +GLOBAL_LIST_INIT(simple_animals, list(list(),list(),list(),list())) // One for each AI_* status define +GLOBAL_LIST_EMPTY(spidermobs) //all sentient spider mobs +GLOBAL_LIST_EMPTY(bots_list) +GLOBAL_LIST_EMPTY(living_cameras) +GLOBAL_LIST_EMPTY(aiEyes) + +GLOBAL_LIST_EMPTY(language_datum_instances) +GLOBAL_LIST_EMPTY(all_languages) + +GLOBAL_LIST_EMPTY(sentient_disease_instances) + +GLOBAL_LIST_EMPTY(latejoin_ai_cores) + +GLOBAL_LIST_EMPTY(mob_config_movespeed_type_lookup) + +GLOBAL_LIST_EMPTY(latejoiners) //CIT CHANGE - All latejoining people, for traitor-target purposes. + +/proc/update_config_movespeed_type_lookup(update_mobs = TRUE) + var/list/mob_types = list() + var/list/entry_value = CONFIG_GET(keyed_list/multiplicative_movespeed) + for(var/path in entry_value) + var/value = entry_value[path] + if(!value) + continue + for(var/subpath in typesof(path)) + mob_types[subpath] = value + GLOB.mob_config_movespeed_type_lookup = mob_types + if(update_mobs) + update_mob_config_movespeeds() + +/proc/update_mob_config_movespeeds() + for(var/i in GLOB.mob_list) + var/mob/M = i + M.update_config_movespeed() + + //blood types +GLOBAL_LIST_INIT(regular_bloods,list( + "O-", + "O+", + "A-", + "A+", + "B-", + "B+", + "AB-", + "AB+" + )) + +GLOBAL_LIST_INIT(all_types_bloods,list( + "O-", + "O+", + "A-", + "A+", + "B-", + "B+", + "AB-", + "AB+", + "SY", + "X*", + "HF", + "L", + "U", + "GEL", + "BUG" + )) + +GLOBAL_LIST_INIT(blood_types, list( + "blood", + "jellyblood" + )) + +GLOBAL_LIST_INIT(blood_id_types, list( + "blood" = /datum/reagent/blood, + "jellyblood" = /datum/reagent/blood/jellyblood + )) + diff --git a/code/_globalvars/lists/names.dm b/code/_globalvars/lists/names.dm index 63ab782dd4..7ae197a5d1 100644 --- a/code/_globalvars/lists/names.dm +++ b/code/_globalvars/lists/names.dm @@ -1,50 +1,50 @@ -GLOBAL_LIST_INIT(ai_names, world.file2list("strings/names/ai.txt")) -GLOBAL_LIST_INIT(wizard_first, world.file2list("strings/names/wizardfirst.txt")) -GLOBAL_LIST_INIT(wizard_second, world.file2list("strings/names/wizardsecond.txt")) -GLOBAL_LIST_INIT(ninja_titles, world.file2list("strings/names/ninjatitle.txt")) -GLOBAL_LIST_INIT(ninja_names, world.file2list("strings/names/ninjaname.txt")) -GLOBAL_LIST_INIT(commando_names, world.file2list("strings/names/death_commando.txt")) -GLOBAL_LIST_INIT(first_names_male, world.file2list("strings/names/first_male.txt")) -GLOBAL_LIST_INIT(first_names_female, world.file2list("strings/names/first_female.txt")) -GLOBAL_LIST_INIT(last_names, world.file2list("strings/names/last.txt")) -GLOBAL_LIST_INIT(lizard_names_male, world.file2list("strings/names/lizard_male.txt")) -GLOBAL_LIST_INIT(lizard_names_female, world.file2list("strings/names/lizard_female.txt")) -GLOBAL_LIST_INIT(clown_names, world.file2list("strings/names/clown.txt")) -GLOBAL_LIST_INIT(mime_names, world.file2list("strings/names/mime.txt")) -GLOBAL_LIST_INIT(carp_names, world.file2list("strings/names/carp.txt")) -GLOBAL_LIST_INIT(golem_names, world.file2list("strings/names/golem.txt")) -GLOBAL_LIST_INIT(moth_first, world.file2list("strings/names/moth_first.txt")) -GLOBAL_LIST_INIT(moth_last, world.file2list("strings/names/moth_last.txt")) -GLOBAL_LIST_INIT(plasmaman_names, world.file2list("strings/names/plasmaman.txt")) -GLOBAL_LIST_INIT(posibrain_names, world.file2list("strings/names/posibrain.txt")) -GLOBAL_LIST_INIT(nightmare_names, world.file2list("strings/names/nightmare.txt")) -GLOBAL_LIST_INIT(megacarp_first_names, world.file2list("strings/names/megacarp1.txt")) -GLOBAL_LIST_INIT(megacarp_last_names, world.file2list("strings/names/megacarp2.txt")) - -GLOBAL_LIST_INIT(verbs, world.file2list("strings/names/verbs.txt")) -GLOBAL_LIST_INIT(ing_verbs, world.file2list("strings/names/ing_verbs.txt")) -GLOBAL_LIST_INIT(adverbs, world.file2list("strings/names/adverbs.txt")) -GLOBAL_LIST_INIT(adjectives, world.file2list("strings/names/adjectives.txt")) -GLOBAL_LIST_INIT(dream_strings, world.file2list("strings/dreamstrings.txt")) -//loaded on startup because of " -//would include in rsc if ' was used - -/* -List of configurable names in preferences and their metadata -"id" = list( - "pref_name" = "name", //pref label - "qdesc" = "name", //popup question text - "allow_numbers" = FALSE, // numbers allowed in the name - "group" = "whatever", // group (these will be grouped together on pref ui ,order still follows the list so they need to be concurrent to be grouped) - "allow_null" = FALSE // if empty name is entered it's replaced with default value - ), -*/ -GLOBAL_LIST_INIT(preferences_custom_names, list( - "human" = list("pref_name" = "Backup Human", "qdesc" = "backup human name, used in the event you are assigned a command role as another species", "allow_numbers" = FALSE , "group" = "backup_human", "allow_null" = FALSE), - "clown" = list("pref_name" = "Clown" , "qdesc" = "clown name", "allow_numbers" = FALSE , "group" = "fun", "allow_null" = FALSE), - "mime" = list("pref_name" = "Mime", "qdesc" = "mime name" , "allow_numbers" = FALSE , "group" = "fun", "allow_null" = FALSE), - "cyborg" = list("pref_name" = "Cyborg", "qdesc" = "cyborg name (Leave empty to use default naming scheme)", "allow_numbers" = TRUE , "group" = "silicons", "allow_null" = TRUE), - "ai" = list("pref_name" = "AI", "qdesc" = "ai name", "allow_numbers" = TRUE , "group" = "silicons", "allow_null" = FALSE), - "religion" = list("pref_name" = "Chaplain religion", "qdesc" = "religion" , "allow_numbers" = TRUE , "group" = "chaplain", "allow_null" = FALSE), - "deity" = list("pref_name" = "Chaplain deity", "qdesc" = "deity", "allow_numbers" = TRUE , "group" = "chaplain", "allow_null" = FALSE) - )) +GLOBAL_LIST_INIT(ai_names, world.file2list("strings/names/ai.txt")) +GLOBAL_LIST_INIT(wizard_first, world.file2list("strings/names/wizardfirst.txt")) +GLOBAL_LIST_INIT(wizard_second, world.file2list("strings/names/wizardsecond.txt")) +GLOBAL_LIST_INIT(ninja_titles, world.file2list("strings/names/ninjatitle.txt")) +GLOBAL_LIST_INIT(ninja_names, world.file2list("strings/names/ninjaname.txt")) +GLOBAL_LIST_INIT(commando_names, world.file2list("strings/names/death_commando.txt")) +GLOBAL_LIST_INIT(first_names_male, world.file2list("strings/names/first_male.txt")) +GLOBAL_LIST_INIT(first_names_female, world.file2list("strings/names/first_female.txt")) +GLOBAL_LIST_INIT(last_names, world.file2list("strings/names/last.txt")) +GLOBAL_LIST_INIT(lizard_names_male, world.file2list("strings/names/lizard_male.txt")) +GLOBAL_LIST_INIT(lizard_names_female, world.file2list("strings/names/lizard_female.txt")) +GLOBAL_LIST_INIT(clown_names, world.file2list("strings/names/clown.txt")) +GLOBAL_LIST_INIT(mime_names, world.file2list("strings/names/mime.txt")) +GLOBAL_LIST_INIT(carp_names, world.file2list("strings/names/carp.txt")) +GLOBAL_LIST_INIT(golem_names, world.file2list("strings/names/golem.txt")) +GLOBAL_LIST_INIT(moth_first, world.file2list("strings/names/moth_first.txt")) +GLOBAL_LIST_INIT(moth_last, world.file2list("strings/names/moth_last.txt")) +GLOBAL_LIST_INIT(plasmaman_names, world.file2list("strings/names/plasmaman.txt")) +GLOBAL_LIST_INIT(posibrain_names, world.file2list("strings/names/posibrain.txt")) +GLOBAL_LIST_INIT(nightmare_names, world.file2list("strings/names/nightmare.txt")) +GLOBAL_LIST_INIT(megacarp_first_names, world.file2list("strings/names/megacarp1.txt")) +GLOBAL_LIST_INIT(megacarp_last_names, world.file2list("strings/names/megacarp2.txt")) + +GLOBAL_LIST_INIT(verbs, world.file2list("strings/names/verbs.txt")) +GLOBAL_LIST_INIT(ing_verbs, world.file2list("strings/names/ing_verbs.txt")) +GLOBAL_LIST_INIT(adverbs, world.file2list("strings/names/adverbs.txt")) +GLOBAL_LIST_INIT(adjectives, world.file2list("strings/names/adjectives.txt")) +GLOBAL_LIST_INIT(dream_strings, world.file2list("strings/dreamstrings.txt")) +//loaded on startup because of " +//would include in rsc if ' was used + +/* +List of configurable names in preferences and their metadata +"id" = list( + "pref_name" = "name", //pref label + "qdesc" = "name", //popup question text + "allow_numbers" = FALSE, // numbers allowed in the name + "group" = "whatever", // group (these will be grouped together on pref ui ,order still follows the list so they need to be concurrent to be grouped) + "allow_null" = FALSE // if empty name is entered it's replaced with default value + ), +*/ +GLOBAL_LIST_INIT(preferences_custom_names, list( + "human" = list("pref_name" = "Backup Human", "qdesc" = "backup human name, used in the event you are assigned a command role as another species", "allow_numbers" = FALSE , "group" = "backup_human", "allow_null" = FALSE), + "clown" = list("pref_name" = "Clown" , "qdesc" = "clown name", "allow_numbers" = FALSE , "group" = "fun", "allow_null" = FALSE), + "mime" = list("pref_name" = "Mime", "qdesc" = "mime name" , "allow_numbers" = FALSE , "group" = "fun", "allow_null" = FALSE), + "cyborg" = list("pref_name" = "Cyborg", "qdesc" = "cyborg name (Leave empty to use default naming scheme)", "allow_numbers" = TRUE , "group" = "silicons", "allow_null" = TRUE), + "ai" = list("pref_name" = "AI", "qdesc" = "ai name", "allow_numbers" = TRUE , "group" = "silicons", "allow_null" = FALSE), + "religion" = list("pref_name" = "Chaplain religion", "qdesc" = "religion" , "allow_numbers" = TRUE , "group" = "chaplain", "allow_null" = FALSE), + "deity" = list("pref_name" = "Chaplain deity", "qdesc" = "deity", "allow_numbers" = TRUE , "group" = "chaplain", "allow_null" = FALSE) + )) diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index fa68fab85f..6a0d8201a7 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -1,43 +1,43 @@ -GLOBAL_LIST_EMPTY(cable_list) //Index for all cables, so that powernets don't have to look through the entire world all the time -GLOBAL_LIST_EMPTY(portals) //list of all /obj/effect/portal -GLOBAL_LIST_EMPTY(airlocks) //list of all airlocks -GLOBAL_LIST_EMPTY(mechas_list) //list of all mechs. Used by hostile mobs target tracking. -GLOBAL_LIST_EMPTY(shuttle_caller_list) //list of all communication consoles and AIs, for automatic shuttle calls when there are none. -GLOBAL_LIST_EMPTY(machines) //NOTE: this is a list of ALL machines now. The processing machines list is SSmachine.processing ! -GLOBAL_LIST_EMPTY(navigation_computers) //list of all /obj/machinery/computer/camera_advanced/shuttle_docker -GLOBAL_LIST_EMPTY(syndicate_shuttle_boards) //important to keep track of for managing nukeops war declarations. -GLOBAL_LIST_EMPTY(navbeacons) //list of all bot nagivation beacons, used for patrolling. -GLOBAL_LIST_EMPTY(teleportbeacons) //list of all tracking beacons used by teleporters -GLOBAL_LIST_EMPTY(deliverybeacons) //list of all MULEbot delivery beacons. -GLOBAL_LIST_EMPTY(deliverybeacontags) //list of all tags associated with delivery beacons. -GLOBAL_LIST_EMPTY(nuke_list) -GLOBAL_LIST_EMPTY(alarmdisplay) //list of all machines or programs that can display station alerts -GLOBAL_LIST_EMPTY(singularities) //list of all singularities on the station (actually technically all engines) - -GLOBAL_LIST(chemical_reactions_list) //list of all /datum/chemical_reaction datums. Used during chemical reactions -GLOBAL_LIST(chemical_reagents_list) //list of all /datum/reagent datums indexed by reagent id. Used by chemistry stuff -GLOBAL_LIST_EMPTY(materials_list) //list of all /datum/material datums indexed by material id. -GLOBAL_LIST_EMPTY(tech_list) //list of all /datum/tech datums indexed by id. -GLOBAL_LIST_EMPTY(surgeries_list) //list of all surgeries by name, associated with their path. -GLOBAL_LIST_EMPTY(uplink_items) //list of all uplink item typepaths, ascendingly sorted by their initial name. -GLOBAL_LIST_EMPTY(uplink_categories) //list of all uplink categories, listed by the order they are loaded in code. Be careful. -GLOBAL_LIST_EMPTY(crafting_recipes) //list of all table craft recipes -GLOBAL_LIST_EMPTY(rcd_list) //list of Rapid Construction Devices. -GLOBAL_LIST_EMPTY(apcs_list) //list of all Area Power Controller machines, separate from machines for powernet speeeeeeed. -GLOBAL_LIST_EMPTY(tracked_implants) //list of all current implants that are tracked to work out what sort of trek everyone is on. Sadly not on lavaworld not implemented... -GLOBAL_LIST_EMPTY(tracked_chem_implants) //list of implants the prisoner console can track and send inject commands too -GLOBAL_LIST_EMPTY(poi_list) //list of points of interest for observe/follow -GLOBAL_LIST_EMPTY(pinpointer_list) //list of all pinpointers. Used to change stuff they are pointing to all at once. -GLOBAL_LIST_EMPTY(zombie_infection_list) // A list of all zombie_infection organs, for any mass "animation" -GLOBAL_LIST_EMPTY(meteor_list) // List of all meteors. -GLOBAL_LIST_EMPTY(active_jammers) // List of active radio jammers -GLOBAL_LIST_EMPTY(ladders) -GLOBAL_LIST_EMPTY(trophy_cases) - -GLOBAL_LIST_EMPTY(wire_color_directory) -GLOBAL_LIST_EMPTY(wire_name_directory) - -GLOBAL_LIST_EMPTY(ai_status_displays) - -GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects -GLOBAL_LIST_EMPTY(alert_consoles) // Station alert consoles, /obj/machinery/computer/station_alert +GLOBAL_LIST_EMPTY(cable_list) //Index for all cables, so that powernets don't have to look through the entire world all the time +GLOBAL_LIST_EMPTY(portals) //list of all /obj/effect/portal +GLOBAL_LIST_EMPTY(airlocks) //list of all airlocks +GLOBAL_LIST_EMPTY(mechas_list) //list of all mechs. Used by hostile mobs target tracking. +GLOBAL_LIST_EMPTY(shuttle_caller_list) //list of all communication consoles and AIs, for automatic shuttle calls when there are none. +GLOBAL_LIST_EMPTY(machines) //NOTE: this is a list of ALL machines now. The processing machines list is SSmachine.processing ! +GLOBAL_LIST_EMPTY(navigation_computers) //list of all /obj/machinery/computer/camera_advanced/shuttle_docker +GLOBAL_LIST_EMPTY(syndicate_shuttle_boards) //important to keep track of for managing nukeops war declarations. +GLOBAL_LIST_EMPTY(navbeacons) //list of all bot nagivation beacons, used for patrolling. +GLOBAL_LIST_EMPTY(teleportbeacons) //list of all tracking beacons used by teleporters +GLOBAL_LIST_EMPTY(deliverybeacons) //list of all MULEbot delivery beacons. +GLOBAL_LIST_EMPTY(deliverybeacontags) //list of all tags associated with delivery beacons. +GLOBAL_LIST_EMPTY(nuke_list) +GLOBAL_LIST_EMPTY(alarmdisplay) //list of all machines or programs that can display station alerts +GLOBAL_LIST_EMPTY(singularities) //list of all singularities on the station (actually technically all engines) + +GLOBAL_LIST(chemical_reactions_list) //list of all /datum/chemical_reaction datums. Used during chemical reactions +GLOBAL_LIST(chemical_reagents_list) //list of all /datum/reagent datums indexed by reagent id. Used by chemistry stuff +GLOBAL_LIST_EMPTY(materials_list) //list of all /datum/material datums indexed by material id. +GLOBAL_LIST_EMPTY(tech_list) //list of all /datum/tech datums indexed by id. +GLOBAL_LIST_EMPTY(surgeries_list) //list of all surgeries by name, associated with their path. +GLOBAL_LIST_EMPTY(uplink_items) //list of all uplink item typepaths, ascendingly sorted by their initial name. +GLOBAL_LIST_EMPTY(uplink_categories) //list of all uplink categories, listed by the order they are loaded in code. Be careful. +GLOBAL_LIST_EMPTY(crafting_recipes) //list of all table craft recipes +GLOBAL_LIST_EMPTY(rcd_list) //list of Rapid Construction Devices. +GLOBAL_LIST_EMPTY(apcs_list) //list of all Area Power Controller machines, separate from machines for powernet speeeeeeed. +GLOBAL_LIST_EMPTY(tracked_implants) //list of all current implants that are tracked to work out what sort of trek everyone is on. Sadly not on lavaworld not implemented... +GLOBAL_LIST_EMPTY(tracked_chem_implants) //list of implants the prisoner console can track and send inject commands too +GLOBAL_LIST_EMPTY(poi_list) //list of points of interest for observe/follow +GLOBAL_LIST_EMPTY(pinpointer_list) //list of all pinpointers. Used to change stuff they are pointing to all at once. +GLOBAL_LIST_EMPTY(zombie_infection_list) // A list of all zombie_infection organs, for any mass "animation" +GLOBAL_LIST_EMPTY(meteor_list) // List of all meteors. +GLOBAL_LIST_EMPTY(active_jammers) // List of active radio jammers +GLOBAL_LIST_EMPTY(ladders) +GLOBAL_LIST_EMPTY(trophy_cases) + +GLOBAL_LIST_EMPTY(wire_color_directory) +GLOBAL_LIST_EMPTY(wire_name_directory) + +GLOBAL_LIST_EMPTY(ai_status_displays) + +GLOBAL_LIST_EMPTY(mob_spawners) // All mob_spawn objects +GLOBAL_LIST_EMPTY(alert_consoles) // Station alert consoles, /obj/machinery/computer/station_alert diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm index 01d5051dba..2a97c596b2 100644 --- a/code/_globalvars/logging.dm +++ b/code/_globalvars/logging.dm @@ -1,64 +1,64 @@ -GLOBAL_VAR(log_directory) -GLOBAL_PROTECT(log_directory) -GLOBAL_VAR(world_game_log) -GLOBAL_PROTECT(world_game_log) -GLOBAL_VAR(world_runtime_log) -GLOBAL_PROTECT(world_runtime_log) -GLOBAL_VAR(world_qdel_log) -GLOBAL_PROTECT(world_qdel_log) -GLOBAL_VAR(world_attack_log) -GLOBAL_PROTECT(world_attack_log) -GLOBAL_VAR(world_href_log) -GLOBAL_PROTECT(world_href_log) -GLOBAL_VAR(round_id) -GLOBAL_PROTECT(round_id) -GLOBAL_VAR(config_error_log) -GLOBAL_PROTECT(config_error_log) -GLOBAL_VAR(sql_error_log) -GLOBAL_PROTECT(sql_error_log) -GLOBAL_VAR(world_pda_log) -GLOBAL_PROTECT(world_pda_log) -GLOBAL_VAR(world_telecomms_log) -GLOBAL_PROTECT(world_telecomms_log) -GLOBAL_VAR(world_manifest_log) -GLOBAL_PROTECT(world_manifest_log) -GLOBAL_VAR(query_debug_log) -GLOBAL_PROTECT(query_debug_log) -GLOBAL_VAR(world_job_debug_log) -GLOBAL_PROTECT(world_job_debug_log) -GLOBAL_VAR(world_virus_log) -GLOBAL_PROTECT(world_virus_log) -GLOBAL_VAR(world_map_error_log) -GLOBAL_PROTECT(world_map_error_log) -GLOBAL_VAR(subsystem_log) -GLOBAL_PROTECT(subsystem_log) - -GLOBAL_LIST_EMPTY(bombers) -GLOBAL_PROTECT(bombers) -GLOBAL_LIST_EMPTY(admin_log) -GLOBAL_PROTECT(admin_log) -GLOBAL_LIST_EMPTY(lastsignalers) //keeps last 100 signals here in format: "[src] used [REF(src)] @ location [src.loc]: [freq]/[code]" -GLOBAL_PROTECT(lastsignalers) -GLOBAL_LIST_EMPTY(lawchanges) //Stores who uploaded laws to which silicon-based lifeform, and what the law was -GLOBAL_PROTECT(lawchanges) - -GLOBAL_LIST_EMPTY(combatlog) -GLOBAL_PROTECT(combatlog) -GLOBAL_LIST_EMPTY(IClog) -GLOBAL_PROTECT(IClog) -GLOBAL_LIST_EMPTY(OOClog) -GLOBAL_PROTECT(OOClog) -GLOBAL_LIST_EMPTY(adminlog) -GLOBAL_PROTECT(adminlog) - -GLOBAL_LIST_EMPTY(active_turfs_startlist) - -/////Picture logging -GLOBAL_VAR(picture_log_directory) -GLOBAL_PROTECT(picture_log_directory) - -GLOBAL_VAR_INIT(picture_logging_id, 1) -GLOBAL_PROTECT(picture_logging_id) -GLOBAL_VAR(picture_logging_prefix) -GLOBAL_PROTECT(picture_logging_prefix) -///// +GLOBAL_VAR(log_directory) +GLOBAL_PROTECT(log_directory) +GLOBAL_VAR(world_game_log) +GLOBAL_PROTECT(world_game_log) +GLOBAL_VAR(world_runtime_log) +GLOBAL_PROTECT(world_runtime_log) +GLOBAL_VAR(world_qdel_log) +GLOBAL_PROTECT(world_qdel_log) +GLOBAL_VAR(world_attack_log) +GLOBAL_PROTECT(world_attack_log) +GLOBAL_VAR(world_href_log) +GLOBAL_PROTECT(world_href_log) +GLOBAL_VAR(round_id) +GLOBAL_PROTECT(round_id) +GLOBAL_VAR(config_error_log) +GLOBAL_PROTECT(config_error_log) +GLOBAL_VAR(sql_error_log) +GLOBAL_PROTECT(sql_error_log) +GLOBAL_VAR(world_pda_log) +GLOBAL_PROTECT(world_pda_log) +GLOBAL_VAR(world_telecomms_log) +GLOBAL_PROTECT(world_telecomms_log) +GLOBAL_VAR(world_manifest_log) +GLOBAL_PROTECT(world_manifest_log) +GLOBAL_VAR(query_debug_log) +GLOBAL_PROTECT(query_debug_log) +GLOBAL_VAR(world_job_debug_log) +GLOBAL_PROTECT(world_job_debug_log) +GLOBAL_VAR(world_virus_log) +GLOBAL_PROTECT(world_virus_log) +GLOBAL_VAR(world_map_error_log) +GLOBAL_PROTECT(world_map_error_log) +GLOBAL_VAR(subsystem_log) +GLOBAL_PROTECT(subsystem_log) + +GLOBAL_LIST_EMPTY(bombers) +GLOBAL_PROTECT(bombers) +GLOBAL_LIST_EMPTY(admin_log) +GLOBAL_PROTECT(admin_log) +GLOBAL_LIST_EMPTY(lastsignalers) //keeps last 100 signals here in format: "[src] used [REF(src)] @ location [src.loc]: [freq]/[code]" +GLOBAL_PROTECT(lastsignalers) +GLOBAL_LIST_EMPTY(lawchanges) //Stores who uploaded laws to which silicon-based lifeform, and what the law was +GLOBAL_PROTECT(lawchanges) + +GLOBAL_LIST_EMPTY(combatlog) +GLOBAL_PROTECT(combatlog) +GLOBAL_LIST_EMPTY(IClog) +GLOBAL_PROTECT(IClog) +GLOBAL_LIST_EMPTY(OOClog) +GLOBAL_PROTECT(OOClog) +GLOBAL_LIST_EMPTY(adminlog) +GLOBAL_PROTECT(adminlog) + +GLOBAL_LIST_EMPTY(active_turfs_startlist) + +/////Picture logging +GLOBAL_VAR(picture_log_directory) +GLOBAL_PROTECT(picture_log_directory) + +GLOBAL_VAR_INIT(picture_logging_id, 1) +GLOBAL_PROTECT(picture_logging_id) +GLOBAL_VAR(picture_logging_prefix) +GLOBAL_PROTECT(picture_logging_prefix) +///// diff --git a/code/_globalvars/misc.dm b/code/_globalvars/misc.dm index ec3593ee9d..21e3663cca 100644 --- a/code/_globalvars/misc.dm +++ b/code/_globalvars/misc.dm @@ -1,35 +1,35 @@ -GLOBAL_VAR_INIT(admin_notice, "") // Admin notice that all clients see when joining the server - -GLOBAL_VAR_INIT(timezoneOffset, 0) // The difference betwen midnight (of the host computer) and 0 world.ticks. - -GLOBAL_VAR_INIT(year, time2text(world.realtime,"YYYY")) -GLOBAL_VAR_INIT(year_integer, text2num(year)) // = 2013??? - - -GLOBAL_VAR_INIT(announcertype, "standard") - - // For FTP requests. (i.e. downloading runtime logs.) - // However it'd be ok to use for accessing attack logs and such too, which are even laggier. -GLOBAL_VAR_INIT(fileaccess_timer, 0) - -GLOBAL_DATUM_INIT(data_core, /datum/datacore, new) - -GLOBAL_VAR_INIT(CELLRATE, 0.002) // conversion ratio between a watt-tick and kilojoule -GLOBAL_VAR_INIT(CHARGELEVEL, 0.001) // Cap for how fast cells charge, as a percentage-per-tick (.001 means cellcharge is capped to 1% per second) - -GLOBAL_LIST_EMPTY(powernets) - -GLOBAL_VAR_INIT(bsa_unlock, FALSE) //BSA unlocked by head ID swipes - -GLOBAL_LIST_EMPTY(player_details) // ckey -> /datum/player_details - -GLOBAL_LIST_EMPTY(clientless_round_timeouts) // ckey -> time that ckey can rejoin round - -// All religion stuff -GLOBAL_VAR(religion) -GLOBAL_VAR(deity) -GLOBAL_VAR(bible_name) -GLOBAL_VAR(bible_icon_state) -GLOBAL_VAR(bible_item_state) -GLOBAL_VAR(holy_weapon_type) -GLOBAL_VAR(holy_armor_type) +GLOBAL_VAR_INIT(admin_notice, "") // Admin notice that all clients see when joining the server + +GLOBAL_VAR_INIT(timezoneOffset, 0) // The difference betwen midnight (of the host computer) and 0 world.ticks. + +GLOBAL_VAR_INIT(year, time2text(world.realtime,"YYYY")) +GLOBAL_VAR_INIT(year_integer, text2num(year)) // = 2013??? + + +GLOBAL_VAR_INIT(announcertype, "standard") + + // For FTP requests. (i.e. downloading runtime logs.) + // However it'd be ok to use for accessing attack logs and such too, which are even laggier. +GLOBAL_VAR_INIT(fileaccess_timer, 0) + +GLOBAL_DATUM_INIT(data_core, /datum/datacore, new) + +GLOBAL_VAR_INIT(CELLRATE, 0.002) // conversion ratio between a watt-tick and kilojoule +GLOBAL_VAR_INIT(CHARGELEVEL, 0.001) // Cap for how fast cells charge, as a percentage-per-tick (.001 means cellcharge is capped to 1% per second) + +GLOBAL_LIST_EMPTY(powernets) + +GLOBAL_VAR_INIT(bsa_unlock, FALSE) //BSA unlocked by head ID swipes + +GLOBAL_LIST_EMPTY(player_details) // ckey -> /datum/player_details + +GLOBAL_LIST_EMPTY(clientless_round_timeouts) // ckey -> time that ckey can rejoin round + +// All religion stuff +GLOBAL_VAR(religion) +GLOBAL_VAR(deity) +GLOBAL_VAR(bible_name) +GLOBAL_VAR(bible_icon_state) +GLOBAL_VAR(bible_item_state) +GLOBAL_VAR(holy_weapon_type) +GLOBAL_VAR(holy_armor_type) diff --git a/code/_js/byjax.dm b/code/_js/byjax.dm index 9d96bbc412..7ac9bbff18 100644 --- a/code/_js/byjax.dm +++ b/code/_js/byjax.dm @@ -1,48 +1,48 @@ -//this function places received data into element with specified id. -#define js_byjax {" - -function replaceContent() { - var args = Array.prototype.slice.call(arguments); - var id = args\[0\]; - var content = args\[1\]; - var callback = null; - if(args\[2\]){ - callback = args\[2\]; - if(args\[3\]){ - args = args.slice(3); - } - } - var parent = document.getElementById(id); - if(typeof(parent)!=='undefined' && parent!=null){ - parent.innerHTML = content?content:''; - } - if(callback && window\[callback\]){ - window\[callback\].apply(null,args); - } -} -"} - -/* -sends data to control_id:replaceContent - -receiver - mob -control_id - window id (for windows opened with browse(), it'll be "windowname.browser") -target_element - HTML element id -new_content - HTML content -callback - js function that will be called after the data is sent -callback_args - arguments for callback function - -Be sure to include required js functions in your page, or it'll raise an exception. -*/ -/proc/send_byjax(receiver, control_id, target_element, new_content=null, callback=null, list/callback_args=null) - if(receiver && target_element && control_id) // && winexists(receiver, control_id)) - var/list/argums = list(target_element, new_content) - if(callback) - argums += callback - if(callback_args) - argums += callback_args - argums = list2params(argums) - - receiver << output(argums,"[control_id]:replaceContent") - return - +//this function places received data into element with specified id. +#define js_byjax {" + +function replaceContent() { + var args = Array.prototype.slice.call(arguments); + var id = args\[0\]; + var content = args\[1\]; + var callback = null; + if(args\[2\]){ + callback = args\[2\]; + if(args\[3\]){ + args = args.slice(3); + } + } + var parent = document.getElementById(id); + if(typeof(parent)!=='undefined' && parent!=null){ + parent.innerHTML = content?content:''; + } + if(callback && window\[callback\]){ + window\[callback\].apply(null,args); + } +} +"} + +/* +sends data to control_id:replaceContent + +receiver - mob +control_id - window id (for windows opened with browse(), it'll be "windowname.browser") +target_element - HTML element id +new_content - HTML content +callback - js function that will be called after the data is sent +callback_args - arguments for callback function + +Be sure to include required js functions in your page, or it'll raise an exception. +*/ +/proc/send_byjax(receiver, control_id, target_element, new_content=null, callback=null, list/callback_args=null) + if(receiver && target_element && control_id) // && winexists(receiver, control_id)) + var/list/argums = list(target_element, new_content) + if(callback) + argums += callback + if(callback_args) + argums += callback_args + argums = list2params(argums) + + receiver << output(argums,"[control_id]:replaceContent") + return + diff --git a/code/_onclick/adjacent.dm b/code/_onclick/adjacent.dm index 9485ea3374..3f3eecb676 100644 --- a/code/_onclick/adjacent.dm +++ b/code/_onclick/adjacent.dm @@ -1,105 +1,105 @@ -/* - Adjacency proc for determining touch range - - This is mostly to determine if a user can enter a square for the purposes of touching something. - Examples include reaching a square diagonally or reaching something on the other side of a glass window. - - This is calculated by looking for border items, or in the case of clicking diagonally from yourself, dense items. - This proc will NOT notice if you are trying to attack a window on the other side of a dense object in its turf. There is a window helper for that. - - Note that in all cases the neighbor is handled simply; this is usually the user's mob, in which case it is up to you - to check that the mob is not inside of something -*/ -/atom/proc/Adjacent(atom/neighbor) // basic inheritance, unused - return 0 - -// Not a sane use of the function and (for now) indicative of an error elsewhere -/area/Adjacent(var/atom/neighbor) - CRASH("Call to /area/Adjacent(), unimplemented proc") - - -/* - Adjacency (to turf): - * If you are in the same turf, always true - * If you are vertically/horizontally adjacent, ensure there are no border objects - * If you are diagonally adjacent, ensure you can pass through at least one of the mutually adjacent square. - * Passing through in this case ignores anything with the LETPASSTHROW pass flag, such as tables, racks, and morgue trays. -*/ -/turf/Adjacent(atom/neighbor, atom/target = null, atom/movable/mover = null) - var/turf/T0 = get_turf(neighbor) - - if(T0 == src) //same turf - return TRUE - - if(get_dist(src, T0) > 1 || z != T0.z) //too far - return FALSE - - // Non diagonal case - if(T0.x == x || T0.y == y) - // Check for border blockages - return T0.ClickCross(get_dir(T0,src), border_only = 1, target_atom = target, mover = mover) && src.ClickCross(get_dir(src,T0), border_only = 1, target_atom = target, mover = mover) - - // Diagonal case - var/in_dir = get_dir(T0,src) // eg. northwest (1+8) = 9 (00001001) - var/d1 = in_dir&3 // eg. north (1+8)&3 (0000 0011) = 1 (0000 0001) - var/d2 = in_dir&12 // eg. west (1+8)&12 (0000 1100) = 8 (0000 1000) - - for(var/d in list(d1,d2)) - if(!T0.ClickCross(d, border_only = 1, target_atom = target, mover = mover)) - continue // could not leave T0 in that direction - - var/turf/T1 = get_step(T0,d) - if(!T1 || T1.density) - continue - if(!T1.ClickCross(get_dir(T1,src), border_only = 0, target_atom = target, mover = mover) || !T1.ClickCross(get_dir(T1,T0), border_only = 0, target_atom = target, mover = mover)) - continue // couldn't enter or couldn't leave T1 - - if(!src.ClickCross(get_dir(src,T1), border_only = 1, target_atom = target, mover = mover)) - continue // could not enter src - - return 1 // we don't care about our own density - - return 0 - -/* - Adjacency (to anything else): - * Must be on a turf -*/ -/atom/movable/Adjacent(var/atom/neighbor) - if(neighbor == loc) - return TRUE - var/turf/T = loc - if(!istype(T)) - return FALSE - if(T.Adjacent(neighbor, neighbor, src)) - return TRUE - return FALSE - -// This is necessary for storage items not on your person. -/obj/item/Adjacent(var/atom/neighbor, var/recurse = 1) - if(neighbor == loc) - return 1 - if(isitem(loc)) - if(recurse > 0) - return loc.Adjacent(neighbor,recurse - 1) - return 0 - return ..() - -/* - This checks if you there is uninterrupted airspace between that turf and this one. - This is defined as any dense ON_BORDER_1 object, or any dense object without LETPASSTHROW. - The border_only flag allows you to not objects (for source and destination squares) -*/ -/turf/proc/ClickCross(target_dir, border_only, target_atom = null, atom/movable/mover = null) - for(var/obj/O in src) - if((mover && O.CanPass(mover,get_step(src,target_dir))) || (!mover && !O.density)) - continue - if(O == target_atom || O == mover || (O.pass_flags & LETPASSTHROW)) //check if there's a dense object present on the turf - continue // LETPASSTHROW is used for anything you can click through (or the firedoor special case, see above) - - if( O.flags_1&ON_BORDER_1) // windows are on border, check them first - if( O.dir & target_dir || O.dir & (O.dir-1) ) // full tile windows are just diagonals mechanically - return 0 //O.dir&(O.dir-1) is false for any cardinal direction, but true for diagonal ones - else if( !border_only ) // dense, not on border, cannot pass over - return 0 - return 1 +/* + Adjacency proc for determining touch range + + This is mostly to determine if a user can enter a square for the purposes of touching something. + Examples include reaching a square diagonally or reaching something on the other side of a glass window. + + This is calculated by looking for border items, or in the case of clicking diagonally from yourself, dense items. + This proc will NOT notice if you are trying to attack a window on the other side of a dense object in its turf. There is a window helper for that. + + Note that in all cases the neighbor is handled simply; this is usually the user's mob, in which case it is up to you + to check that the mob is not inside of something +*/ +/atom/proc/Adjacent(atom/neighbor) // basic inheritance, unused + return 0 + +// Not a sane use of the function and (for now) indicative of an error elsewhere +/area/Adjacent(var/atom/neighbor) + CRASH("Call to /area/Adjacent(), unimplemented proc") + + +/* + Adjacency (to turf): + * If you are in the same turf, always true + * If you are vertically/horizontally adjacent, ensure there are no border objects + * If you are diagonally adjacent, ensure you can pass through at least one of the mutually adjacent square. + * Passing through in this case ignores anything with the LETPASSTHROW pass flag, such as tables, racks, and morgue trays. +*/ +/turf/Adjacent(atom/neighbor, atom/target = null, atom/movable/mover = null) + var/turf/T0 = get_turf(neighbor) + + if(T0 == src) //same turf + return TRUE + + if(get_dist(src, T0) > 1 || z != T0.z) //too far + return FALSE + + // Non diagonal case + if(T0.x == x || T0.y == y) + // Check for border blockages + return T0.ClickCross(get_dir(T0,src), border_only = 1, target_atom = target, mover = mover) && src.ClickCross(get_dir(src,T0), border_only = 1, target_atom = target, mover = mover) + + // Diagonal case + var/in_dir = get_dir(T0,src) // eg. northwest (1+8) = 9 (00001001) + var/d1 = in_dir&3 // eg. north (1+8)&3 (0000 0011) = 1 (0000 0001) + var/d2 = in_dir&12 // eg. west (1+8)&12 (0000 1100) = 8 (0000 1000) + + for(var/d in list(d1,d2)) + if(!T0.ClickCross(d, border_only = 1, target_atom = target, mover = mover)) + continue // could not leave T0 in that direction + + var/turf/T1 = get_step(T0,d) + if(!T1 || T1.density) + continue + if(!T1.ClickCross(get_dir(T1,src), border_only = 0, target_atom = target, mover = mover) || !T1.ClickCross(get_dir(T1,T0), border_only = 0, target_atom = target, mover = mover)) + continue // couldn't enter or couldn't leave T1 + + if(!src.ClickCross(get_dir(src,T1), border_only = 1, target_atom = target, mover = mover)) + continue // could not enter src + + return 1 // we don't care about our own density + + return 0 + +/* + Adjacency (to anything else): + * Must be on a turf +*/ +/atom/movable/Adjacent(var/atom/neighbor) + if(neighbor == loc) + return TRUE + var/turf/T = loc + if(!istype(T)) + return FALSE + if(T.Adjacent(neighbor, neighbor, src)) + return TRUE + return FALSE + +// This is necessary for storage items not on your person. +/obj/item/Adjacent(var/atom/neighbor, var/recurse = 1) + if(neighbor == loc) + return 1 + if(isitem(loc)) + if(recurse > 0) + return loc.Adjacent(neighbor,recurse - 1) + return 0 + return ..() + +/* + This checks if you there is uninterrupted airspace between that turf and this one. + This is defined as any dense ON_BORDER_1 object, or any dense object without LETPASSTHROW. + The border_only flag allows you to not objects (for source and destination squares) +*/ +/turf/proc/ClickCross(target_dir, border_only, target_atom = null, atom/movable/mover = null) + for(var/obj/O in src) + if((mover && O.CanPass(mover,get_step(src,target_dir))) || (!mover && !O.density)) + continue + if(O == target_atom || O == mover || (O.pass_flags & LETPASSTHROW)) //check if there's a dense object present on the turf + continue // LETPASSTHROW is used for anything you can click through (or the firedoor special case, see above) + + if( O.flags_1&ON_BORDER_1) // windows are on border, check them first + if( O.dir & target_dir || O.dir & (O.dir-1) ) // full tile windows are just diagonals mechanically + return 0 //O.dir&(O.dir-1) is false for any cardinal direction, but true for diagonal ones + else if( !border_only ) // dense, not on border, cannot pass over + return 0 + return 1 diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 4c477f3872..9bf59d5e76 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -1,520 +1,520 @@ -/* - Click code cleanup - ~Sayu -*/ - -// 1 decisecond click delay (above and beyond mob/next_move) -//This is mainly modified by click code, to modify click delays elsewhere, use next_move and changeNext_move() -/mob/var/next_click = 0 - -// THESE DO NOT EFFECT THE BASE 1 DECISECOND DELAY OF NEXT_CLICK -/mob/var/next_move_adjust = 0 //Amount to adjust action/click delays by, + or - -/mob/var/next_move_modifier = 1 //Value to multiply action/click delays by - - -//Delays the mob's next click/action by num deciseconds -// eg: 10-3 = 7 deciseconds of delay -// eg: 10*0.5 = 5 deciseconds of delay -// DOES NOT EFFECT THE BASE 1 DECISECOND DELAY OF NEXT_CLICK - -/mob/proc/changeNext_move(num) - next_move = world.time + ((num+next_move_adjust)*next_move_modifier) - -/mob/living/changeNext_move(num) - var/mod = next_move_modifier - var/adj = next_move_adjust - for(var/i in status_effects) - var/datum/status_effect/S = i - mod *= S.nextmove_modifier() - adj += S.nextmove_adjust() - next_move = world.time + ((num + adj)*mod) - -/* - Before anything else, defer these calls to a per-mobtype handler. This allows us to - remove istype() spaghetti code, but requires the addition of other handler procs to simplify it. - - Alternately, you could hardcode every mob's variation in a flat ClickOn() proc; however, - that's a lot of code duplication and is hard to maintain. - - Note that this proc can be overridden, and is in the case of screen objects. -*/ -/atom/Click(location,control,params) - if(flags_1 & INITIALIZED_1) - SEND_SIGNAL(src, COMSIG_CLICK, location, control, params, usr) - usr.ClickOn(src, params) - -/atom/DblClick(location,control,params) - if(flags_1 & INITIALIZED_1) - usr.DblClickOn(src,params) - -/atom/MouseWheel(delta_x,delta_y,location,control,params) - if(flags_1 & INITIALIZED_1) - usr.MouseWheelOn(src, delta_x, delta_y, params) - -/* - Standard mob ClickOn() - Handles exceptions: Buildmode, middle click, modified clicks, mech actions - - After that, mostly just check your state, check whether you're holding an item, - check whether you're adjacent to the target, then pass off the click to whoever - is receiving it. - The most common are: - * mob/UnarmedAttack(atom,adjacent) - used here only when adjacent, with no item in hand; in the case of humans, checks gloves - * atom/attackby(item,user) - used only when adjacent - * item/afterattack(atom,user,adjacent,params) - used both ranged and adjacent - * mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed -*/ -/mob/proc/ClickOn( atom/A, params ) - if(world.time <= next_click) - return - next_click = world.time + world.tick_lag - - if(check_click_intercept(params,A)) - return - - if(notransform) - return - - var/list/modifiers = params2list(params) - if(modifiers["shift"] && modifiers["middle"]) - ShiftMiddleClickOn(A) - return - if(modifiers["shift"] && modifiers["ctrl"]) - CtrlShiftClickOn(A) - return - if(modifiers["middle"]) - MiddleClickOn(A) - return - if(modifiers["shift"] && (client && client.show_popup_menus || modifiers["right"])) //CIT CHANGE - makes shift-click examine use right click instead of left click in combat mode - ShiftClickOn(A) - return - if(modifiers["alt"]) // alt and alt-gr (rightalt) - AltClickOn(A) - return - if(modifiers["ctrl"]) - CtrlClickOn(A) - return - - if(modifiers["right"]) //CIT CHANGE - allows right clicking to perform actions - RightClickOn(A,params) //CIT CHANGE - ditto - return //CIT CHANGE - ditto - - if(incapacitated(ignore_restraints = 1)) - return - - face_atom(A) - - if(next_move > world.time) // in the year 2000... - return - - if(!modifiers["catcher"] && A.IsObscured()) - return - - if(ismecha(loc)) - var/obj/mecha/M = loc - return M.click_action(A,src,params) - - if(restrained()) - changeNext_move(CLICK_CD_HANDCUFFED) //Doing shit in cuffs shall be vey slow - RestrainedClickOn(A) - return - - if(in_throw_mode) - throw_item(A) - return - - var/obj/item/W = get_active_held_item() - - if(W == A) - W.attack_self(src) - update_inv_hands() - return - - //These are always reachable. - //User itself, current loc, and user inventory - if(A in DirectAccess()) - if(W) - W.melee_attack_chain(src, A, params) - else - if(ismob(A)) - changeNext_move(CLICK_CD_MELEE) - UnarmedAttack(A) - return - - //Can't reach anything else in lockers or other weirdness - if(!loc.AllowClick()) - return - - //Standard reach turf to turf or reaching inside storage - if(CanReach(A,W)) - if(W) - W.melee_attack_chain(src, A, params) - else - if(ismob(A)) - changeNext_move(CLICK_CD_MELEE) - UnarmedAttack(A,1) - else - if(W) - W.afterattack(A,src,0,params) - else - RangedAttack(A,params) - -//Is the atom obscured by a PREVENT_CLICK_UNDER_1 object above it -/atom/proc/IsObscured() - if(!isturf(loc)) //This only makes sense for things directly on turfs for now - return FALSE - var/turf/T = get_turf_pixel(src) - if(!T) - return FALSE - for(var/atom/movable/AM in T) - if(AM.flags_1 & PREVENT_CLICK_UNDER_1 && AM.density && AM.layer > layer) - return TRUE - return FALSE - -/turf/IsObscured() - for(var/atom/movable/AM in src) - if(AM.flags_1 & PREVENT_CLICK_UNDER_1 && AM.density) - return TRUE - return FALSE - -/atom/movable/proc/CanReach(atom/ultimate_target, obj/item/tool, view_only = FALSE) - // A backwards depth-limited breadth-first-search to see if the target is - // logically "in" anything adjacent to us. - var/list/direct_access = DirectAccess() - var/depth = 1 + (view_only ? STORAGE_VIEW_DEPTH : INVENTORY_DEPTH) - - var/list/closed = list() - var/list/checking = list(ultimate_target) - while (checking.len && depth > 0) - var/list/next = list() - --depth - - for(var/atom/target in checking) // will filter out nulls - if(closed[target] || isarea(target)) // avoid infinity situations - continue - closed[target] = TRUE - if(isturf(target) || isturf(target.loc) || (target in direct_access)) //Directly accessible atoms - if(Adjacent(target) || (tool && CheckToolReach(src, target, tool.reach))) //Adjacent or reaching attacks - return TRUE - - if (!target.loc) - continue - - if(!(SEND_SIGNAL(target.loc, COMSIG_ATOM_CANREACH, next) & COMPONENT_BLOCK_REACH) && target.loc.canReachInto(src, ultimate_target, next, view_only, tool)) - next += target.loc - - checking = next - return FALSE - -/atom/movable/proc/DirectAccess() - return list(src, loc) - -/mob/DirectAccess(atom/target) - return ..() + contents - -/mob/living/DirectAccess(atom/target) - return ..() + GetAllContents() - -//This is called reach into but it's called on the deepest things first so uh, make sure to account for that! -/atom/proc/canReachInto(atom/user, atom/target, list/next, view_only, obj/item/tool) - return TRUE - -/atom/proc/AllowClick() - return FALSE - -/turf/AllowClick() - return TRUE - -/proc/CheckToolReach(atom/movable/here, atom/movable/there, reach) - if(!here || !there) - return - switch(reach) - if(0) - return FALSE - if(1) - return FALSE //here.Adjacent(there) - if(2 to INFINITY) - var/obj/dummy = new(get_turf(here)) - dummy.pass_flags |= PASSTABLE - dummy.invisibility = INVISIBILITY_ABSTRACT - for(var/i in 1 to reach) //Limit it to that many tries - var/turf/T = get_step(dummy, get_dir(dummy, there)) - if(dummy.CanReach(there)) - qdel(dummy) - return TRUE - if(!dummy.Move(T)) //we're blocked! - qdel(dummy) - return - qdel(dummy) - -// Default behavior: ignore double clicks (the second click that makes the doubleclick call already calls for a normal click) -/mob/proc/DblClickOn(atom/A, params) - return - - -/* - Translates into attack_hand, etc. - - Note: proximity_flag here is used to distinguish between normal usage (flag=1), - and usage when clicking on things telekinetically (flag=0). This proc will - not be called at ranged except with telekinesis. - - proximity_flag is not currently passed to attack_hand, and is instead used - in human click code to allow glove touches only at melee range. -*/ -/mob/proc/UnarmedAttack(atom/A, proximity_flag) - if(ismob(A)) - changeNext_move(CLICK_CD_MELEE) - return - -/* - Ranged unarmed attack: - - This currently is just a default for all mobs, involving - laser eyes and telekinesis. You could easily add exceptions - for things like ranged glove touches, spitting alien acid/neurotoxin, - animals lunging, etc. -*/ -/mob/proc/RangedAttack(atom/A, params) - SEND_SIGNAL(src, COMSIG_MOB_ATTACK_RANGED, A, params) -/* - Restrained ClickOn - - Used when you are handcuffed and click things. - Not currently used by anything but could easily be. -*/ -/mob/proc/RestrainedClickOn(atom/A) - return - -/* - Middle click - Only used for swapping hands -*/ -/mob/proc/MiddleClickOn(atom/A) - return - -/mob/living/carbon/MiddleClickOn(atom/A) - if(!stat && mind && iscarbon(A) && A != src) - var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling) - if(C && C.chosen_sting) - C.chosen_sting.try_to_sting(src,A) - next_click = world.time + 5 - return - swap_hand() - -/mob/living/simple_animal/drone/MiddleClickOn(atom/A) - swap_hand() - -// In case of use break glass -/* -/atom/proc/MiddleClick(mob/M as mob) - return -*/ - -/* - Shift click - For most mobs, examine. - This is overridden in ai.dm -*/ -/mob/proc/ShiftClickOn(atom/A) - A.ShiftClick(src) - return -/atom/proc/ShiftClick(mob/user) - SEND_SIGNAL(src, COMSIG_CLICK_SHIFT, user) - user.examinate(src) - return - -/* - Ctrl click - For most objects, pull -*/ - -/mob/proc/CtrlClickOn(atom/A) - A.CtrlClick(src) - return - -/atom/proc/CtrlClick(mob/user) - SEND_SIGNAL(src, COMSIG_CLICK_CTRL, user) - var/mob/living/ML = user - if(istype(ML)) - ML.pulled(src) - -/mob/living/carbon/human/CtrlClick(mob/user) - if(ishuman(user) && Adjacent(user) && !user.incapacitated()) - if(world.time < user.next_move) - return FALSE - var/mob/living/carbon/human/H = user - H.dna.species.grab(H, src, H.mind.martial_art) - H.changeNext_move(CLICK_CD_MELEE) - else - ..() -/* - Alt click - Unused except for AI -*/ -/mob/proc/AltClickOn(atom/A) - if(!A.AltClick(src)) - altclick_listed_turf(A) - -/mob/proc/altclick_listed_turf(atom/A) - var/turf/T = get_turf(A) - if(T == A.loc || T == A) - if(T == listed_turf) - listed_turf = null - else if(TurfAdjacent(T)) - listed_turf = T - client.statpanel = T.name - -/mob/living/carbon/AltClickOn(atom/A) - if(!stat && mind && iscarbon(A) && A != src) - var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling) - if(C && C.chosen_sting) - C.chosen_sting.try_to_sting(src,A) - next_click = world.time + 5 - return - ..() - -/atom/proc/AltClick(mob/user) - . = SEND_SIGNAL(src, COMSIG_CLICK_ALT, user) - -/mob/proc/TurfAdjacent(turf/T) - return T.Adjacent(src) - -/* - Control+Shift click - Unused except for AI -*/ -/mob/proc/CtrlShiftClickOn(atom/A) - A.CtrlShiftClick(src) - return - -/mob/proc/ShiftMiddleClickOn(atom/A) - src.pointed(A) - return - -/atom/proc/CtrlShiftClick(mob/user) - SEND_SIGNAL(src, COMSIG_CLICK_CTRL_SHIFT) - return - -/* - Misc helpers - - Laser Eyes: as the name implies, handles this since nothing else does currently - face_atom: turns the mob towards what you clicked on -*/ -/mob/proc/LaserEyes(atom/A, params) - return - -/mob/living/LaserEyes(atom/A, params) - changeNext_move(CLICK_CD_RANGE) - - var/obj/item/projectile/beam/LE = new /obj/item/projectile/beam( loc ) - LE.icon = 'icons/effects/genetics.dmi' - LE.icon_state = "eyelasers" - playsound(usr.loc, 'sound/weapons/taser2.ogg', 75, 1) - - LE.firer = src - LE.def_zone = get_organ_target() - LE.preparePixelProjectile(A, src, params) - LE.fire() - -// Simple helper to face what you clicked on, in case it should be needed in more than one place -/mob/proc/face_atom(atom/A) - if( buckled || stat != CONSCIOUS || !A || !x || !y || !A.x || !A.y ) - return - var/dx = A.x - x - var/dy = A.y - y - if(!dx && !dy) // Wall items are graphically shifted but on the floor - if(A.pixel_y > 16) - setDir(NORTH) - else if(A.pixel_y < -16) - setDir(SOUTH) - else if(A.pixel_x > 16) - setDir(EAST) - else if(A.pixel_x < -16) - setDir(WEST) - return - - if(abs(dx) < abs(dy)) - if(dy > 0) - setDir(NORTH) - else - setDir(SOUTH) - else - if(dx > 0) - setDir(EAST) - else - setDir(WEST) - -//debug -/obj/screen/proc/scale_to(x1,y1) - if(!y1) - y1 = x1 - var/matrix/M = new - M.Scale(x1,y1) - transform = M - -/obj/screen/click_catcher - icon = 'icons/mob/screen_gen.dmi' - icon_state = "catcher" - plane = CLICKCATCHER_PLANE - mouse_opacity = MOUSE_OPACITY_OPAQUE - screen_loc = "CENTER" - -#define MAX_SAFE_BYOND_ICON_SCALE_TILES (MAX_SAFE_BYOND_ICON_SCALE_PX / world.icon_size) -#define MAX_SAFE_BYOND_ICON_SCALE_PX (33 * 32) //Not using world.icon_size on purpose. - -/obj/screen/click_catcher/proc/UpdateGreed(view_size_x = 15, view_size_y = 15) - var/icon/newicon = icon('icons/mob/screen_gen.dmi', "catcher") - var/ox = min(MAX_SAFE_BYOND_ICON_SCALE_TILES, view_size_x) - var/oy = min(MAX_SAFE_BYOND_ICON_SCALE_TILES, view_size_y) - var/px = view_size_x * world.icon_size - var/py = view_size_y * world.icon_size - var/sx = min(MAX_SAFE_BYOND_ICON_SCALE_PX, px) - var/sy = min(MAX_SAFE_BYOND_ICON_SCALE_PX, py) - newicon.Scale(sx, sy) - icon = newicon - screen_loc = "CENTER-[(ox-1)*0.5],CENTER-[(oy-1)*0.5]" - var/matrix/M = new - M.Scale(px/sx, py/sy) - transform = M - -/obj/screen/click_catcher/Click(location, control, params) - var/list/modifiers = params2list(params) - if(modifiers["middle"] && iscarbon(usr)) - var/mob/living/carbon/C = usr - C.swap_hand() - else - var/turf/T = params2turf(modifiers["screen-loc"], get_turf(usr.client ? usr.client.eye : usr), usr.client) - params += "&catcher=1" - if(T) - T.Click(location, control, params) - . = 1 - -/* MouseWheelOn */ - -/mob/proc/MouseWheelOn(atom/A, delta_x, delta_y, params) - return - -/mob/dead/observer/MouseWheelOn(atom/A, delta_x, delta_y, params) - var/list/modifier = params2list(params) - if(modifier["shift"]) - var/view = 0 - if(delta_y > 0) - view = -1 - else - view = 1 - add_view_range(view) - -/mob/proc/check_click_intercept(params,A) - //Client level intercept - if(client && client.click_intercept) - if(call(client.click_intercept, "InterceptClickOn")(src, params, A)) - return TRUE - - //Mob level intercept - if(click_intercept) - if(call(click_intercept, "InterceptClickOn")(src, params, A)) - return TRUE - - return FALSE +/* + Click code cleanup + ~Sayu +*/ + +// 1 decisecond click delay (above and beyond mob/next_move) +//This is mainly modified by click code, to modify click delays elsewhere, use next_move and changeNext_move() +/mob/var/next_click = 0 + +// THESE DO NOT EFFECT THE BASE 1 DECISECOND DELAY OF NEXT_CLICK +/mob/var/next_move_adjust = 0 //Amount to adjust action/click delays by, + or - +/mob/var/next_move_modifier = 1 //Value to multiply action/click delays by + + +//Delays the mob's next click/action by num deciseconds +// eg: 10-3 = 7 deciseconds of delay +// eg: 10*0.5 = 5 deciseconds of delay +// DOES NOT EFFECT THE BASE 1 DECISECOND DELAY OF NEXT_CLICK + +/mob/proc/changeNext_move(num) + next_move = world.time + ((num+next_move_adjust)*next_move_modifier) + +/mob/living/changeNext_move(num) + var/mod = next_move_modifier + var/adj = next_move_adjust + for(var/i in status_effects) + var/datum/status_effect/S = i + mod *= S.nextmove_modifier() + adj += S.nextmove_adjust() + next_move = world.time + ((num + adj)*mod) + +/* + Before anything else, defer these calls to a per-mobtype handler. This allows us to + remove istype() spaghetti code, but requires the addition of other handler procs to simplify it. + + Alternately, you could hardcode every mob's variation in a flat ClickOn() proc; however, + that's a lot of code duplication and is hard to maintain. + + Note that this proc can be overridden, and is in the case of screen objects. +*/ +/atom/Click(location,control,params) + if(flags_1 & INITIALIZED_1) + SEND_SIGNAL(src, COMSIG_CLICK, location, control, params, usr) + usr.ClickOn(src, params) + +/atom/DblClick(location,control,params) + if(flags_1 & INITIALIZED_1) + usr.DblClickOn(src,params) + +/atom/MouseWheel(delta_x,delta_y,location,control,params) + if(flags_1 & INITIALIZED_1) + usr.MouseWheelOn(src, delta_x, delta_y, params) + +/* + Standard mob ClickOn() + Handles exceptions: Buildmode, middle click, modified clicks, mech actions + + After that, mostly just check your state, check whether you're holding an item, + check whether you're adjacent to the target, then pass off the click to whoever + is receiving it. + The most common are: + * mob/UnarmedAttack(atom,adjacent) - used here only when adjacent, with no item in hand; in the case of humans, checks gloves + * atom/attackby(item,user) - used only when adjacent + * item/afterattack(atom,user,adjacent,params) - used both ranged and adjacent + * mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed +*/ +/mob/proc/ClickOn( atom/A, params ) + if(world.time <= next_click) + return + next_click = world.time + world.tick_lag + + if(check_click_intercept(params,A)) + return + + if(notransform) + return + + var/list/modifiers = params2list(params) + if(modifiers["shift"] && modifiers["middle"]) + ShiftMiddleClickOn(A) + return + if(modifiers["shift"] && modifiers["ctrl"]) + CtrlShiftClickOn(A) + return + if(modifiers["middle"]) + MiddleClickOn(A) + return + if(modifiers["shift"] && (client && client.show_popup_menus || modifiers["right"])) //CIT CHANGE - makes shift-click examine use right click instead of left click in combat mode + ShiftClickOn(A) + return + if(modifiers["alt"]) // alt and alt-gr (rightalt) + AltClickOn(A) + return + if(modifiers["ctrl"]) + CtrlClickOn(A) + return + + if(modifiers["right"]) //CIT CHANGE - allows right clicking to perform actions + RightClickOn(A,params) //CIT CHANGE - ditto + return //CIT CHANGE - ditto + + if(incapacitated(ignore_restraints = 1)) + return + + face_atom(A) + + if(next_move > world.time) // in the year 2000... + return + + if(!modifiers["catcher"] && A.IsObscured()) + return + + if(ismecha(loc)) + var/obj/mecha/M = loc + return M.click_action(A,src,params) + + if(restrained()) + changeNext_move(CLICK_CD_HANDCUFFED) //Doing shit in cuffs shall be vey slow + RestrainedClickOn(A) + return + + if(in_throw_mode) + throw_item(A) + return + + var/obj/item/W = get_active_held_item() + + if(W == A) + W.attack_self(src) + update_inv_hands() + return + + //These are always reachable. + //User itself, current loc, and user inventory + if(A in DirectAccess()) + if(W) + W.melee_attack_chain(src, A, params) + else + if(ismob(A)) + changeNext_move(CLICK_CD_MELEE) + UnarmedAttack(A) + return + + //Can't reach anything else in lockers or other weirdness + if(!loc.AllowClick()) + return + + //Standard reach turf to turf or reaching inside storage + if(CanReach(A,W)) + if(W) + W.melee_attack_chain(src, A, params) + else + if(ismob(A)) + changeNext_move(CLICK_CD_MELEE) + UnarmedAttack(A,1) + else + if(W) + W.afterattack(A,src,0,params) + else + RangedAttack(A,params) + +//Is the atom obscured by a PREVENT_CLICK_UNDER_1 object above it +/atom/proc/IsObscured() + if(!isturf(loc)) //This only makes sense for things directly on turfs for now + return FALSE + var/turf/T = get_turf_pixel(src) + if(!T) + return FALSE + for(var/atom/movable/AM in T) + if(AM.flags_1 & PREVENT_CLICK_UNDER_1 && AM.density && AM.layer > layer) + return TRUE + return FALSE + +/turf/IsObscured() + for(var/atom/movable/AM in src) + if(AM.flags_1 & PREVENT_CLICK_UNDER_1 && AM.density) + return TRUE + return FALSE + +/atom/movable/proc/CanReach(atom/ultimate_target, obj/item/tool, view_only = FALSE) + // A backwards depth-limited breadth-first-search to see if the target is + // logically "in" anything adjacent to us. + var/list/direct_access = DirectAccess() + var/depth = 1 + (view_only ? STORAGE_VIEW_DEPTH : INVENTORY_DEPTH) + + var/list/closed = list() + var/list/checking = list(ultimate_target) + while (checking.len && depth > 0) + var/list/next = list() + --depth + + for(var/atom/target in checking) // will filter out nulls + if(closed[target] || isarea(target)) // avoid infinity situations + continue + closed[target] = TRUE + if(isturf(target) || isturf(target.loc) || (target in direct_access)) //Directly accessible atoms + if(Adjacent(target) || (tool && CheckToolReach(src, target, tool.reach))) //Adjacent or reaching attacks + return TRUE + + if (!target.loc) + continue + + if(!(SEND_SIGNAL(target.loc, COMSIG_ATOM_CANREACH, next) & COMPONENT_BLOCK_REACH) && target.loc.canReachInto(src, ultimate_target, next, view_only, tool)) + next += target.loc + + checking = next + return FALSE + +/atom/movable/proc/DirectAccess() + return list(src, loc) + +/mob/DirectAccess(atom/target) + return ..() + contents + +/mob/living/DirectAccess(atom/target) + return ..() + GetAllContents() + +//This is called reach into but it's called on the deepest things first so uh, make sure to account for that! +/atom/proc/canReachInto(atom/user, atom/target, list/next, view_only, obj/item/tool) + return TRUE + +/atom/proc/AllowClick() + return FALSE + +/turf/AllowClick() + return TRUE + +/proc/CheckToolReach(atom/movable/here, atom/movable/there, reach) + if(!here || !there) + return + switch(reach) + if(0) + return FALSE + if(1) + return FALSE //here.Adjacent(there) + if(2 to INFINITY) + var/obj/dummy = new(get_turf(here)) + dummy.pass_flags |= PASSTABLE + dummy.invisibility = INVISIBILITY_ABSTRACT + for(var/i in 1 to reach) //Limit it to that many tries + var/turf/T = get_step(dummy, get_dir(dummy, there)) + if(dummy.CanReach(there)) + qdel(dummy) + return TRUE + if(!dummy.Move(T)) //we're blocked! + qdel(dummy) + return + qdel(dummy) + +// Default behavior: ignore double clicks (the second click that makes the doubleclick call already calls for a normal click) +/mob/proc/DblClickOn(atom/A, params) + return + + +/* + Translates into attack_hand, etc. + + Note: proximity_flag here is used to distinguish between normal usage (flag=1), + and usage when clicking on things telekinetically (flag=0). This proc will + not be called at ranged except with telekinesis. + + proximity_flag is not currently passed to attack_hand, and is instead used + in human click code to allow glove touches only at melee range. +*/ +/mob/proc/UnarmedAttack(atom/A, proximity_flag) + if(ismob(A)) + changeNext_move(CLICK_CD_MELEE) + return + +/* + Ranged unarmed attack: + + This currently is just a default for all mobs, involving + laser eyes and telekinesis. You could easily add exceptions + for things like ranged glove touches, spitting alien acid/neurotoxin, + animals lunging, etc. +*/ +/mob/proc/RangedAttack(atom/A, params) + SEND_SIGNAL(src, COMSIG_MOB_ATTACK_RANGED, A, params) +/* + Restrained ClickOn + + Used when you are handcuffed and click things. + Not currently used by anything but could easily be. +*/ +/mob/proc/RestrainedClickOn(atom/A) + return + +/* + Middle click + Only used for swapping hands +*/ +/mob/proc/MiddleClickOn(atom/A) + return + +/mob/living/carbon/MiddleClickOn(atom/A) + if(!stat && mind && iscarbon(A) && A != src) + var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling) + if(C && C.chosen_sting) + C.chosen_sting.try_to_sting(src,A) + next_click = world.time + 5 + return + swap_hand() + +/mob/living/simple_animal/drone/MiddleClickOn(atom/A) + swap_hand() + +// In case of use break glass +/* +/atom/proc/MiddleClick(mob/M as mob) + return +*/ + +/* + Shift click + For most mobs, examine. + This is overridden in ai.dm +*/ +/mob/proc/ShiftClickOn(atom/A) + A.ShiftClick(src) + return +/atom/proc/ShiftClick(mob/user) + SEND_SIGNAL(src, COMSIG_CLICK_SHIFT, user) + user.examinate(src) + return + +/* + Ctrl click + For most objects, pull +*/ + +/mob/proc/CtrlClickOn(atom/A) + A.CtrlClick(src) + return + +/atom/proc/CtrlClick(mob/user) + SEND_SIGNAL(src, COMSIG_CLICK_CTRL, user) + var/mob/living/ML = user + if(istype(ML)) + ML.pulled(src) + +/mob/living/carbon/human/CtrlClick(mob/user) + if(ishuman(user) && Adjacent(user) && !user.incapacitated()) + if(world.time < user.next_move) + return FALSE + var/mob/living/carbon/human/H = user + H.dna.species.grab(H, src, H.mind.martial_art) + H.changeNext_move(CLICK_CD_MELEE) + else + ..() +/* + Alt click + Unused except for AI +*/ +/mob/proc/AltClickOn(atom/A) + if(!A.AltClick(src)) + altclick_listed_turf(A) + +/mob/proc/altclick_listed_turf(atom/A) + var/turf/T = get_turf(A) + if(T == A.loc || T == A) + if(T == listed_turf) + listed_turf = null + else if(TurfAdjacent(T)) + listed_turf = T + client.statpanel = T.name + +/mob/living/carbon/AltClickOn(atom/A) + if(!stat && mind && iscarbon(A) && A != src) + var/datum/antagonist/changeling/C = mind.has_antag_datum(/datum/antagonist/changeling) + if(C && C.chosen_sting) + C.chosen_sting.try_to_sting(src,A) + next_click = world.time + 5 + return + ..() + +/atom/proc/AltClick(mob/user) + . = SEND_SIGNAL(src, COMSIG_CLICK_ALT, user) + +/mob/proc/TurfAdjacent(turf/T) + return T.Adjacent(src) + +/* + Control+Shift click + Unused except for AI +*/ +/mob/proc/CtrlShiftClickOn(atom/A) + A.CtrlShiftClick(src) + return + +/mob/proc/ShiftMiddleClickOn(atom/A) + src.pointed(A) + return + +/atom/proc/CtrlShiftClick(mob/user) + SEND_SIGNAL(src, COMSIG_CLICK_CTRL_SHIFT) + return + +/* + Misc helpers + + Laser Eyes: as the name implies, handles this since nothing else does currently + face_atom: turns the mob towards what you clicked on +*/ +/mob/proc/LaserEyes(atom/A, params) + return + +/mob/living/LaserEyes(atom/A, params) + changeNext_move(CLICK_CD_RANGE) + + var/obj/item/projectile/beam/LE = new /obj/item/projectile/beam( loc ) + LE.icon = 'icons/effects/genetics.dmi' + LE.icon_state = "eyelasers" + playsound(usr.loc, 'sound/weapons/taser2.ogg', 75, 1) + + LE.firer = src + LE.def_zone = get_organ_target() + LE.preparePixelProjectile(A, src, params) + LE.fire() + +// Simple helper to face what you clicked on, in case it should be needed in more than one place +/mob/proc/face_atom(atom/A) + if( buckled || stat != CONSCIOUS || !A || !x || !y || !A.x || !A.y ) + return + var/dx = A.x - x + var/dy = A.y - y + if(!dx && !dy) // Wall items are graphically shifted but on the floor + if(A.pixel_y > 16) + setDir(NORTH) + else if(A.pixel_y < -16) + setDir(SOUTH) + else if(A.pixel_x > 16) + setDir(EAST) + else if(A.pixel_x < -16) + setDir(WEST) + return + + if(abs(dx) < abs(dy)) + if(dy > 0) + setDir(NORTH) + else + setDir(SOUTH) + else + if(dx > 0) + setDir(EAST) + else + setDir(WEST) + +//debug +/obj/screen/proc/scale_to(x1,y1) + if(!y1) + y1 = x1 + var/matrix/M = new + M.Scale(x1,y1) + transform = M + +/obj/screen/click_catcher + icon = 'icons/mob/screen_gen.dmi' + icon_state = "catcher" + plane = CLICKCATCHER_PLANE + mouse_opacity = MOUSE_OPACITY_OPAQUE + screen_loc = "CENTER" + +#define MAX_SAFE_BYOND_ICON_SCALE_TILES (MAX_SAFE_BYOND_ICON_SCALE_PX / world.icon_size) +#define MAX_SAFE_BYOND_ICON_SCALE_PX (33 * 32) //Not using world.icon_size on purpose. + +/obj/screen/click_catcher/proc/UpdateGreed(view_size_x = 15, view_size_y = 15) + var/icon/newicon = icon('icons/mob/screen_gen.dmi', "catcher") + var/ox = min(MAX_SAFE_BYOND_ICON_SCALE_TILES, view_size_x) + var/oy = min(MAX_SAFE_BYOND_ICON_SCALE_TILES, view_size_y) + var/px = view_size_x * world.icon_size + var/py = view_size_y * world.icon_size + var/sx = min(MAX_SAFE_BYOND_ICON_SCALE_PX, px) + var/sy = min(MAX_SAFE_BYOND_ICON_SCALE_PX, py) + newicon.Scale(sx, sy) + icon = newicon + screen_loc = "CENTER-[(ox-1)*0.5],CENTER-[(oy-1)*0.5]" + var/matrix/M = new + M.Scale(px/sx, py/sy) + transform = M + +/obj/screen/click_catcher/Click(location, control, params) + var/list/modifiers = params2list(params) + if(modifiers["middle"] && iscarbon(usr)) + var/mob/living/carbon/C = usr + C.swap_hand() + else + var/turf/T = params2turf(modifiers["screen-loc"], get_turf(usr.client ? usr.client.eye : usr), usr.client) + params += "&catcher=1" + if(T) + T.Click(location, control, params) + . = 1 + +/* MouseWheelOn */ + +/mob/proc/MouseWheelOn(atom/A, delta_x, delta_y, params) + return + +/mob/dead/observer/MouseWheelOn(atom/A, delta_x, delta_y, params) + var/list/modifier = params2list(params) + if(modifier["shift"]) + var/view = 0 + if(delta_y > 0) + view = -1 + else + view = 1 + add_view_range(view) + +/mob/proc/check_click_intercept(params,A) + //Client level intercept + if(client && client.click_intercept) + if(call(client.click_intercept, "InterceptClickOn")(src, params, A)) + return TRUE + + //Mob level intercept + if(click_intercept) + if(call(click_intercept, "InterceptClickOn")(src, params, A)) + return TRUE + + return FALSE diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index a2d566d566..6e3cfea424 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -1,185 +1,185 @@ -/* - Cyborg ClickOn() - - Cyborgs have no range restriction on attack_robot(), because it is basically an AI click. - However, they do have a range restriction on item use, so they cannot do without the - adjacency code. -*/ - -/mob/living/silicon/robot/ClickOn(var/atom/A, var/params) - if(world.time <= next_click) - return - next_click = world.time + 1 - - if(check_click_intercept(params,A)) - return - - if(stat || lockcharge || IsKnockdown() || IsStun() || IsUnconscious()) - return - - var/list/modifiers = params2list(params) - if(modifiers["shift"] && modifiers["ctrl"]) - CtrlShiftClickOn(A) - return - if(modifiers["shift"] && modifiers["middle"]) - ShiftMiddleClickOn(A) - return - if(modifiers["middle"]) - MiddleClickOn(A) - return - if(modifiers["shift"]) - ShiftClickOn(A) - return - if(modifiers["alt"]) // alt and alt-gr (rightalt) - AltClickOn(A) - return - if(modifiers["ctrl"]) - CtrlClickOn(A) - return - - if(next_move >= world.time) - return - - face_atom(A) // change direction to face what you clicked on - - /* - cyborg restrained() currently does nothing - if(restrained()) - RestrainedClickOn(A) - return - */ - if(aicamera.in_camera_mode) //Cyborg picture taking - aicamera.camera_mode_off() - aicamera.captureimage(A, usr) - return - - var/obj/item/W = get_active_held_item() - - if(!W && A.Adjacent(src) && (isobj(A) || ismob(A))) - var/atom/movable/C = A - if(C.can_buckle && C.has_buckled_mobs()) - if(C.buckled_mobs.len > 1) - var/unbuckled = input(src, "Who do you wish to unbuckle?","Unbuckle Who?") as null|mob in C.buckled_mobs - if(C.user_unbuckle_mob(unbuckled,src)) - return - else - if(C.user_unbuckle_mob(C.buckled_mobs[1],src)) - return - - if(!W && get_dist(src,A) <= interaction_range) - A.attack_robot(src) - return - - if(W) - // buckled cannot prevent machine interlinking but stops arm movement - if( buckled || incapacitated()) - return - - if(W == A) - W.attack_self(src) - return - - // cyborgs are prohibited from using storage items so we can I think safely remove (A.loc in contents) - if(A == loc || (A in loc) || (A in contents)) - W.melee_attack_chain(src, A, params) - return - - if(!isturf(loc)) - return - - // cyborgs are prohibited from using storage items so we can I think safely remove (A.loc && isturf(A.loc.loc)) - if(isturf(A) || isturf(A.loc)) - if(A.Adjacent(src)) // see adjacent.dm - W.melee_attack_chain(src, A, params) - return - else - W.afterattack(A, src, 0, params) - return - -//Middle click cycles through selected modules. -/mob/living/silicon/robot/MiddleClickOn(atom/A) - cycle_modules() - return - -//Give cyborgs hotkey clicks without breaking existing uses of hotkey clicks -// for non-doors/apcs -/mob/living/silicon/robot/CtrlShiftClickOn(atom/A) - A.BorgCtrlShiftClick(src) -/mob/living/silicon/robot/ShiftClickOn(atom/A) - A.BorgShiftClick(src) -/mob/living/silicon/robot/CtrlClickOn(atom/A) - A.BorgCtrlClick(src) -/mob/living/silicon/robot/AltClickOn(atom/A) - if(!A.BorgAltClick(src)) - altclick_listed_turf(A) - -/atom/proc/BorgCtrlShiftClick(mob/living/silicon/robot/user) //forward to human click if not overridden - CtrlShiftClick(user) - -/obj/machinery/door/airlock/BorgCtrlShiftClick(mob/living/silicon/robot/user) // Sets/Unsets Emergency Access Override Forwards to AI code. - if(get_dist(src,user) <= user.interaction_range) - AICtrlShiftClick() - else - ..() - - -/atom/proc/BorgShiftClick(mob/living/silicon/robot/user) //forward to human click if not overridden - ShiftClick(user) - -/obj/machinery/door/airlock/BorgShiftClick(mob/living/silicon/robot/user) // Opens and closes doors! Forwards to AI code. - if(get_dist(src,user) <= user.interaction_range) - AIShiftClick() - else - ..() - - -/atom/proc/BorgCtrlClick(mob/living/silicon/robot/user) //forward to human click if not overridden - CtrlClick(user) - -/obj/machinery/door/airlock/BorgCtrlClick(mob/living/silicon/robot/user) // Bolts doors. Forwards to AI code. - if(get_dist(src,user) <= user.interaction_range) - AICtrlClick() - else - ..() - -/obj/machinery/power/apc/BorgCtrlClick(mob/living/silicon/robot/user) // turns off/on APCs. Forwards to AI code. - if(get_dist(src,user) <= user.interaction_range) - AICtrlClick() - else - ..() - -/obj/machinery/turretid/BorgCtrlClick(mob/living/silicon/robot/user) //turret control on/off. Forwards to AI code. - if(get_dist(src,user) <= user.interaction_range) - AICtrlClick() - else - ..() - -/atom/proc/BorgAltClick(mob/living/silicon/robot/user) - return AltClick(user) - -/obj/machinery/door/airlock/BorgAltClick(mob/living/silicon/robot/user) // Eletrifies doors. Forwards to AI code. - if(get_dist(src,user) <= user.interaction_range) - return AIAltClick() - return ..() - -/obj/machinery/turretid/BorgAltClick(mob/living/silicon/robot/user) //turret lethal on/off. Forwards to AI code. - if(get_dist(src,user) <= user.interaction_range) - return AIAltClick() - return ..() - -/* - As with AI, these are not used in click code, - because the code for robots is specific, not generic. - - If you would like to add advanced features to robot - clicks, you can do so here, but you will have to - change attack_robot() above to the proper function -*/ -/mob/living/silicon/robot/UnarmedAttack(atom/A) - A.attack_robot(src) -/mob/living/silicon/robot/RangedAttack(atom/A) - A.attack_robot(src) - -/atom/proc/attack_robot(mob/user) - attack_ai(user) - return +/* + Cyborg ClickOn() + + Cyborgs have no range restriction on attack_robot(), because it is basically an AI click. + However, they do have a range restriction on item use, so they cannot do without the + adjacency code. +*/ + +/mob/living/silicon/robot/ClickOn(var/atom/A, var/params) + if(world.time <= next_click) + return + next_click = world.time + 1 + + if(check_click_intercept(params,A)) + return + + if(stat || lockcharge || IsKnockdown() || IsStun() || IsUnconscious()) + return + + var/list/modifiers = params2list(params) + if(modifiers["shift"] && modifiers["ctrl"]) + CtrlShiftClickOn(A) + return + if(modifiers["shift"] && modifiers["middle"]) + ShiftMiddleClickOn(A) + return + if(modifiers["middle"]) + MiddleClickOn(A) + return + if(modifiers["shift"]) + ShiftClickOn(A) + return + if(modifiers["alt"]) // alt and alt-gr (rightalt) + AltClickOn(A) + return + if(modifiers["ctrl"]) + CtrlClickOn(A) + return + + if(next_move >= world.time) + return + + face_atom(A) // change direction to face what you clicked on + + /* + cyborg restrained() currently does nothing + if(restrained()) + RestrainedClickOn(A) + return + */ + if(aicamera.in_camera_mode) //Cyborg picture taking + aicamera.camera_mode_off() + aicamera.captureimage(A, usr) + return + + var/obj/item/W = get_active_held_item() + + if(!W && A.Adjacent(src) && (isobj(A) || ismob(A))) + var/atom/movable/C = A + if(C.can_buckle && C.has_buckled_mobs()) + if(C.buckled_mobs.len > 1) + var/unbuckled = input(src, "Who do you wish to unbuckle?","Unbuckle Who?") as null|mob in C.buckled_mobs + if(C.user_unbuckle_mob(unbuckled,src)) + return + else + if(C.user_unbuckle_mob(C.buckled_mobs[1],src)) + return + + if(!W && get_dist(src,A) <= interaction_range) + A.attack_robot(src) + return + + if(W) + // buckled cannot prevent machine interlinking but stops arm movement + if( buckled || incapacitated()) + return + + if(W == A) + W.attack_self(src) + return + + // cyborgs are prohibited from using storage items so we can I think safely remove (A.loc in contents) + if(A == loc || (A in loc) || (A in contents)) + W.melee_attack_chain(src, A, params) + return + + if(!isturf(loc)) + return + + // cyborgs are prohibited from using storage items so we can I think safely remove (A.loc && isturf(A.loc.loc)) + if(isturf(A) || isturf(A.loc)) + if(A.Adjacent(src)) // see adjacent.dm + W.melee_attack_chain(src, A, params) + return + else + W.afterattack(A, src, 0, params) + return + +//Middle click cycles through selected modules. +/mob/living/silicon/robot/MiddleClickOn(atom/A) + cycle_modules() + return + +//Give cyborgs hotkey clicks without breaking existing uses of hotkey clicks +// for non-doors/apcs +/mob/living/silicon/robot/CtrlShiftClickOn(atom/A) + A.BorgCtrlShiftClick(src) +/mob/living/silicon/robot/ShiftClickOn(atom/A) + A.BorgShiftClick(src) +/mob/living/silicon/robot/CtrlClickOn(atom/A) + A.BorgCtrlClick(src) +/mob/living/silicon/robot/AltClickOn(atom/A) + if(!A.BorgAltClick(src)) + altclick_listed_turf(A) + +/atom/proc/BorgCtrlShiftClick(mob/living/silicon/robot/user) //forward to human click if not overridden + CtrlShiftClick(user) + +/obj/machinery/door/airlock/BorgCtrlShiftClick(mob/living/silicon/robot/user) // Sets/Unsets Emergency Access Override Forwards to AI code. + if(get_dist(src,user) <= user.interaction_range) + AICtrlShiftClick() + else + ..() + + +/atom/proc/BorgShiftClick(mob/living/silicon/robot/user) //forward to human click if not overridden + ShiftClick(user) + +/obj/machinery/door/airlock/BorgShiftClick(mob/living/silicon/robot/user) // Opens and closes doors! Forwards to AI code. + if(get_dist(src,user) <= user.interaction_range) + AIShiftClick() + else + ..() + + +/atom/proc/BorgCtrlClick(mob/living/silicon/robot/user) //forward to human click if not overridden + CtrlClick(user) + +/obj/machinery/door/airlock/BorgCtrlClick(mob/living/silicon/robot/user) // Bolts doors. Forwards to AI code. + if(get_dist(src,user) <= user.interaction_range) + AICtrlClick() + else + ..() + +/obj/machinery/power/apc/BorgCtrlClick(mob/living/silicon/robot/user) // turns off/on APCs. Forwards to AI code. + if(get_dist(src,user) <= user.interaction_range) + AICtrlClick() + else + ..() + +/obj/machinery/turretid/BorgCtrlClick(mob/living/silicon/robot/user) //turret control on/off. Forwards to AI code. + if(get_dist(src,user) <= user.interaction_range) + AICtrlClick() + else + ..() + +/atom/proc/BorgAltClick(mob/living/silicon/robot/user) + return AltClick(user) + +/obj/machinery/door/airlock/BorgAltClick(mob/living/silicon/robot/user) // Eletrifies doors. Forwards to AI code. + if(get_dist(src,user) <= user.interaction_range) + return AIAltClick() + return ..() + +/obj/machinery/turretid/BorgAltClick(mob/living/silicon/robot/user) //turret lethal on/off. Forwards to AI code. + if(get_dist(src,user) <= user.interaction_range) + return AIAltClick() + return ..() + +/* + As with AI, these are not used in click code, + because the code for robots is specific, not generic. + + If you would like to add advanced features to robot + clicks, you can do so here, but you will have to + change attack_robot() above to the proper function +*/ +/mob/living/silicon/robot/UnarmedAttack(atom/A) + A.attack_robot(src) +/mob/living/silicon/robot/RangedAttack(atom/A) + A.attack_robot(src) + +/atom/proc/attack_robot(mob/user) + attack_ai(user) + return diff --git a/code/_onclick/drag_drop.dm b/code/_onclick/drag_drop.dm index e5c0ffc1ab..dc18107a95 100644 --- a/code/_onclick/drag_drop.dm +++ b/code/_onclick/drag_drop.dm @@ -1,148 +1,148 @@ -/* - MouseDrop: - - Called on the atom you're dragging. In a lot of circumstances we want to use the - receiving object instead, so that's the default action. This allows you to drag - almost anything into a trash can. -*/ -/atom/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params) - if(!usr || !over) - return - if(SEND_SIGNAL(src, COMSIG_MOUSEDROP_ONTO, over, usr) & COMPONENT_NO_MOUSEDROP) //Whatever is receiving will verify themselves for adjacency. - return - if(over == src) - return usr.client.Click(src, src_location, src_control, params) - if(!Adjacent(usr) || !over.Adjacent(usr)) - return // should stop you from dragging through windows - - over.MouseDrop_T(src,usr) - return - -// receive a mousedrop -/atom/proc/MouseDrop_T(atom/dropping, mob/user) - SEND_SIGNAL(src, COMSIG_MOUSEDROPPED_ONTO, dropping, user) - return - - -/client - var/list/atom/selected_target[2] - var/obj/item/active_mousedown_item = null - var/mouseParams = "" - var/mouseLocation = null - var/mouseObject = null - var/mouseControlObject = null - var/middragtime = 0 - var/atom/middragatom - -/client/MouseDown(object, location, control, params) - if (mouse_down_icon) - mouse_pointer_icon = mouse_down_icon - var/delay = mob.CanMobAutoclick(object, location, params) - if(delay) - selected_target[1] = object - selected_target[2] = params - while(selected_target[1]) - Click(selected_target[1], location, control, selected_target[2]) - sleep(delay) - active_mousedown_item = mob.canMobMousedown(object, location, params) - if(active_mousedown_item) - active_mousedown_item.onMouseDown(object, location, params, mob) - -/client/MouseUp(object, location, control, params) - if (mouse_up_icon) - mouse_pointer_icon = mouse_up_icon - selected_target[1] = null - if(active_mousedown_item) - active_mousedown_item.onMouseUp(object, location, params, mob) - active_mousedown_item = null - -/mob/proc/CanMobAutoclick(object, location, params) - -/mob/living/carbon/CanMobAutoclick(atom/object, location, params) - if(!object.IsAutoclickable()) - return - var/obj/item/h = get_active_held_item() - if(h) - . = h.CanItemAutoclick(object, location, params) - -/mob/proc/canMobMousedown(atom/object, location, params) - -/mob/living/carbon/canMobMousedown(atom/object, location, params) - var/obj/item/H = get_active_held_item() - if(H) - . = H.canItemMouseDown(object, location, params) - -/obj/item/proc/CanItemAutoclick(object, location, params) - -/obj/item/proc/canItemMouseDown(object, location, params) - if(canMouseDown) - return src - -/obj/item/proc/onMouseDown(object, location, params, mob) - return - -/obj/item/proc/onMouseUp(object, location, params, mob) - return - -/obj/item - var/canMouseDown = FALSE - -/obj/item/gun - var/automatic = 0 //can gun use it, 0 is no, anything above 0 is the delay between clicks in ds - -/obj/item/gun/CanItemAutoclick(object, location, params) - . = automatic - -/atom/proc/IsAutoclickable() - . = 1 - -/obj/screen/IsAutoclickable() - . = 0 - -/obj/screen/click_catcher/IsAutoclickable() - . = 1 - -//Please don't roast me too hard -/client/MouseMove(object,location,control,params) - mouseParams = params - mouseLocation = location - mouseObject = object - mouseControlObject = control - if(mob && LAZYLEN(mob.mousemove_intercept_objects)) - for(var/datum/D in mob.mousemove_intercept_objects) - D.onMouseMove(object, location, control, params) - if(!show_popup_menus && mob) //CIT CHANGE - passes onmousemove() to mobs - mob.onMouseMove(object, location, control, params) //CIT CHANGE - ditto - ..() - -/datum/proc/onMouseMove(object, location, control, params) - return - -/client/MouseDrag(src_object,atom/over_object,src_location,over_location,src_control,over_control,params) - var/list/L = params2list(params) - if (L["middle"]) - if (src_object && src_location != over_location) - middragtime = world.time - middragatom = src_object - else - middragtime = 0 - middragatom = null - mouseParams = params - mouseLocation = over_location - mouseObject = over_object - mouseControlObject = over_control - if(selected_target[1] && over_object && over_object.IsAutoclickable()) - selected_target[1] = over_object - selected_target[2] = params - if(active_mousedown_item) - active_mousedown_item.onMouseDrag(src_object, over_object, src_location, over_location, params, mob) - - -/obj/item/proc/onMouseDrag(src_object, over_object, src_location, over_location, params, mob) - return - -/client/MouseDrop(src_object, over_object, src_location, over_location, src_control, over_control, params) - if (middragatom == src_object) - middragtime = 0 - middragatom = null +/* + MouseDrop: + + Called on the atom you're dragging. In a lot of circumstances we want to use the + receiving object instead, so that's the default action. This allows you to drag + almost anything into a trash can. +*/ +/atom/MouseDrop(atom/over, src_location, over_location, src_control, over_control, params) + if(!usr || !over) + return + if(SEND_SIGNAL(src, COMSIG_MOUSEDROP_ONTO, over, usr) & COMPONENT_NO_MOUSEDROP) //Whatever is receiving will verify themselves for adjacency. + return + if(over == src) + return usr.client.Click(src, src_location, src_control, params) + if(!Adjacent(usr) || !over.Adjacent(usr)) + return // should stop you from dragging through windows + + over.MouseDrop_T(src,usr) + return + +// receive a mousedrop +/atom/proc/MouseDrop_T(atom/dropping, mob/user) + SEND_SIGNAL(src, COMSIG_MOUSEDROPPED_ONTO, dropping, user) + return + + +/client + var/list/atom/selected_target[2] + var/obj/item/active_mousedown_item = null + var/mouseParams = "" + var/mouseLocation = null + var/mouseObject = null + var/mouseControlObject = null + var/middragtime = 0 + var/atom/middragatom + +/client/MouseDown(object, location, control, params) + if (mouse_down_icon) + mouse_pointer_icon = mouse_down_icon + var/delay = mob.CanMobAutoclick(object, location, params) + if(delay) + selected_target[1] = object + selected_target[2] = params + while(selected_target[1]) + Click(selected_target[1], location, control, selected_target[2]) + sleep(delay) + active_mousedown_item = mob.canMobMousedown(object, location, params) + if(active_mousedown_item) + active_mousedown_item.onMouseDown(object, location, params, mob) + +/client/MouseUp(object, location, control, params) + if (mouse_up_icon) + mouse_pointer_icon = mouse_up_icon + selected_target[1] = null + if(active_mousedown_item) + active_mousedown_item.onMouseUp(object, location, params, mob) + active_mousedown_item = null + +/mob/proc/CanMobAutoclick(object, location, params) + +/mob/living/carbon/CanMobAutoclick(atom/object, location, params) + if(!object.IsAutoclickable()) + return + var/obj/item/h = get_active_held_item() + if(h) + . = h.CanItemAutoclick(object, location, params) + +/mob/proc/canMobMousedown(atom/object, location, params) + +/mob/living/carbon/canMobMousedown(atom/object, location, params) + var/obj/item/H = get_active_held_item() + if(H) + . = H.canItemMouseDown(object, location, params) + +/obj/item/proc/CanItemAutoclick(object, location, params) + +/obj/item/proc/canItemMouseDown(object, location, params) + if(canMouseDown) + return src + +/obj/item/proc/onMouseDown(object, location, params, mob) + return + +/obj/item/proc/onMouseUp(object, location, params, mob) + return + +/obj/item + var/canMouseDown = FALSE + +/obj/item/gun + var/automatic = 0 //can gun use it, 0 is no, anything above 0 is the delay between clicks in ds + +/obj/item/gun/CanItemAutoclick(object, location, params) + . = automatic + +/atom/proc/IsAutoclickable() + . = 1 + +/obj/screen/IsAutoclickable() + . = 0 + +/obj/screen/click_catcher/IsAutoclickable() + . = 1 + +//Please don't roast me too hard +/client/MouseMove(object,location,control,params) + mouseParams = params + mouseLocation = location + mouseObject = object + mouseControlObject = control + if(mob && LAZYLEN(mob.mousemove_intercept_objects)) + for(var/datum/D in mob.mousemove_intercept_objects) + D.onMouseMove(object, location, control, params) + if(!show_popup_menus && mob) //CIT CHANGE - passes onmousemove() to mobs + mob.onMouseMove(object, location, control, params) //CIT CHANGE - ditto + ..() + +/datum/proc/onMouseMove(object, location, control, params) + return + +/client/MouseDrag(src_object,atom/over_object,src_location,over_location,src_control,over_control,params) + var/list/L = params2list(params) + if (L["middle"]) + if (src_object && src_location != over_location) + middragtime = world.time + middragatom = src_object + else + middragtime = 0 + middragatom = null + mouseParams = params + mouseLocation = over_location + mouseObject = over_object + mouseControlObject = over_control + if(selected_target[1] && over_object && over_object.IsAutoclickable()) + selected_target[1] = over_object + selected_target[2] = params + if(active_mousedown_item) + active_mousedown_item.onMouseDrag(src_object, over_object, src_location, over_location, params, mob) + + +/obj/item/proc/onMouseDrag(src_object, over_object, src_location, over_location, params, mob) + return + +/client/MouseDrop(src_object, over_object, src_location, over_location, src_control, over_control, params) + if (middragatom == src_object) + middragtime = 0 + middragatom = null ..() \ No newline at end of file diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index 9d53703cdd..12f7986357 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -1,165 +1,165 @@ -/* - These defines specificy screen locations. For more information, see the byond documentation on the screen_loc var. - - The short version: - - Everything is encoded as strings because apparently that's how Byond rolls. - - "1,1" is the bottom left square of the user's screen. This aligns perfectly with the turf grid. - "1:2,3:4" is the square (1,3) with pixel offsets (+2, +4); slightly right and slightly above the turf grid. - Pixel offsets are used so you don't perfectly hide the turf under them, that would be crappy. - - In addition, the keywords NORTH, SOUTH, EAST, WEST and CENTER can be used to represent their respective - screen borders. NORTH-1, for example, is the row just below the upper edge. Useful if you want your - UI to scale with screen size. - - The size of the user's screen is defined by client.view (indirectly by world.view), in our case "15x15". - Therefore, the top right corner (except during admin shenanigans) is at "15,15" -*/ - -//Lower left, persistent menu -#define ui_inventory "WEST:6,SOUTH:5" - -//Middle left indicators -#define ui_lingchemdisplay "WEST,CENTER-1:15" -#define ui_lingstingdisplay "WEST:6,CENTER-3:11" - -#define ui_devilsouldisplay "WEST:6,CENTER-1:15" - -//Lower center, persistent menu -#define ui_sstore1 "CENTER-5:10,SOUTH:5" -#define ui_id "CENTER-4:12,SOUTH:5" -#define ui_belt "CENTER-3:14,SOUTH:5" -#define ui_back "CENTER-2:14,SOUTH:5" - -/proc/ui_hand_position(i) //values based on old hand ui positions (CENTER:-/+16,SOUTH:5) - var/x_off = -(!(i % 2)) - var/y_off = round((i-1) / 2) - return"CENTER+[x_off]:16,SOUTH+[y_off]:5" - -/proc/ui_equip_position(mob/M) - var/y_off = round((M.held_items.len-1) / 2) //values based on old equip ui position (CENTER: +/-16,SOUTH+1:5) - return "CENTER:-16,SOUTH+[y_off+1]:5" - -/proc/ui_swaphand_position(mob/M, which = 1) //values based on old swaphand ui positions (CENTER: +/-16,SOUTH+1:5) - var/x_off = which == 1 ? -1 : 0 - var/y_off = round((M.held_items.len-1) / 2) - return "CENTER+[x_off]:16,SOUTH+[y_off+1]:5" - -#define ui_storage1 "CENTER+1:18,SOUTH:5" -#define ui_storage2 "CENTER+2:20,SOUTH:5" - -#define ui_borg_sensor "CENTER-3:15, SOUTH:5" //borgs -#define ui_borg_lamp "CENTER-4:15, SOUTH:5" //borgs -#define ui_borg_thrusters "CENTER-5:15, SOUTH:5" //borgs -#define ui_inv1 "CENTER-2:16,SOUTH:5" //borgs -#define ui_inv2 "CENTER-1 :16,SOUTH:5" //borgs -#define ui_inv3 "CENTER :16,SOUTH:5" //borgs -#define ui_borg_module "CENTER+1:16,SOUTH:5" //borgs -#define ui_borg_store "CENTER+2:16,SOUTH:5" //borgs -#define ui_borg_camera "CENTER+3:21,SOUTH:5" //borgs -#define ui_borg_album "CENTER+4:21,SOUTH:5" //borgs -#define ui_borg_language_menu "EAST-1:27,SOUTH+2:8" //borgs - -#define ui_monkey_head "CENTER-5:13,SOUTH:5" //monkey -#define ui_monkey_mask "CENTER-4:14,SOUTH:5" //monkey -#define ui_monkey_neck "CENTER-3:15,SOUTH:5" //monkey -#define ui_monkey_back "CENTER-2:16,SOUTH:5" //monkey - -//#define ui_alien_storage_l "CENTER-2:14,SOUTH:5"//alien -#define ui_alien_storage_r "CENTER+1:18,SOUTH:5"//alien -#define ui_alien_language_menu "EAST-3:26,SOUTH:5" //alien - -#define ui_drone_drop "CENTER+1:18,SOUTH:5" //maintenance drones -#define ui_drone_pull "CENTER+2:2,SOUTH:5" //maintenance drones -#define ui_drone_storage "CENTER-2:14,SOUTH:5" //maintenance drones -#define ui_drone_head "CENTER-3:14,SOUTH:5" //maintenance drones - -//Lower right, persistent menu -#define ui_drop_throw "EAST-1:28,SOUTH+1:7" -#define ui_pull_resist "EAST-2:26,SOUTH+1:7" -#define ui_movi "EAST-2:26,SOUTH:5" -#define ui_sprintbufferloc "EAST-2:26,SOUTH:18" -#define ui_acti "EAST-3:24,SOUTH:5" -#define ui_zonesel "EAST-1:28,SOUTH:5" -#define ui_acti_alt "EAST-1:28,SOUTH:5" //alternative intent switcher for when the interface is hidden (F12) -#define ui_crafting "EAST-5:20,SOUTH:5"//CIT CHANGE - moves this over one tile to accommodate for combat mode toggle -#define ui_building "EAST-5:20,SOUTH:21"//CIT CHANGE - ditto -#define ui_language_menu "EAST-5:4,SOUTH:21"//CIT CHANGE - ditto -#define ui_voremode "EAST-5:20,SOUTH:5" - -#define ui_borg_pull "EAST-2:26,SOUTH+1:7" -#define ui_borg_radio "EAST-1:28,SOUTH+1:7" -#define ui_borg_intents "EAST-2:26,SOUTH:5" - - -//Upper-middle right (alerts) -#define ui_alert1 "EAST-1:28,CENTER+5:27" -#define ui_alert2 "EAST-1:28,CENTER+4:25" -#define ui_alert3 "EAST-1:28,CENTER+3:23" -#define ui_alert4 "EAST-1:28,CENTER+2:21" -#define ui_alert5 "EAST-1:28,CENTER+1:19" - - -//Middle right (status indicators) -#define ui_healthdoll "EAST-1:28,CENTER-2:13" -#define ui_health "EAST-1:28,CENTER-1:15" -#define ui_internal "EAST-1:28,CENTER+1:19"//CIT CHANGE - moves internal icon up a little bit to accommodate for the stamina meter -#define ui_mood "EAST-1:28,CENTER-3:10" - -//living -#define ui_living_pull "EAST-1:28,CENTER-2:15" -#define ui_living_health "EAST-1:28,CENTER:15" - -//borgs -#define ui_borg_health "EAST-1:28,CENTER-1:15" //borgs have the health display where humans have the pressure damage indicator. - -//aliens -#define ui_alien_health "EAST,CENTER-1:15" //aliens have the health display where humans have the pressure damage indicator. -#define ui_alienplasmadisplay "EAST,CENTER-2:15" -#define ui_alien_queen_finder "EAST,CENTER-3:15" - -//constructs -#define ui_construct_pull "EAST,CENTER-2:15" -#define ui_construct_health "EAST,CENTER:15" //same as borgs and humans - -// AI - -#define ui_ai_core "SOUTH:6,WEST" -#define ui_ai_camera_list "SOUTH:6,WEST+1" -#define ui_ai_track_with_camera "SOUTH:6,WEST+2" -#define ui_ai_camera_light "SOUTH:6,WEST+3" -#define ui_ai_crew_monitor "SOUTH:6,WEST+4" -#define ui_ai_crew_manifest "SOUTH:6,WEST+5" -#define ui_ai_alerts "SOUTH:6,WEST+6" -#define ui_ai_announcement "SOUTH:6,WEST+7" -#define ui_ai_shuttle "SOUTH:6,WEST+8" -#define ui_ai_state_laws "SOUTH:6,WEST+9" -#define ui_ai_pda_send "SOUTH:6,WEST+10" -#define ui_ai_pda_log "SOUTH:6,WEST+11" -#define ui_ai_take_picture "SOUTH:6,WEST+12" -#define ui_ai_view_images "SOUTH:6,WEST+13" -#define ui_ai_sensor "SOUTH:6,WEST+14" -#define ui_ai_multicam "SOUTH+1:6,WEST+13" -#define ui_ai_add_multicam "SOUTH+1:6,WEST+14" - -//Pop-up inventory -#define ui_shoes "WEST+1:8,SOUTH:5" - -#define ui_iclothing "WEST:6,SOUTH+1:7" -#define ui_oclothing "WEST+1:8,SOUTH+1:7" -#define ui_gloves "WEST+2:10,SOUTH+1:7" - -#define ui_glasses "WEST:6,SOUTH+3:11" -#define ui_mask "WEST+1:8,SOUTH+2:9" -#define ui_ears "WEST+2:10,SOUTH+2:9" -#define ui_neck "WEST:6,SOUTH+2:9" -#define ui_head "WEST+1:8,SOUTH+3:11" - -//Ghosts - -#define ui_ghost_jumptomob "SOUTH:6,CENTER-2:24" -#define ui_ghost_orbit "SOUTH:6,CENTER-1:24" -#define ui_ghost_reenter_corpse "SOUTH:6,CENTER:24" -#define ui_ghost_teleport "SOUTH:6,CENTER+1:24" -#define ui_ghost_pai "SOUTH: 6, CENTER+2:24" +/* + These defines specificy screen locations. For more information, see the byond documentation on the screen_loc var. + + The short version: + + Everything is encoded as strings because apparently that's how Byond rolls. + + "1,1" is the bottom left square of the user's screen. This aligns perfectly with the turf grid. + "1:2,3:4" is the square (1,3) with pixel offsets (+2, +4); slightly right and slightly above the turf grid. + Pixel offsets are used so you don't perfectly hide the turf under them, that would be crappy. + + In addition, the keywords NORTH, SOUTH, EAST, WEST and CENTER can be used to represent their respective + screen borders. NORTH-1, for example, is the row just below the upper edge. Useful if you want your + UI to scale with screen size. + + The size of the user's screen is defined by client.view (indirectly by world.view), in our case "15x15". + Therefore, the top right corner (except during admin shenanigans) is at "15,15" +*/ + +//Lower left, persistent menu +#define ui_inventory "WEST:6,SOUTH:5" + +//Middle left indicators +#define ui_lingchemdisplay "WEST,CENTER-1:15" +#define ui_lingstingdisplay "WEST:6,CENTER-3:11" + +#define ui_devilsouldisplay "WEST:6,CENTER-1:15" + +//Lower center, persistent menu +#define ui_sstore1 "CENTER-5:10,SOUTH:5" +#define ui_id "CENTER-4:12,SOUTH:5" +#define ui_belt "CENTER-3:14,SOUTH:5" +#define ui_back "CENTER-2:14,SOUTH:5" + +/proc/ui_hand_position(i) //values based on old hand ui positions (CENTER:-/+16,SOUTH:5) + var/x_off = -(!(i % 2)) + var/y_off = round((i-1) / 2) + return"CENTER+[x_off]:16,SOUTH+[y_off]:5" + +/proc/ui_equip_position(mob/M) + var/y_off = round((M.held_items.len-1) / 2) //values based on old equip ui position (CENTER: +/-16,SOUTH+1:5) + return "CENTER:-16,SOUTH+[y_off+1]:5" + +/proc/ui_swaphand_position(mob/M, which = 1) //values based on old swaphand ui positions (CENTER: +/-16,SOUTH+1:5) + var/x_off = which == 1 ? -1 : 0 + var/y_off = round((M.held_items.len-1) / 2) + return "CENTER+[x_off]:16,SOUTH+[y_off+1]:5" + +#define ui_storage1 "CENTER+1:18,SOUTH:5" +#define ui_storage2 "CENTER+2:20,SOUTH:5" + +#define ui_borg_sensor "CENTER-3:15, SOUTH:5" //borgs +#define ui_borg_lamp "CENTER-4:15, SOUTH:5" //borgs +#define ui_borg_thrusters "CENTER-5:15, SOUTH:5" //borgs +#define ui_inv1 "CENTER-2:16,SOUTH:5" //borgs +#define ui_inv2 "CENTER-1 :16,SOUTH:5" //borgs +#define ui_inv3 "CENTER :16,SOUTH:5" //borgs +#define ui_borg_module "CENTER+1:16,SOUTH:5" //borgs +#define ui_borg_store "CENTER+2:16,SOUTH:5" //borgs +#define ui_borg_camera "CENTER+3:21,SOUTH:5" //borgs +#define ui_borg_album "CENTER+4:21,SOUTH:5" //borgs +#define ui_borg_language_menu "EAST-1:27,SOUTH+2:8" //borgs + +#define ui_monkey_head "CENTER-5:13,SOUTH:5" //monkey +#define ui_monkey_mask "CENTER-4:14,SOUTH:5" //monkey +#define ui_monkey_neck "CENTER-3:15,SOUTH:5" //monkey +#define ui_monkey_back "CENTER-2:16,SOUTH:5" //monkey + +//#define ui_alien_storage_l "CENTER-2:14,SOUTH:5"//alien +#define ui_alien_storage_r "CENTER+1:18,SOUTH:5"//alien +#define ui_alien_language_menu "EAST-3:26,SOUTH:5" //alien + +#define ui_drone_drop "CENTER+1:18,SOUTH:5" //maintenance drones +#define ui_drone_pull "CENTER+2:2,SOUTH:5" //maintenance drones +#define ui_drone_storage "CENTER-2:14,SOUTH:5" //maintenance drones +#define ui_drone_head "CENTER-3:14,SOUTH:5" //maintenance drones + +//Lower right, persistent menu +#define ui_drop_throw "EAST-1:28,SOUTH+1:7" +#define ui_pull_resist "EAST-2:26,SOUTH+1:7" +#define ui_movi "EAST-2:26,SOUTH:5" +#define ui_sprintbufferloc "EAST-2:26,SOUTH:18" +#define ui_acti "EAST-3:24,SOUTH:5" +#define ui_zonesel "EAST-1:28,SOUTH:5" +#define ui_acti_alt "EAST-1:28,SOUTH:5" //alternative intent switcher for when the interface is hidden (F12) +#define ui_crafting "EAST-5:20,SOUTH:5"//CIT CHANGE - moves this over one tile to accommodate for combat mode toggle +#define ui_building "EAST-5:20,SOUTH:21"//CIT CHANGE - ditto +#define ui_language_menu "EAST-5:4,SOUTH:21"//CIT CHANGE - ditto +#define ui_voremode "EAST-5:20,SOUTH:5" + +#define ui_borg_pull "EAST-2:26,SOUTH+1:7" +#define ui_borg_radio "EAST-1:28,SOUTH+1:7" +#define ui_borg_intents "EAST-2:26,SOUTH:5" + + +//Upper-middle right (alerts) +#define ui_alert1 "EAST-1:28,CENTER+5:27" +#define ui_alert2 "EAST-1:28,CENTER+4:25" +#define ui_alert3 "EAST-1:28,CENTER+3:23" +#define ui_alert4 "EAST-1:28,CENTER+2:21" +#define ui_alert5 "EAST-1:28,CENTER+1:19" + + +//Middle right (status indicators) +#define ui_healthdoll "EAST-1:28,CENTER-2:13" +#define ui_health "EAST-1:28,CENTER-1:15" +#define ui_internal "EAST-1:28,CENTER+1:19"//CIT CHANGE - moves internal icon up a little bit to accommodate for the stamina meter +#define ui_mood "EAST-1:28,CENTER-3:10" + +//living +#define ui_living_pull "EAST-1:28,CENTER-2:15" +#define ui_living_health "EAST-1:28,CENTER:15" + +//borgs +#define ui_borg_health "EAST-1:28,CENTER-1:15" //borgs have the health display where humans have the pressure damage indicator. + +//aliens +#define ui_alien_health "EAST,CENTER-1:15" //aliens have the health display where humans have the pressure damage indicator. +#define ui_alienplasmadisplay "EAST,CENTER-2:15" +#define ui_alien_queen_finder "EAST,CENTER-3:15" + +//constructs +#define ui_construct_pull "EAST,CENTER-2:15" +#define ui_construct_health "EAST,CENTER:15" //same as borgs and humans + +// AI + +#define ui_ai_core "SOUTH:6,WEST" +#define ui_ai_camera_list "SOUTH:6,WEST+1" +#define ui_ai_track_with_camera "SOUTH:6,WEST+2" +#define ui_ai_camera_light "SOUTH:6,WEST+3" +#define ui_ai_crew_monitor "SOUTH:6,WEST+4" +#define ui_ai_crew_manifest "SOUTH:6,WEST+5" +#define ui_ai_alerts "SOUTH:6,WEST+6" +#define ui_ai_announcement "SOUTH:6,WEST+7" +#define ui_ai_shuttle "SOUTH:6,WEST+8" +#define ui_ai_state_laws "SOUTH:6,WEST+9" +#define ui_ai_pda_send "SOUTH:6,WEST+10" +#define ui_ai_pda_log "SOUTH:6,WEST+11" +#define ui_ai_take_picture "SOUTH:6,WEST+12" +#define ui_ai_view_images "SOUTH:6,WEST+13" +#define ui_ai_sensor "SOUTH:6,WEST+14" +#define ui_ai_multicam "SOUTH+1:6,WEST+13" +#define ui_ai_add_multicam "SOUTH+1:6,WEST+14" + +//Pop-up inventory +#define ui_shoes "WEST+1:8,SOUTH:5" + +#define ui_iclothing "WEST:6,SOUTH+1:7" +#define ui_oclothing "WEST+1:8,SOUTH+1:7" +#define ui_gloves "WEST+2:10,SOUTH+1:7" + +#define ui_glasses "WEST:6,SOUTH+3:11" +#define ui_mask "WEST+1:8,SOUTH+2:9" +#define ui_ears "WEST+2:10,SOUTH+2:9" +#define ui_neck "WEST:6,SOUTH+2:9" +#define ui_head "WEST+1:8,SOUTH+3:11" + +//Ghosts + +#define ui_ghost_jumptomob "SOUTH:6,CENTER-2:24" +#define ui_ghost_orbit "SOUTH:6,CENTER-1:24" +#define ui_ghost_reenter_corpse "SOUTH:6,CENTER:24" +#define ui_ghost_teleport "SOUTH:6,CENTER+1:24" +#define ui_ghost_pai "SOUTH: 6, CENTER+2:24" diff --git a/code/_onclick/hud/credits.dm b/code/_onclick/hud/credits.dm index 702aa1cdcb..2cd0ddedaa 100644 --- a/code/_onclick/hud/credits.dm +++ b/code/_onclick/hud/credits.dm @@ -1,69 +1,69 @@ -#define CREDIT_ROLL_SPEED 125 -#define CREDIT_SPAWN_SPEED 10 -#define CREDIT_ANIMATE_HEIGHT (14 * world.icon_size) -#define CREDIT_EASE_DURATION 22 -#define CREDITS_PATH "[global.config.directory]/contributors.dmi" - -/client/proc/RollCredits() - set waitfor = FALSE - if(!fexists(CREDITS_PATH)) - return - var/icon/credits_icon = new(CREDITS_PATH) - LAZYINITLIST(credits) - var/list/_credits = credits - verbs += /client/proc/ClearCredits - var/static/list/credit_order_for_this_round - if(isnull(credit_order_for_this_round)) - credit_order_for_this_round = list("Thanks for playing!") + (shuffle(icon_states(credits_icon)) - "Thanks for playing!") - for(var/I in credit_order_for_this_round) - if(!credits) - return - _credits += new /obj/screen/credit(null, I, src, credits_icon) - sleep(CREDIT_SPAWN_SPEED) - sleep(CREDIT_ROLL_SPEED - CREDIT_SPAWN_SPEED) - verbs -= /client/proc/ClearCredits - qdel(credits_icon) - -/client/proc/ClearCredits() - set name = "Hide Credits" - set category = "OOC" - verbs -= /client/proc/ClearCredits - QDEL_LIST(credits) - credits = null - -/obj/screen/credit - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - alpha = 0 - screen_loc = "12,1" - layer = SPLASHSCREEN_LAYER - var/client/parent - var/matrix/target - -/obj/screen/credit/Initialize(mapload, credited, client/P, icon/I) - . = ..() - icon = I - parent = P - icon_state = credited - maptext = credited - maptext_x = world.icon_size + 8 - maptext_y = (world.icon_size / 2) - 4 - maptext_width = world.icon_size * 3 - var/matrix/M = matrix(transform) - M.Translate(0, CREDIT_ANIMATE_HEIGHT) - animate(src, transform = M, time = CREDIT_ROLL_SPEED) - target = M - animate(src, alpha = 255, time = CREDIT_EASE_DURATION, flags = ANIMATION_PARALLEL) - addtimer(CALLBACK(src, .proc/FadeOut), CREDIT_ROLL_SPEED - CREDIT_EASE_DURATION) - QDEL_IN(src, CREDIT_ROLL_SPEED) - P.screen += src - -/obj/screen/credit/Destroy() - var/client/P = parent - P.screen -= src - icon = null - LAZYREMOVE(P.credits, src) - parent = null - return ..() - -/obj/screen/credit/proc/FadeOut() - animate(src, alpha = 0, transform = target, time = CREDIT_EASE_DURATION) +#define CREDIT_ROLL_SPEED 125 +#define CREDIT_SPAWN_SPEED 10 +#define CREDIT_ANIMATE_HEIGHT (14 * world.icon_size) +#define CREDIT_EASE_DURATION 22 +#define CREDITS_PATH "[global.config.directory]/contributors.dmi" + +/client/proc/RollCredits() + set waitfor = FALSE + if(!fexists(CREDITS_PATH)) + return + var/icon/credits_icon = new(CREDITS_PATH) + LAZYINITLIST(credits) + var/list/_credits = credits + verbs += /client/proc/ClearCredits + var/static/list/credit_order_for_this_round + if(isnull(credit_order_for_this_round)) + credit_order_for_this_round = list("Thanks for playing!") + (shuffle(icon_states(credits_icon)) - "Thanks for playing!") + for(var/I in credit_order_for_this_round) + if(!credits) + return + _credits += new /obj/screen/credit(null, I, src, credits_icon) + sleep(CREDIT_SPAWN_SPEED) + sleep(CREDIT_ROLL_SPEED - CREDIT_SPAWN_SPEED) + verbs -= /client/proc/ClearCredits + qdel(credits_icon) + +/client/proc/ClearCredits() + set name = "Hide Credits" + set category = "OOC" + verbs -= /client/proc/ClearCredits + QDEL_LIST(credits) + credits = null + +/obj/screen/credit + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + alpha = 0 + screen_loc = "12,1" + layer = SPLASHSCREEN_LAYER + var/client/parent + var/matrix/target + +/obj/screen/credit/Initialize(mapload, credited, client/P, icon/I) + . = ..() + icon = I + parent = P + icon_state = credited + maptext = credited + maptext_x = world.icon_size + 8 + maptext_y = (world.icon_size / 2) - 4 + maptext_width = world.icon_size * 3 + var/matrix/M = matrix(transform) + M.Translate(0, CREDIT_ANIMATE_HEIGHT) + animate(src, transform = M, time = CREDIT_ROLL_SPEED) + target = M + animate(src, alpha = 255, time = CREDIT_EASE_DURATION, flags = ANIMATION_PARALLEL) + addtimer(CALLBACK(src, .proc/FadeOut), CREDIT_ROLL_SPEED - CREDIT_EASE_DURATION) + QDEL_IN(src, CREDIT_ROLL_SPEED) + P.screen += src + +/obj/screen/credit/Destroy() + var/client/P = parent + P.screen -= src + icon = null + LAZYREMOVE(P.credits, src) + parent = null + return ..() + +/obj/screen/credit/proc/FadeOut() + animate(src, alpha = 0, transform = target, time = CREDIT_EASE_DURATION) diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index a34a53125b..3cfa71e19d 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -1,181 +1,181 @@ - -/mob - var/list/screens = list() - -/mob/proc/overlay_fullscreen(category, type, severity) - var/obj/screen/fullscreen/screen = screens[category] - if (!screen || screen.type != type) - // needs to be recreated - clear_fullscreen(category, FALSE) - screens[category] = screen = new type() - else if ((!severity || severity == screen.severity) && (!client || screen.screen_loc != "CENTER-7,CENTER-7" || screen.view == client.view)) - // doesn't need to be updated - return screen - - screen.icon_state = "[initial(screen.icon_state)][severity]" - screen.severity = severity - if (client && screen.should_show_to(src)) - screen.update_for_view(client.view) - client.screen += screen - - return screen - -/mob/proc/clear_fullscreen(category, animated = 10) - var/obj/screen/fullscreen/screen = screens[category] - if(!screen) - return - - screens -= category - - if(animated) - animate(screen, alpha = 0, time = animated) - addtimer(CALLBACK(src, .proc/clear_fullscreen_after_animate, screen), animated, TIMER_CLIENT_TIME) - else - if(client) - client.screen -= screen - qdel(screen) - -/mob/proc/clear_fullscreen_after_animate(obj/screen/fullscreen/screen) - if(client) - client.screen -= screen - qdel(screen) - -/mob/proc/clear_fullscreens() - for(var/category in screens) - clear_fullscreen(category) - -/mob/proc/hide_fullscreens() - if(client) - for(var/category in screens) - client.screen -= screens[category] - -/mob/proc/reload_fullscreen() - if(client) - var/obj/screen/fullscreen/screen - for(var/category in screens) - screen = screens[category] - if(screen.should_show_to(src)) - screen.update_for_view(client.view) - client.screen |= screen - else - client.screen -= screen - -/obj/screen/fullscreen - icon = 'icons/mob/screen_full.dmi' - icon_state = "default" - screen_loc = "CENTER-7,CENTER-7" - layer = FULLSCREEN_LAYER - plane = FULLSCREEN_PLANE - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - var/view = 7 - var/severity = 0 - var/show_when_dead = FALSE - -/obj/screen/fullscreen/proc/update_for_view(client_view) - if (screen_loc == "CENTER-7,CENTER-7" && view != client_view) - var/list/actualview = getviewsize(client_view) - view = client_view - transform = matrix(actualview[1]/FULLSCREEN_OVERLAY_RESOLUTION_X, 0, 0, 0, actualview[2]/FULLSCREEN_OVERLAY_RESOLUTION_Y, 0) - -/obj/screen/fullscreen/proc/should_show_to(mob/mymob) - if(!show_when_dead && mymob.stat == DEAD) - return FALSE - return TRUE - -/obj/screen/fullscreen/Destroy() - severity = 0 - . = ..() - -/obj/screen/fullscreen/brute - icon_state = "brutedamageoverlay" - layer = UI_DAMAGE_LAYER - plane = FULLSCREEN_PLANE - -/obj/screen/fullscreen/oxy - icon_state = "oxydamageoverlay" - layer = UI_DAMAGE_LAYER - plane = FULLSCREEN_PLANE - -/obj/screen/fullscreen/crit - icon_state = "passage" - layer = CRIT_LAYER - plane = FULLSCREEN_PLANE - -/obj/screen/fullscreen/crit/vision - icon_state = "oxydamageoverlay" - layer = BLIND_LAYER - -/obj/screen/fullscreen/blind - icon_state = "blackimageoverlay" - layer = BLIND_LAYER - plane = FULLSCREEN_PLANE - -/obj/screen/fullscreen/curse - icon_state = "curse" - layer = CURSE_LAYER - plane = FULLSCREEN_PLANE - -/obj/screen/fullscreen/impaired - icon_state = "impairedoverlay" - -/obj/screen/fullscreen/blurry - icon = 'icons/mob/screen_gen.dmi' - screen_loc = "WEST,SOUTH to EAST,NORTH" - icon_state = "blurry" - -/obj/screen/fullscreen/flash - icon = 'icons/mob/screen_gen.dmi' - screen_loc = "WEST,SOUTH to EAST,NORTH" - icon_state = "flash" - -/obj/screen/fullscreen/flash/static - icon = 'icons/mob/screen_gen.dmi' - screen_loc = "WEST,SOUTH to EAST,NORTH" - icon_state = "noise" - -/obj/screen/fullscreen/high - icon = 'icons/mob/screen_gen.dmi' - screen_loc = "WEST,SOUTH to EAST,NORTH" - icon_state = "druggy" - -/obj/screen/fullscreen/color_vision - icon = 'icons/mob/screen_gen.dmi' - screen_loc = "WEST,SOUTH to EAST,NORTH" - icon_state = "flash" - alpha = 80 - -/obj/screen/fullscreen/color_vision/green - color = "#00ff00" - -/obj/screen/fullscreen/color_vision/red - color = "#ff0000" - -/obj/screen/fullscreen/color_vision/blue - color = "#0000ff" - -/obj/screen/fullscreen/lighting_backdrop - icon = 'icons/mob/screen_gen.dmi' - icon_state = "flash" - transform = matrix(200, 0, 0, 0, 200, 0) - plane = LIGHTING_PLANE - blend_mode = BLEND_OVERLAY - show_when_dead = TRUE - -//Provides darkness to the back of the lighting plane -/obj/screen/fullscreen/lighting_backdrop/lit - invisibility = INVISIBILITY_LIGHTING - layer = BACKGROUND_LAYER+21 - color = "#000" - show_when_dead = TRUE - -//Provides whiteness in case you don't see lights so everything is still visible -/obj/screen/fullscreen/lighting_backdrop/unlit - layer = BACKGROUND_LAYER+20 - show_when_dead = TRUE - -/obj/screen/fullscreen/see_through_darkness - icon_state = "nightvision" - plane = LIGHTING_PLANE - layer = LIGHTING_LAYER - blend_mode = BLEND_ADD - show_when_dead = TRUE + +/mob + var/list/screens = list() + +/mob/proc/overlay_fullscreen(category, type, severity) + var/obj/screen/fullscreen/screen = screens[category] + if (!screen || screen.type != type) + // needs to be recreated + clear_fullscreen(category, FALSE) + screens[category] = screen = new type() + else if ((!severity || severity == screen.severity) && (!client || screen.screen_loc != "CENTER-7,CENTER-7" || screen.view == client.view)) + // doesn't need to be updated + return screen + + screen.icon_state = "[initial(screen.icon_state)][severity]" + screen.severity = severity + if (client && screen.should_show_to(src)) + screen.update_for_view(client.view) + client.screen += screen + + return screen + +/mob/proc/clear_fullscreen(category, animated = 10) + var/obj/screen/fullscreen/screen = screens[category] + if(!screen) + return + + screens -= category + + if(animated) + animate(screen, alpha = 0, time = animated) + addtimer(CALLBACK(src, .proc/clear_fullscreen_after_animate, screen), animated, TIMER_CLIENT_TIME) + else + if(client) + client.screen -= screen + qdel(screen) + +/mob/proc/clear_fullscreen_after_animate(obj/screen/fullscreen/screen) + if(client) + client.screen -= screen + qdel(screen) + +/mob/proc/clear_fullscreens() + for(var/category in screens) + clear_fullscreen(category) + +/mob/proc/hide_fullscreens() + if(client) + for(var/category in screens) + client.screen -= screens[category] + +/mob/proc/reload_fullscreen() + if(client) + var/obj/screen/fullscreen/screen + for(var/category in screens) + screen = screens[category] + if(screen.should_show_to(src)) + screen.update_for_view(client.view) + client.screen |= screen + else + client.screen -= screen + +/obj/screen/fullscreen + icon = 'icons/mob/screen_full.dmi' + icon_state = "default" + screen_loc = "CENTER-7,CENTER-7" + layer = FULLSCREEN_LAYER + plane = FULLSCREEN_PLANE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + var/view = 7 + var/severity = 0 + var/show_when_dead = FALSE + +/obj/screen/fullscreen/proc/update_for_view(client_view) + if (screen_loc == "CENTER-7,CENTER-7" && view != client_view) + var/list/actualview = getviewsize(client_view) + view = client_view + transform = matrix(actualview[1]/FULLSCREEN_OVERLAY_RESOLUTION_X, 0, 0, 0, actualview[2]/FULLSCREEN_OVERLAY_RESOLUTION_Y, 0) + +/obj/screen/fullscreen/proc/should_show_to(mob/mymob) + if(!show_when_dead && mymob.stat == DEAD) + return FALSE + return TRUE + +/obj/screen/fullscreen/Destroy() + severity = 0 + . = ..() + +/obj/screen/fullscreen/brute + icon_state = "brutedamageoverlay" + layer = UI_DAMAGE_LAYER + plane = FULLSCREEN_PLANE + +/obj/screen/fullscreen/oxy + icon_state = "oxydamageoverlay" + layer = UI_DAMAGE_LAYER + plane = FULLSCREEN_PLANE + +/obj/screen/fullscreen/crit + icon_state = "passage" + layer = CRIT_LAYER + plane = FULLSCREEN_PLANE + +/obj/screen/fullscreen/crit/vision + icon_state = "oxydamageoverlay" + layer = BLIND_LAYER + +/obj/screen/fullscreen/blind + icon_state = "blackimageoverlay" + layer = BLIND_LAYER + plane = FULLSCREEN_PLANE + +/obj/screen/fullscreen/curse + icon_state = "curse" + layer = CURSE_LAYER + plane = FULLSCREEN_PLANE + +/obj/screen/fullscreen/impaired + icon_state = "impairedoverlay" + +/obj/screen/fullscreen/blurry + icon = 'icons/mob/screen_gen.dmi' + screen_loc = "WEST,SOUTH to EAST,NORTH" + icon_state = "blurry" + +/obj/screen/fullscreen/flash + icon = 'icons/mob/screen_gen.dmi' + screen_loc = "WEST,SOUTH to EAST,NORTH" + icon_state = "flash" + +/obj/screen/fullscreen/flash/static + icon = 'icons/mob/screen_gen.dmi' + screen_loc = "WEST,SOUTH to EAST,NORTH" + icon_state = "noise" + +/obj/screen/fullscreen/high + icon = 'icons/mob/screen_gen.dmi' + screen_loc = "WEST,SOUTH to EAST,NORTH" + icon_state = "druggy" + +/obj/screen/fullscreen/color_vision + icon = 'icons/mob/screen_gen.dmi' + screen_loc = "WEST,SOUTH to EAST,NORTH" + icon_state = "flash" + alpha = 80 + +/obj/screen/fullscreen/color_vision/green + color = "#00ff00" + +/obj/screen/fullscreen/color_vision/red + color = "#ff0000" + +/obj/screen/fullscreen/color_vision/blue + color = "#0000ff" + +/obj/screen/fullscreen/lighting_backdrop + icon = 'icons/mob/screen_gen.dmi' + icon_state = "flash" + transform = matrix(200, 0, 0, 0, 200, 0) + plane = LIGHTING_PLANE + blend_mode = BLEND_OVERLAY + show_when_dead = TRUE + +//Provides darkness to the back of the lighting plane +/obj/screen/fullscreen/lighting_backdrop/lit + invisibility = INVISIBILITY_LIGHTING + layer = BACKGROUND_LAYER+21 + color = "#000" + show_when_dead = TRUE + +//Provides whiteness in case you don't see lights so everything is still visible +/obj/screen/fullscreen/lighting_backdrop/unlit + layer = BACKGROUND_LAYER+20 + show_when_dead = TRUE + +/obj/screen/fullscreen/see_through_darkness + icon_state = "nightvision" + plane = LIGHTING_PLANE + layer = LIGHTING_LAYER + blend_mode = BLEND_ADD + show_when_dead = TRUE diff --git a/code/_onclick/hud/ghost.dm b/code/_onclick/hud/ghost.dm index 549b6346ce..14da637f18 100644 --- a/code/_onclick/hud/ghost.dm +++ b/code/_onclick/hud/ghost.dm @@ -1,95 +1,95 @@ -/obj/screen/ghost - icon = 'icons/mob/screen_ghost.dmi' - -/obj/screen/ghost/MouseEntered() - flick(icon_state + "_anim", src) - -/obj/screen/ghost/jumptomob - name = "Jump to mob" - icon_state = "jumptomob" - -/obj/screen/ghost/jumptomob/Click() - var/mob/dead/observer/G = usr - G.jumptomob() - -/obj/screen/ghost/orbit - name = "Orbit" - icon_state = "orbit" - -/obj/screen/ghost/orbit/Click() - var/mob/dead/observer/G = usr - G.follow() - -/obj/screen/ghost/reenter_corpse - name = "Reenter corpse" - icon_state = "reenter_corpse" - -/obj/screen/ghost/reenter_corpse/Click() - var/mob/dead/observer/G = usr - G.reenter_corpse() - -/obj/screen/ghost/teleport - name = "Teleport" - icon_state = "teleport" - -/obj/screen/ghost/teleport/Click() - var/mob/dead/observer/G = usr - G.dead_tele() - -/obj/screen/ghost/pai - name = "pAI Candidate" - icon_state = "pai" - -/obj/screen/ghost/pai/Click() - var/mob/dead/observer/G = usr - G.register_pai() - -/datum/hud/ghost/New(mob/owner) - ..() - var/obj/screen/using - - using = new /obj/screen/ghost/jumptomob() - using.screen_loc = ui_ghost_jumptomob - using.hud = src - static_inventory += using - - using = new /obj/screen/ghost/orbit() - using.screen_loc = ui_ghost_orbit - using.hud = src - static_inventory += using - - using = new /obj/screen/ghost/reenter_corpse() - using.screen_loc = ui_ghost_reenter_corpse - using.hud = src - static_inventory += using - - using = new /obj/screen/ghost/teleport() - using.screen_loc = ui_ghost_teleport - using.hud = src - static_inventory += using - - using = new /obj/screen/ghost/pai() - using.screen_loc = ui_ghost_pai - using.hud = src - static_inventory += using - - using = new /obj/screen/language_menu - using.icon = ui_style - using.hud = src - static_inventory += using - -/datum/hud/ghost/show_hud(version = 0, mob/viewmob) - // don't show this HUD if observing; show the HUD of the observee - var/mob/dead/observer/O = mymob - if (istype(O) && O.observetarget) - plane_masters_update() - return FALSE - - . = ..() - if(!.) - return - var/mob/screenmob = viewmob || mymob - if(!screenmob.client.prefs.ghost_hud) - screenmob.client.screen -= static_inventory - else - screenmob.client.screen += static_inventory +/obj/screen/ghost + icon = 'icons/mob/screen_ghost.dmi' + +/obj/screen/ghost/MouseEntered() + flick(icon_state + "_anim", src) + +/obj/screen/ghost/jumptomob + name = "Jump to mob" + icon_state = "jumptomob" + +/obj/screen/ghost/jumptomob/Click() + var/mob/dead/observer/G = usr + G.jumptomob() + +/obj/screen/ghost/orbit + name = "Orbit" + icon_state = "orbit" + +/obj/screen/ghost/orbit/Click() + var/mob/dead/observer/G = usr + G.follow() + +/obj/screen/ghost/reenter_corpse + name = "Reenter corpse" + icon_state = "reenter_corpse" + +/obj/screen/ghost/reenter_corpse/Click() + var/mob/dead/observer/G = usr + G.reenter_corpse() + +/obj/screen/ghost/teleport + name = "Teleport" + icon_state = "teleport" + +/obj/screen/ghost/teleport/Click() + var/mob/dead/observer/G = usr + G.dead_tele() + +/obj/screen/ghost/pai + name = "pAI Candidate" + icon_state = "pai" + +/obj/screen/ghost/pai/Click() + var/mob/dead/observer/G = usr + G.register_pai() + +/datum/hud/ghost/New(mob/owner) + ..() + var/obj/screen/using + + using = new /obj/screen/ghost/jumptomob() + using.screen_loc = ui_ghost_jumptomob + using.hud = src + static_inventory += using + + using = new /obj/screen/ghost/orbit() + using.screen_loc = ui_ghost_orbit + using.hud = src + static_inventory += using + + using = new /obj/screen/ghost/reenter_corpse() + using.screen_loc = ui_ghost_reenter_corpse + using.hud = src + static_inventory += using + + using = new /obj/screen/ghost/teleport() + using.screen_loc = ui_ghost_teleport + using.hud = src + static_inventory += using + + using = new /obj/screen/ghost/pai() + using.screen_loc = ui_ghost_pai + using.hud = src + static_inventory += using + + using = new /obj/screen/language_menu + using.icon = ui_style + using.hud = src + static_inventory += using + +/datum/hud/ghost/show_hud(version = 0, mob/viewmob) + // don't show this HUD if observing; show the HUD of the observee + var/mob/dead/observer/O = mymob + if (istype(O) && O.observetarget) + plane_masters_update() + return FALSE + + . = ..() + if(!.) + return + var/mob/screenmob = viewmob || mymob + if(!screenmob.client.prefs.ghost_hud) + screenmob.client.screen -= static_inventory + else + screenmob.client.screen += static_inventory diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 09794444d1..f8df958eea 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -1,297 +1,297 @@ -/* - The hud datum - Used to show and hide huds for all the different mob types, - including inventories and item quick actions. -*/ - -// The default UI style is the first one in the list -GLOBAL_LIST_INIT(available_ui_styles, list( - "Midnight" = 'icons/mob/screen_midnight.dmi', - "Retro" = 'icons/mob/screen_retro.dmi', - "Plasmafire" = 'icons/mob/screen_plasmafire.dmi', - "Slimecore" = 'icons/mob/screen_slimecore.dmi', - "Operative" = 'icons/mob/screen_operative.dmi', - "Clockwork" = 'icons/mob/screen_clockwork.dmi' -)) - -/proc/ui_style2icon(ui_style) - return GLOB.available_ui_styles[ui_style] || GLOB.available_ui_styles[GLOB.available_ui_styles[1]] - -/datum/hud - var/mob/mymob - - var/hud_shown = TRUE //Used for the HUD toggle (F12) - var/hud_version = HUD_STYLE_STANDARD //Current displayed version of the HUD - var/inventory_shown = FALSE //Equipped item inventory - var/hotkey_ui_hidden = FALSE //This is to hide the buttons that can be used via hotkeys. (hotkeybuttons list of buttons) - - var/obj/screen/ling/chems/lingchemdisplay - var/obj/screen/ling/sting/lingstingdisplay - - var/obj/screen/blobpwrdisplay - - var/obj/screen/alien_plasma_display - var/obj/screen/alien_queen_finder - - var/obj/screen/devil/soul_counter/devilsouldisplay - - var/obj/screen/action_intent - var/obj/screen/zone_select - var/obj/screen/pull_icon - var/obj/screen/rest_icon - var/obj/screen/throw_icon - var/obj/screen/module_store_icon - - var/list/static_inventory = list() //the screen objects which are static - var/list/toggleable_inventory = list() //the screen objects which can be hidden - var/list/obj/screen/hotkeybuttons = list() //the buttons that can be used via hotkeys - var/list/infodisplay = list() //the screen objects that display mob info (health, alien plasma, etc...) - var/list/screenoverlays = list() //the screen objects used as whole screen overlays (flash, damageoverlay, etc...) - var/list/inv_slots[SLOTS_AMT] // /obj/screen/inventory objects, ordered by their slot ID. - var/list/hand_slots // /obj/screen/inventory/hand objects, assoc list of "[held_index]" = object - var/list/obj/screen/plane_master/plane_masters = list() // see "appearance_flags" in the ref, assoc list of "[plane]" = object - - var/obj/screen/movable/action_button/hide_toggle/hide_actions_toggle - var/action_buttons_hidden = FALSE - - var/obj/screen/healths - var/obj/screen/healthdoll - var/obj/screen/internals - - // subtypes can override this to force a specific UI style - var/ui_style - - //Citadel stuff - var/obj/screen/arousal - -/datum/hud/New(mob/owner) - mymob = owner - - if (!ui_style) - // will fall back to the default if any of these are null - ui_style = ui_style2icon(owner.client && owner.client.prefs && owner.client.prefs.UI_style) - - hide_actions_toggle = new - hide_actions_toggle.InitialiseIcon(src) - if(mymob.client) - hide_actions_toggle.locked = mymob.client.prefs.buttons_locked - - hand_slots = list() - - for(var/mytype in subtypesof(/obj/screen/plane_master)) - var/obj/screen/plane_master/instance = new mytype() - plane_masters["[instance.plane]"] = instance - instance.backdrop(mymob) - -/datum/hud/Destroy() - if(mymob.hud_used == src) - mymob.hud_used = null - - QDEL_NULL(hide_actions_toggle) - QDEL_NULL(module_store_icon) - QDEL_LIST(static_inventory) - - inv_slots.Cut() - action_intent = null - zone_select = null - pull_icon = null - - QDEL_LIST(toggleable_inventory) - QDEL_LIST(hotkeybuttons) - throw_icon = null - QDEL_LIST(infodisplay) - - healths = null - healthdoll = null - internals = null - lingchemdisplay = null - devilsouldisplay = null - lingstingdisplay = null - blobpwrdisplay = null - alien_plasma_display = null - alien_queen_finder = null - - QDEL_LIST_ASSOC_VAL(plane_masters) - QDEL_LIST(screenoverlays) - mymob = null - - return ..() - -/mob - var/hud_type = /datum/hud - -/mob/proc/create_mob_hud() - if(!client || hud_used) - return - hud_used = new hud_type(src) - update_sight() - SEND_SIGNAL(src, COMSIG_MOB_HUD_CREATED) - -//Version denotes which style should be displayed. blank or 0 means "next version" -/datum/hud/proc/show_hud(version = 0, mob/viewmob) - if(!ismob(mymob)) - return FALSE - var/mob/screenmob = viewmob || mymob - if(!screenmob.client) - return FALSE - - screenmob.client.screen = list() - screenmob.client.apply_clickcatcher() - - var/display_hud_version = version - if(!display_hud_version) //If 0 or blank, display the next hud version - display_hud_version = hud_version + 1 - if(display_hud_version > HUD_VERSIONS) //If the requested version number is greater than the available versions, reset back to the first version - display_hud_version = 1 - - switch(display_hud_version) - if(HUD_STYLE_STANDARD) //Default HUD - hud_shown = TRUE //Governs behavior of other procs - if(static_inventory.len) - screenmob.client.screen += static_inventory - if(toggleable_inventory.len && screenmob.hud_used && screenmob.hud_used.inventory_shown) - screenmob.client.screen += toggleable_inventory - if(hotkeybuttons.len && !hotkey_ui_hidden) - screenmob.client.screen += hotkeybuttons - if(infodisplay.len) - screenmob.client.screen += infodisplay - - screenmob.client.screen += hide_actions_toggle - - if(action_intent) - action_intent.screen_loc = initial(action_intent.screen_loc) //Restore intent selection to the original position - - if(HUD_STYLE_REDUCED) //Reduced HUD - hud_shown = FALSE //Governs behavior of other procs - if(static_inventory.len) - screenmob.client.screen -= static_inventory - if(toggleable_inventory.len) - screenmob.client.screen -= toggleable_inventory - if(hotkeybuttons.len) - screenmob.client.screen -= hotkeybuttons - if(infodisplay.len) - screenmob.client.screen += infodisplay - - //These ones are a part of 'static_inventory', 'toggleable_inventory' or 'hotkeybuttons' but we want them to stay - for(var/h in hand_slots) - var/obj/screen/hand = hand_slots[h] - if(hand) - screenmob.client.screen += hand - if(action_intent) - screenmob.client.screen += action_intent //we want the intent switcher visible - action_intent.screen_loc = ui_acti_alt //move this to the alternative position, where zone_select usually is. - - if(HUD_STYLE_NOHUD) //No HUD - hud_shown = FALSE //Governs behavior of other procs - if(static_inventory.len) - screenmob.client.screen -= static_inventory - if(toggleable_inventory.len) - screenmob.client.screen -= toggleable_inventory - if(hotkeybuttons.len) - screenmob.client.screen -= hotkeybuttons - if(infodisplay.len) - screenmob.client.screen -= infodisplay - - hud_version = display_hud_version - persistent_inventory_update(screenmob) - screenmob.update_action_buttons(1) - reorganize_alerts() - screenmob.reload_fullscreen() - update_parallax_pref(screenmob) - - // ensure observers get an accurate and up-to-date view - if (!viewmob) - plane_masters_update() - for(var/M in mymob.observers) - show_hud(hud_version, M) - else if (viewmob.hud_used) - viewmob.hud_used.plane_masters_update() - - return TRUE - -/datum/hud/proc/plane_masters_update() - // Plane masters are always shown to OUR mob, never to observers - for(var/thing in plane_masters) - var/obj/screen/plane_master/PM = plane_masters[thing] - PM.backdrop(mymob) - mymob.client.screen += PM - -/datum/hud/human/show_hud(version = 0,mob/viewmob) - . = ..() - if(!.) - return - var/mob/screenmob = viewmob || mymob - hidden_inventory_update(screenmob) - -/datum/hud/robot/show_hud(version = 0, mob/viewmob) - . = ..() - if(!.) - return - update_robot_modules_display() - -/datum/hud/proc/hidden_inventory_update() - return - -/datum/hud/proc/persistent_inventory_update(mob/viewer) - if(!mymob) - return - -/datum/hud/proc/update_ui_style(new_ui_style) - // do nothing if overridden by a subtype or already on that style - if (initial(ui_style) || ui_style == new_ui_style) - return - - for(var/atom/item in static_inventory + toggleable_inventory + hotkeybuttons + infodisplay + screenoverlays + inv_slots) - if (item.icon == ui_style) - item.icon = new_ui_style - - ui_style = new_ui_style - build_hand_slots() - hide_actions_toggle.InitialiseIcon(src) - -//Triggered when F12 is pressed (Unless someone changed something in the DMF) -/mob/verb/button_pressed_F12() - set name = "F12" - set hidden = TRUE - - if(hud_used && client) - hud_used.show_hud() //Shows the next hud preset - to_chat(usr, "Switched HUD mode. Press F12 to toggle.") - else - to_chat(usr, "This mob type does not use a HUD.") - - -//(re)builds the hand ui slots, throwing away old ones -//not really worth jugglying existing ones so we just scrap+rebuild -//9/10 this is only called once per mob and only for 2 hands -/datum/hud/proc/build_hand_slots() - for(var/h in hand_slots) - var/obj/screen/inventory/hand/H = hand_slots[h] - if(H) - static_inventory -= H - hand_slots = list() - var/obj/screen/inventory/hand/hand_box - for(var/i in 1 to mymob.held_items.len) - hand_box = new /obj/screen/inventory/hand() - hand_box.name = mymob.get_held_index_name(i) - hand_box.icon = ui_style - hand_box.icon_state = "hand_[mymob.held_index_to_dir(i)]" - hand_box.screen_loc = ui_hand_position(i) - hand_box.held_index = i - hand_slots["[i]"] = hand_box - hand_box.hud = src - static_inventory += hand_box - hand_box.update_icon() - - var/i = 1 - for(var/obj/screen/swap_hand/SH in static_inventory) - SH.screen_loc = ui_swaphand_position(mymob,!(i % 2) ? 2: 1) - i++ - for(var/obj/screen/human/equip/E in static_inventory) - E.screen_loc = ui_equip_position(mymob) - - if(ismob(mymob) && mymob.hud_used == src) - show_hud(hud_version) - -/datum/hud/proc/update_locked_slots() - return +/* + The hud datum + Used to show and hide huds for all the different mob types, + including inventories and item quick actions. +*/ + +// The default UI style is the first one in the list +GLOBAL_LIST_INIT(available_ui_styles, list( + "Midnight" = 'icons/mob/screen_midnight.dmi', + "Retro" = 'icons/mob/screen_retro.dmi', + "Plasmafire" = 'icons/mob/screen_plasmafire.dmi', + "Slimecore" = 'icons/mob/screen_slimecore.dmi', + "Operative" = 'icons/mob/screen_operative.dmi', + "Clockwork" = 'icons/mob/screen_clockwork.dmi' +)) + +/proc/ui_style2icon(ui_style) + return GLOB.available_ui_styles[ui_style] || GLOB.available_ui_styles[GLOB.available_ui_styles[1]] + +/datum/hud + var/mob/mymob + + var/hud_shown = TRUE //Used for the HUD toggle (F12) + var/hud_version = HUD_STYLE_STANDARD //Current displayed version of the HUD + var/inventory_shown = FALSE //Equipped item inventory + var/hotkey_ui_hidden = FALSE //This is to hide the buttons that can be used via hotkeys. (hotkeybuttons list of buttons) + + var/obj/screen/ling/chems/lingchemdisplay + var/obj/screen/ling/sting/lingstingdisplay + + var/obj/screen/blobpwrdisplay + + var/obj/screen/alien_plasma_display + var/obj/screen/alien_queen_finder + + var/obj/screen/devil/soul_counter/devilsouldisplay + + var/obj/screen/action_intent + var/obj/screen/zone_select + var/obj/screen/pull_icon + var/obj/screen/rest_icon + var/obj/screen/throw_icon + var/obj/screen/module_store_icon + + var/list/static_inventory = list() //the screen objects which are static + var/list/toggleable_inventory = list() //the screen objects which can be hidden + var/list/obj/screen/hotkeybuttons = list() //the buttons that can be used via hotkeys + var/list/infodisplay = list() //the screen objects that display mob info (health, alien plasma, etc...) + var/list/screenoverlays = list() //the screen objects used as whole screen overlays (flash, damageoverlay, etc...) + var/list/inv_slots[SLOTS_AMT] // /obj/screen/inventory objects, ordered by their slot ID. + var/list/hand_slots // /obj/screen/inventory/hand objects, assoc list of "[held_index]" = object + var/list/obj/screen/plane_master/plane_masters = list() // see "appearance_flags" in the ref, assoc list of "[plane]" = object + + var/obj/screen/movable/action_button/hide_toggle/hide_actions_toggle + var/action_buttons_hidden = FALSE + + var/obj/screen/healths + var/obj/screen/healthdoll + var/obj/screen/internals + + // subtypes can override this to force a specific UI style + var/ui_style + + //Citadel stuff + var/obj/screen/arousal + +/datum/hud/New(mob/owner) + mymob = owner + + if (!ui_style) + // will fall back to the default if any of these are null + ui_style = ui_style2icon(owner.client && owner.client.prefs && owner.client.prefs.UI_style) + + hide_actions_toggle = new + hide_actions_toggle.InitialiseIcon(src) + if(mymob.client) + hide_actions_toggle.locked = mymob.client.prefs.buttons_locked + + hand_slots = list() + + for(var/mytype in subtypesof(/obj/screen/plane_master)) + var/obj/screen/plane_master/instance = new mytype() + plane_masters["[instance.plane]"] = instance + instance.backdrop(mymob) + +/datum/hud/Destroy() + if(mymob.hud_used == src) + mymob.hud_used = null + + QDEL_NULL(hide_actions_toggle) + QDEL_NULL(module_store_icon) + QDEL_LIST(static_inventory) + + inv_slots.Cut() + action_intent = null + zone_select = null + pull_icon = null + + QDEL_LIST(toggleable_inventory) + QDEL_LIST(hotkeybuttons) + throw_icon = null + QDEL_LIST(infodisplay) + + healths = null + healthdoll = null + internals = null + lingchemdisplay = null + devilsouldisplay = null + lingstingdisplay = null + blobpwrdisplay = null + alien_plasma_display = null + alien_queen_finder = null + + QDEL_LIST_ASSOC_VAL(plane_masters) + QDEL_LIST(screenoverlays) + mymob = null + + return ..() + +/mob + var/hud_type = /datum/hud + +/mob/proc/create_mob_hud() + if(!client || hud_used) + return + hud_used = new hud_type(src) + update_sight() + SEND_SIGNAL(src, COMSIG_MOB_HUD_CREATED) + +//Version denotes which style should be displayed. blank or 0 means "next version" +/datum/hud/proc/show_hud(version = 0, mob/viewmob) + if(!ismob(mymob)) + return FALSE + var/mob/screenmob = viewmob || mymob + if(!screenmob.client) + return FALSE + + screenmob.client.screen = list() + screenmob.client.apply_clickcatcher() + + var/display_hud_version = version + if(!display_hud_version) //If 0 or blank, display the next hud version + display_hud_version = hud_version + 1 + if(display_hud_version > HUD_VERSIONS) //If the requested version number is greater than the available versions, reset back to the first version + display_hud_version = 1 + + switch(display_hud_version) + if(HUD_STYLE_STANDARD) //Default HUD + hud_shown = TRUE //Governs behavior of other procs + if(static_inventory.len) + screenmob.client.screen += static_inventory + if(toggleable_inventory.len && screenmob.hud_used && screenmob.hud_used.inventory_shown) + screenmob.client.screen += toggleable_inventory + if(hotkeybuttons.len && !hotkey_ui_hidden) + screenmob.client.screen += hotkeybuttons + if(infodisplay.len) + screenmob.client.screen += infodisplay + + screenmob.client.screen += hide_actions_toggle + + if(action_intent) + action_intent.screen_loc = initial(action_intent.screen_loc) //Restore intent selection to the original position + + if(HUD_STYLE_REDUCED) //Reduced HUD + hud_shown = FALSE //Governs behavior of other procs + if(static_inventory.len) + screenmob.client.screen -= static_inventory + if(toggleable_inventory.len) + screenmob.client.screen -= toggleable_inventory + if(hotkeybuttons.len) + screenmob.client.screen -= hotkeybuttons + if(infodisplay.len) + screenmob.client.screen += infodisplay + + //These ones are a part of 'static_inventory', 'toggleable_inventory' or 'hotkeybuttons' but we want them to stay + for(var/h in hand_slots) + var/obj/screen/hand = hand_slots[h] + if(hand) + screenmob.client.screen += hand + if(action_intent) + screenmob.client.screen += action_intent //we want the intent switcher visible + action_intent.screen_loc = ui_acti_alt //move this to the alternative position, where zone_select usually is. + + if(HUD_STYLE_NOHUD) //No HUD + hud_shown = FALSE //Governs behavior of other procs + if(static_inventory.len) + screenmob.client.screen -= static_inventory + if(toggleable_inventory.len) + screenmob.client.screen -= toggleable_inventory + if(hotkeybuttons.len) + screenmob.client.screen -= hotkeybuttons + if(infodisplay.len) + screenmob.client.screen -= infodisplay + + hud_version = display_hud_version + persistent_inventory_update(screenmob) + screenmob.update_action_buttons(1) + reorganize_alerts() + screenmob.reload_fullscreen() + update_parallax_pref(screenmob) + + // ensure observers get an accurate and up-to-date view + if (!viewmob) + plane_masters_update() + for(var/M in mymob.observers) + show_hud(hud_version, M) + else if (viewmob.hud_used) + viewmob.hud_used.plane_masters_update() + + return TRUE + +/datum/hud/proc/plane_masters_update() + // Plane masters are always shown to OUR mob, never to observers + for(var/thing in plane_masters) + var/obj/screen/plane_master/PM = plane_masters[thing] + PM.backdrop(mymob) + mymob.client.screen += PM + +/datum/hud/human/show_hud(version = 0,mob/viewmob) + . = ..() + if(!.) + return + var/mob/screenmob = viewmob || mymob + hidden_inventory_update(screenmob) + +/datum/hud/robot/show_hud(version = 0, mob/viewmob) + . = ..() + if(!.) + return + update_robot_modules_display() + +/datum/hud/proc/hidden_inventory_update() + return + +/datum/hud/proc/persistent_inventory_update(mob/viewer) + if(!mymob) + return + +/datum/hud/proc/update_ui_style(new_ui_style) + // do nothing if overridden by a subtype or already on that style + if (initial(ui_style) || ui_style == new_ui_style) + return + + for(var/atom/item in static_inventory + toggleable_inventory + hotkeybuttons + infodisplay + screenoverlays + inv_slots) + if (item.icon == ui_style) + item.icon = new_ui_style + + ui_style = new_ui_style + build_hand_slots() + hide_actions_toggle.InitialiseIcon(src) + +//Triggered when F12 is pressed (Unless someone changed something in the DMF) +/mob/verb/button_pressed_F12() + set name = "F12" + set hidden = TRUE + + if(hud_used && client) + hud_used.show_hud() //Shows the next hud preset + to_chat(usr, "Switched HUD mode. Press F12 to toggle.") + else + to_chat(usr, "This mob type does not use a HUD.") + + +//(re)builds the hand ui slots, throwing away old ones +//not really worth jugglying existing ones so we just scrap+rebuild +//9/10 this is only called once per mob and only for 2 hands +/datum/hud/proc/build_hand_slots() + for(var/h in hand_slots) + var/obj/screen/inventory/hand/H = hand_slots[h] + if(H) + static_inventory -= H + hand_slots = list() + var/obj/screen/inventory/hand/hand_box + for(var/i in 1 to mymob.held_items.len) + hand_box = new /obj/screen/inventory/hand() + hand_box.name = mymob.get_held_index_name(i) + hand_box.icon = ui_style + hand_box.icon_state = "hand_[mymob.held_index_to_dir(i)]" + hand_box.screen_loc = ui_hand_position(i) + hand_box.held_index = i + hand_slots["[i]"] = hand_box + hand_box.hud = src + static_inventory += hand_box + hand_box.update_icon() + + var/i = 1 + for(var/obj/screen/swap_hand/SH in static_inventory) + SH.screen_loc = ui_swaphand_position(mymob,!(i % 2) ? 2: 1) + i++ + for(var/obj/screen/human/equip/E in static_inventory) + E.screen_loc = ui_equip_position(mymob) + + if(ismob(mymob) && mymob.hud_used == src) + show_hud(hud_version) + +/datum/hud/proc/update_locked_slots() + return diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 78a2d2fd17..04da0ef03d 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -1,528 +1,528 @@ -/obj/screen/human - icon = 'icons/mob/screen_midnight.dmi' - -/obj/screen/human/toggle - name = "toggle" - icon_state = "toggle" - -/obj/screen/human/toggle/Click() - - var/mob/targetmob = usr - - if(isobserver(usr)) - if(ishuman(usr.client.eye) && (usr.client.eye != usr)) - var/mob/M = usr.client.eye - targetmob = M - - if(usr.hud_used.inventory_shown && targetmob.hud_used) - usr.hud_used.inventory_shown = FALSE - usr.client.screen -= targetmob.hud_used.toggleable_inventory - else - usr.hud_used.inventory_shown = TRUE - usr.client.screen += targetmob.hud_used.toggleable_inventory - - targetmob.hud_used.hidden_inventory_update(usr) - -/obj/screen/human/equip - name = "equip" - icon_state = "act_equip" - -/obj/screen/human/equip/Click() - if(ismecha(usr.loc)) // stops inventory actions in a mech - return 1 - var/mob/living/carbon/human/H = usr - H.quick_equip() - -/obj/screen/devil - invisibility = INVISIBILITY_ABSTRACT - -/obj/screen/devil/soul_counter - icon = 'icons/mob/screen_gen.dmi' - name = "souls owned" - icon_state = "Devil-6" - screen_loc = ui_devilsouldisplay - -/obj/screen/devil/soul_counter/proc/update_counter(souls = 0) - invisibility = 0 - maptext = "
      [souls]
      " - switch(souls) - if(0,null) - icon_state = "Devil-1" - if(1,2) - icon_state = "Devil-2" - if(3 to 5) - icon_state = "Devil-3" - if(6 to 8) - icon_state = "Devil-4" - if(9 to INFINITY) - icon_state = "Devil-5" - else - icon_state = "Devil-6" - -/obj/screen/devil/soul_counter/proc/clear() - invisibility = INVISIBILITY_ABSTRACT - -/obj/screen/ling - invisibility = INVISIBILITY_ABSTRACT - -/obj/screen/ling/sting - name = "current sting" - screen_loc = ui_lingstingdisplay - -/obj/screen/ling/sting/Click() - if(isobserver(usr)) - return - var/mob/living/carbon/U = usr - U.unset_sting() - -/obj/screen/ling/chems - name = "chemical storage" - icon_state = "power_display" - screen_loc = ui_lingchemdisplay - -/datum/hud/human/New(mob/living/carbon/human/owner) - ..() - owner.overlay_fullscreen("see_through_darkness", /obj/screen/fullscreen/see_through_darkness) - - var/widescreenlayout = FALSE //CIT CHANGE - adds support for different hud layouts depending on widescreen pref - if(owner.client && owner.client.prefs && owner.client.prefs.widescreenpref) //CIT CHANGE - ditto - widescreenlayout = TRUE // CIT CHANGE - ditto - - var/obj/screen/using - var/obj/screen/inventory/inv_box - - using = new /obj/screen/craft - using.icon = ui_style - if(!widescreenlayout) // CIT CHANGE - using.screen_loc = ui_boxcraft // CIT CHANGE - using.hud = src - static_inventory += using - - using = new/obj/screen/language_menu - using.icon = ui_style - if(!widescreenlayout) // CIT CHANGE - using.screen_loc = ui_boxlang // CIT CHANGE - using.hud = src - static_inventory += using - - using = new /obj/screen/area_creator - using.icon = ui_style - if(!widescreenlayout) // CIT CHANGE - using.screen_loc = ui_boxarea // CIT CHANGE - using.hud = src - static_inventory += using - - using = new /obj/screen/voretoggle() //We fancy Vore now - using.icon = tg_ui_icon_to_cit_ui(ui_style) - using.screen_loc = ui_voremode - if(!widescreenlayout) - using.screen_loc = ui_boxvore - using.hud = src - static_inventory += using - - action_intent = new /obj/screen/act_intent/segmented - action_intent.icon_state = mymob.a_intent - action_intent.hud = src - static_inventory += action_intent - - using = new /obj/screen/mov_intent - using.icon = tg_ui_icon_to_cit_ui(ui_style) // CIT CHANGE - overrides mov intent icon - using.icon_state = (mymob.m_intent == MOVE_INTENT_RUN ? "running" : "walking") - using.screen_loc = ui_movi - using.hud = src - static_inventory += using - - //CITADEL CHANGES - sprint button - using = new /obj/screen/sprintbutton - using.icon = tg_ui_icon_to_cit_ui(ui_style) - using.icon_state = (owner.sprinting ? "act_sprint_on" : "act_sprint") - using.screen_loc = ui_movi - using.hud = src - static_inventory += using - //END OF CITADEL CHANGES - - //same as above but buffer. - sprint_buffer = new /obj/screen/sprint_buffer - sprint_buffer.screen_loc = ui_sprintbufferloc - sprint_buffer.hud = src - static_inventory += sprint_buffer - - - using = new /obj/screen/drop() - using.icon = ui_style - using.screen_loc = ui_drop_throw - using.hud = src - static_inventory += using - - inv_box = new /obj/screen/inventory() - inv_box.name = "i_clothing" - inv_box.icon = ui_style - inv_box.slot_id = SLOT_W_UNIFORM - inv_box.icon_state = "uniform" - inv_box.screen_loc = ui_iclothing - toggleable_inventory += inv_box - - inv_box = new /obj/screen/inventory() - inv_box.name = "o_clothing" - inv_box.icon = ui_style - inv_box.slot_id = SLOT_WEAR_SUIT - inv_box.icon_state = "suit" - inv_box.screen_loc = ui_oclothing - toggleable_inventory += inv_box - - build_hand_slots() - - using = new /obj/screen/swap_hand() - using.icon = ui_style - using.icon_state = "swap_1" - using.screen_loc = ui_swaphand_position(owner,1) - using.hud = src - static_inventory += using - - using = new /obj/screen/swap_hand() - using.icon = ui_style - using.icon_state = "swap_2" - using.screen_loc = ui_swaphand_position(owner,2) - using.hud = src - static_inventory += using - - inv_box = new /obj/screen/inventory() - inv_box.name = "id" - inv_box.icon = ui_style - inv_box.icon_state = "id" - inv_box.screen_loc = ui_id - inv_box.slot_id = SLOT_WEAR_ID - static_inventory += inv_box - - inv_box = new /obj/screen/inventory() - inv_box.name = "mask" - inv_box.icon = ui_style - inv_box.icon_state = "mask" - inv_box.screen_loc = ui_mask - inv_box.slot_id = SLOT_WEAR_MASK - toggleable_inventory += inv_box - - inv_box = new /obj/screen/inventory() - inv_box.name = "neck" - inv_box.icon = ui_style - inv_box.icon_state = "neck" - inv_box.screen_loc = ui_neck - inv_box.slot_id = SLOT_NECK - toggleable_inventory += inv_box - - inv_box = new /obj/screen/inventory() - inv_box.name = "back" - inv_box.icon = ui_style - inv_box.icon_state = "back" - inv_box.screen_loc = ui_back - inv_box.slot_id = SLOT_BACK - static_inventory += inv_box - - inv_box = new /obj/screen/inventory() - inv_box.name = "storage1" - inv_box.icon = ui_style - inv_box.icon_state = "pocket" - inv_box.screen_loc = ui_storage1 - inv_box.slot_id = SLOT_L_STORE - static_inventory += inv_box - - inv_box = new /obj/screen/inventory() - inv_box.name = "storage2" - inv_box.icon = ui_style - inv_box.icon_state = "pocket" - inv_box.screen_loc = ui_storage2 - inv_box.slot_id = SLOT_R_STORE - static_inventory += inv_box - - inv_box = new /obj/screen/inventory() - inv_box.name = "suit storage" - inv_box.icon = ui_style - inv_box.icon_state = "suit_storage" - inv_box.screen_loc = ui_sstore1 - inv_box.slot_id = SLOT_S_STORE - static_inventory += inv_box - - using = new /obj/screen/resist() - using.icon = ui_style - using.screen_loc = ui_overridden_resist // CIT CHANGE - changes this to overridden resist - using.hud = src - hotkeybuttons += using - - //CIT CHANGES - rest and combat mode buttons - using = new /obj/screen/restbutton() - using.icon = tg_ui_icon_to_cit_ui(ui_style) - using.screen_loc = ui_pull_resist - using.hud = src - static_inventory += using - - using = new /obj/screen/combattoggle() - using.icon = tg_ui_icon_to_cit_ui(ui_style) - using.screen_loc = ui_combat_toggle - using.hud = src - static_inventory += using - //END OF CIT CHANGES - - using = new /obj/screen/human/toggle() - using.icon = ui_style - using.screen_loc = ui_inventory - using.hud = src - static_inventory += using - - using = new /obj/screen/human/equip() - using.icon = ui_style - using.screen_loc = ui_equip_position(mymob) - using.hud = src - static_inventory += using - - inv_box = new /obj/screen/inventory() - inv_box.name = "gloves" - inv_box.icon = ui_style - inv_box.icon_state = "gloves" - inv_box.screen_loc = ui_gloves - inv_box.slot_id = SLOT_GLOVES - toggleable_inventory += inv_box - - inv_box = new /obj/screen/inventory() - inv_box.name = "eyes" - inv_box.icon = ui_style - inv_box.icon_state = "glasses" - inv_box.screen_loc = ui_glasses - inv_box.slot_id = SLOT_GLASSES - toggleable_inventory += inv_box - - inv_box = new /obj/screen/inventory() - inv_box.name = "ears" - inv_box.icon = ui_style - inv_box.icon_state = "ears" - inv_box.screen_loc = ui_ears - inv_box.slot_id = SLOT_EARS - toggleable_inventory += inv_box - - inv_box = new /obj/screen/inventory() - inv_box.name = "head" - inv_box.icon = ui_style - inv_box.icon_state = "head" - inv_box.screen_loc = ui_head - inv_box.slot_id = SLOT_HEAD - toggleable_inventory += inv_box - - inv_box = new /obj/screen/inventory() - inv_box.name = "shoes" - inv_box.icon = ui_style - inv_box.icon_state = "shoes" - inv_box.screen_loc = ui_shoes - inv_box.slot_id = SLOT_SHOES - toggleable_inventory += inv_box - - inv_box = new /obj/screen/inventory() - inv_box.name = "belt" - inv_box.icon = ui_style - inv_box.icon_state = "belt" -// inv_box.icon_full = "template_small" - inv_box.screen_loc = ui_belt - inv_box.slot_id = SLOT_BELT - static_inventory += inv_box - - throw_icon = new /obj/screen/throw_catch() - throw_icon.icon = ui_style - throw_icon.screen_loc = ui_drop_throw - throw_icon.hud = src - hotkeybuttons += throw_icon - - internals = new /obj/screen/internals() - internals.hud = src - infodisplay += internals - - healths = new /obj/screen/healths() - healths.hud = src - infodisplay += healths - //CIT CHANGE - adds arousal and stamina to hud - arousal = new /obj/screen/arousal() - arousal.icon_state = (owner.canbearoused == 1 ? "arousal0" : "") - arousal.hud = src - infodisplay += arousal - - staminas = new /obj/screen/staminas() - staminas.hud = src - infodisplay += staminas - - if(!CONFIG_GET(flag/disable_stambuffer)) - staminabuffer = new /obj/screen/staminabuffer() - staminabuffer.hud = src - infodisplay += staminabuffer - //END OF CIT CHANGES - - healthdoll = new /obj/screen/healthdoll() - healthdoll.hud = src - infodisplay += healthdoll - - pull_icon = new /obj/screen/pull() - pull_icon.icon = ui_style - pull_icon.hud = src - pull_icon.update_icon() - pull_icon.screen_loc = ui_pull_resist - static_inventory += pull_icon - - lingchemdisplay = new /obj/screen/ling/chems() - lingchemdisplay.hud = src - infodisplay += lingchemdisplay - - lingstingdisplay = new /obj/screen/ling/sting() - lingstingdisplay.hud = src - infodisplay += lingstingdisplay - - devilsouldisplay = new /obj/screen/devil/soul_counter - devilsouldisplay.hud = src - infodisplay += devilsouldisplay - - blood_display = new /obj/screen/bloodsucker/blood_counter // Blood Volume - blood_display.hud = src - infodisplay += blood_display - - vamprank_display = new /obj/screen/bloodsucker/rank_counter // Vampire Rank - vamprank_display.hud = src - infodisplay += vamprank_display - - sunlight_display = new /obj/screen/bloodsucker/sunlight_counter // Sunlight - sunlight_display.hud = src - infodisplay += sunlight_display - - zone_select = new /obj/screen/zone_sel() - zone_select.icon = ui_style - zone_select.hud = src - zone_select.update_icon() - static_inventory += zone_select - - for(var/obj/screen/inventory/inv in (static_inventory + toggleable_inventory)) - if(inv.slot_id) - inv.hud = src - inv_slots[inv.slot_id] = inv - inv.update_icon() - - update_locked_slots() - -/datum/hud/human/update_locked_slots() - if(!mymob) - return - var/mob/living/carbon/human/H = mymob - if(!istype(H) || !H.dna.species) - return - var/datum/species/S = H.dna.species - for(var/obj/screen/inventory/inv in (static_inventory + toggleable_inventory)) - if(inv.slot_id) - if(inv.slot_id in S.no_equip) - inv.alpha = 128 - else - inv.alpha = initial(inv.alpha) - -/datum/hud/human/hidden_inventory_update(mob/viewer) - if(!mymob) - return - var/mob/living/carbon/human/H = mymob - - var/mob/screenmob = viewer || H - - if(screenmob.hud_used.inventory_shown && screenmob.hud_used.hud_shown) - if(H.shoes) - H.shoes.screen_loc = ui_shoes - screenmob.client.screen += H.shoes - if(H.gloves) - H.gloves.screen_loc = ui_gloves - screenmob.client.screen += H.gloves - if(H.ears) - H.ears.screen_loc = ui_ears - screenmob.client.screen += H.ears - if(H.glasses) - H.glasses.screen_loc = ui_glasses - screenmob.client.screen += H.glasses - if(H.w_uniform) - H.w_uniform.screen_loc = ui_iclothing - screenmob.client.screen += H.w_uniform - if(H.wear_suit) - H.wear_suit.screen_loc = ui_oclothing - screenmob.client.screen += H.wear_suit - if(H.wear_mask) - H.wear_mask.screen_loc = ui_mask - screenmob.client.screen += H.wear_mask - if(H.wear_neck) - H.wear_neck.screen_loc = ui_neck - screenmob.client.screen += H.wear_neck - if(H.head) - H.head.screen_loc = ui_head - screenmob.client.screen += H.head - else - if(H.shoes) screenmob.client.screen -= H.shoes - if(H.gloves) screenmob.client.screen -= H.gloves - if(H.ears) screenmob.client.screen -= H.ears - if(H.glasses) screenmob.client.screen -= H.glasses - if(H.w_uniform) screenmob.client.screen -= H.w_uniform - if(H.wear_suit) screenmob.client.screen -= H.wear_suit - if(H.wear_mask) screenmob.client.screen -= H.wear_mask - if(H.wear_neck) screenmob.client.screen -= H.wear_neck - if(H.head) screenmob.client.screen -= H.head - - - -/datum/hud/human/persistent_inventory_update(mob/viewer) - if(!mymob) - return - ..() - var/mob/living/carbon/human/H = mymob - - var/mob/screenmob = viewer || H - - if(screenmob.hud_used) - if(screenmob.hud_used.hud_shown) - if(H.s_store) - H.s_store.screen_loc = ui_sstore1 - screenmob.client.screen += H.s_store - if(H.wear_id) - H.wear_id.screen_loc = ui_id - screenmob.client.screen += H.wear_id - if(H.belt) - H.belt.screen_loc = ui_belt - screenmob.client.screen += H.belt - if(H.back) - H.back.screen_loc = ui_back - screenmob.client.screen += H.back - if(H.l_store) - H.l_store.screen_loc = ui_storage1 - screenmob.client.screen += H.l_store - if(H.r_store) - H.r_store.screen_loc = ui_storage2 - screenmob.client.screen += H.r_store - else - if(H.s_store) - screenmob.client.screen -= H.s_store - if(H.wear_id) - screenmob.client.screen -= H.wear_id - if(H.belt) - screenmob.client.screen -= H.belt - if(H.back) - screenmob.client.screen -= H.back - if(H.l_store) - screenmob.client.screen -= H.l_store - if(H.r_store) - screenmob.client.screen -= H.r_store - - if(hud_version != HUD_STYLE_NOHUD) - for(var/obj/item/I in H.held_items) - I.screen_loc = ui_hand_position(H.get_held_index_of_item(I)) - screenmob.client.screen += I - else - for(var/obj/item/I in H.held_items) - I.screen_loc = null - screenmob.client.screen -= I - - -/mob/living/carbon/human/verb/toggle_hotkey_verbs() - set category = "OOC" - set name = "Toggle hotkey buttons" - set desc = "This disables or enables the user interface buttons which can be used with hotkeys." - - if(hud_used.hotkey_ui_hidden) - client.screen += hud_used.hotkeybuttons - hud_used.hotkey_ui_hidden = FALSE - else - client.screen -= hud_used.hotkeybuttons - hud_used.hotkey_ui_hidden = TRUE +/obj/screen/human + icon = 'icons/mob/screen_midnight.dmi' + +/obj/screen/human/toggle + name = "toggle" + icon_state = "toggle" + +/obj/screen/human/toggle/Click() + + var/mob/targetmob = usr + + if(isobserver(usr)) + if(ishuman(usr.client.eye) && (usr.client.eye != usr)) + var/mob/M = usr.client.eye + targetmob = M + + if(usr.hud_used.inventory_shown && targetmob.hud_used) + usr.hud_used.inventory_shown = FALSE + usr.client.screen -= targetmob.hud_used.toggleable_inventory + else + usr.hud_used.inventory_shown = TRUE + usr.client.screen += targetmob.hud_used.toggleable_inventory + + targetmob.hud_used.hidden_inventory_update(usr) + +/obj/screen/human/equip + name = "equip" + icon_state = "act_equip" + +/obj/screen/human/equip/Click() + if(ismecha(usr.loc)) // stops inventory actions in a mech + return 1 + var/mob/living/carbon/human/H = usr + H.quick_equip() + +/obj/screen/devil + invisibility = INVISIBILITY_ABSTRACT + +/obj/screen/devil/soul_counter + icon = 'icons/mob/screen_gen.dmi' + name = "souls owned" + icon_state = "Devil-6" + screen_loc = ui_devilsouldisplay + +/obj/screen/devil/soul_counter/proc/update_counter(souls = 0) + invisibility = 0 + maptext = "
      [souls]
      " + switch(souls) + if(0,null) + icon_state = "Devil-1" + if(1,2) + icon_state = "Devil-2" + if(3 to 5) + icon_state = "Devil-3" + if(6 to 8) + icon_state = "Devil-4" + if(9 to INFINITY) + icon_state = "Devil-5" + else + icon_state = "Devil-6" + +/obj/screen/devil/soul_counter/proc/clear() + invisibility = INVISIBILITY_ABSTRACT + +/obj/screen/ling + invisibility = INVISIBILITY_ABSTRACT + +/obj/screen/ling/sting + name = "current sting" + screen_loc = ui_lingstingdisplay + +/obj/screen/ling/sting/Click() + if(isobserver(usr)) + return + var/mob/living/carbon/U = usr + U.unset_sting() + +/obj/screen/ling/chems + name = "chemical storage" + icon_state = "power_display" + screen_loc = ui_lingchemdisplay + +/datum/hud/human/New(mob/living/carbon/human/owner) + ..() + owner.overlay_fullscreen("see_through_darkness", /obj/screen/fullscreen/see_through_darkness) + + var/widescreenlayout = FALSE //CIT CHANGE - adds support for different hud layouts depending on widescreen pref + if(owner.client && owner.client.prefs && owner.client.prefs.widescreenpref) //CIT CHANGE - ditto + widescreenlayout = TRUE // CIT CHANGE - ditto + + var/obj/screen/using + var/obj/screen/inventory/inv_box + + using = new /obj/screen/craft + using.icon = ui_style + if(!widescreenlayout) // CIT CHANGE + using.screen_loc = ui_boxcraft // CIT CHANGE + using.hud = src + static_inventory += using + + using = new/obj/screen/language_menu + using.icon = ui_style + if(!widescreenlayout) // CIT CHANGE + using.screen_loc = ui_boxlang // CIT CHANGE + using.hud = src + static_inventory += using + + using = new /obj/screen/area_creator + using.icon = ui_style + if(!widescreenlayout) // CIT CHANGE + using.screen_loc = ui_boxarea // CIT CHANGE + using.hud = src + static_inventory += using + + using = new /obj/screen/voretoggle() //We fancy Vore now + using.icon = tg_ui_icon_to_cit_ui(ui_style) + using.screen_loc = ui_voremode + if(!widescreenlayout) + using.screen_loc = ui_boxvore + using.hud = src + static_inventory += using + + action_intent = new /obj/screen/act_intent/segmented + action_intent.icon_state = mymob.a_intent + action_intent.hud = src + static_inventory += action_intent + + using = new /obj/screen/mov_intent + using.icon = tg_ui_icon_to_cit_ui(ui_style) // CIT CHANGE - overrides mov intent icon + using.icon_state = (mymob.m_intent == MOVE_INTENT_RUN ? "running" : "walking") + using.screen_loc = ui_movi + using.hud = src + static_inventory += using + + //CITADEL CHANGES - sprint button + using = new /obj/screen/sprintbutton + using.icon = tg_ui_icon_to_cit_ui(ui_style) + using.icon_state = (owner.sprinting ? "act_sprint_on" : "act_sprint") + using.screen_loc = ui_movi + using.hud = src + static_inventory += using + //END OF CITADEL CHANGES + + //same as above but buffer. + sprint_buffer = new /obj/screen/sprint_buffer + sprint_buffer.screen_loc = ui_sprintbufferloc + sprint_buffer.hud = src + static_inventory += sprint_buffer + + + using = new /obj/screen/drop() + using.icon = ui_style + using.screen_loc = ui_drop_throw + using.hud = src + static_inventory += using + + inv_box = new /obj/screen/inventory() + inv_box.name = "i_clothing" + inv_box.icon = ui_style + inv_box.slot_id = SLOT_W_UNIFORM + inv_box.icon_state = "uniform" + inv_box.screen_loc = ui_iclothing + toggleable_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "o_clothing" + inv_box.icon = ui_style + inv_box.slot_id = SLOT_WEAR_SUIT + inv_box.icon_state = "suit" + inv_box.screen_loc = ui_oclothing + toggleable_inventory += inv_box + + build_hand_slots() + + using = new /obj/screen/swap_hand() + using.icon = ui_style + using.icon_state = "swap_1" + using.screen_loc = ui_swaphand_position(owner,1) + using.hud = src + static_inventory += using + + using = new /obj/screen/swap_hand() + using.icon = ui_style + using.icon_state = "swap_2" + using.screen_loc = ui_swaphand_position(owner,2) + using.hud = src + static_inventory += using + + inv_box = new /obj/screen/inventory() + inv_box.name = "id" + inv_box.icon = ui_style + inv_box.icon_state = "id" + inv_box.screen_loc = ui_id + inv_box.slot_id = SLOT_WEAR_ID + static_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "mask" + inv_box.icon = ui_style + inv_box.icon_state = "mask" + inv_box.screen_loc = ui_mask + inv_box.slot_id = SLOT_WEAR_MASK + toggleable_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "neck" + inv_box.icon = ui_style + inv_box.icon_state = "neck" + inv_box.screen_loc = ui_neck + inv_box.slot_id = SLOT_NECK + toggleable_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "back" + inv_box.icon = ui_style + inv_box.icon_state = "back" + inv_box.screen_loc = ui_back + inv_box.slot_id = SLOT_BACK + static_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "storage1" + inv_box.icon = ui_style + inv_box.icon_state = "pocket" + inv_box.screen_loc = ui_storage1 + inv_box.slot_id = SLOT_L_STORE + static_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "storage2" + inv_box.icon = ui_style + inv_box.icon_state = "pocket" + inv_box.screen_loc = ui_storage2 + inv_box.slot_id = SLOT_R_STORE + static_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "suit storage" + inv_box.icon = ui_style + inv_box.icon_state = "suit_storage" + inv_box.screen_loc = ui_sstore1 + inv_box.slot_id = SLOT_S_STORE + static_inventory += inv_box + + using = new /obj/screen/resist() + using.icon = ui_style + using.screen_loc = ui_overridden_resist // CIT CHANGE - changes this to overridden resist + using.hud = src + hotkeybuttons += using + + //CIT CHANGES - rest and combat mode buttons + using = new /obj/screen/restbutton() + using.icon = tg_ui_icon_to_cit_ui(ui_style) + using.screen_loc = ui_pull_resist + using.hud = src + static_inventory += using + + using = new /obj/screen/combattoggle() + using.icon = tg_ui_icon_to_cit_ui(ui_style) + using.screen_loc = ui_combat_toggle + using.hud = src + static_inventory += using + //END OF CIT CHANGES + + using = new /obj/screen/human/toggle() + using.icon = ui_style + using.screen_loc = ui_inventory + using.hud = src + static_inventory += using + + using = new /obj/screen/human/equip() + using.icon = ui_style + using.screen_loc = ui_equip_position(mymob) + using.hud = src + static_inventory += using + + inv_box = new /obj/screen/inventory() + inv_box.name = "gloves" + inv_box.icon = ui_style + inv_box.icon_state = "gloves" + inv_box.screen_loc = ui_gloves + inv_box.slot_id = SLOT_GLOVES + toggleable_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "eyes" + inv_box.icon = ui_style + inv_box.icon_state = "glasses" + inv_box.screen_loc = ui_glasses + inv_box.slot_id = SLOT_GLASSES + toggleable_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "ears" + inv_box.icon = ui_style + inv_box.icon_state = "ears" + inv_box.screen_loc = ui_ears + inv_box.slot_id = SLOT_EARS + toggleable_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "head" + inv_box.icon = ui_style + inv_box.icon_state = "head" + inv_box.screen_loc = ui_head + inv_box.slot_id = SLOT_HEAD + toggleable_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "shoes" + inv_box.icon = ui_style + inv_box.icon_state = "shoes" + inv_box.screen_loc = ui_shoes + inv_box.slot_id = SLOT_SHOES + toggleable_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "belt" + inv_box.icon = ui_style + inv_box.icon_state = "belt" +// inv_box.icon_full = "template_small" + inv_box.screen_loc = ui_belt + inv_box.slot_id = SLOT_BELT + static_inventory += inv_box + + throw_icon = new /obj/screen/throw_catch() + throw_icon.icon = ui_style + throw_icon.screen_loc = ui_drop_throw + throw_icon.hud = src + hotkeybuttons += throw_icon + + internals = new /obj/screen/internals() + internals.hud = src + infodisplay += internals + + healths = new /obj/screen/healths() + healths.hud = src + infodisplay += healths + //CIT CHANGE - adds arousal and stamina to hud + arousal = new /obj/screen/arousal() + arousal.icon_state = (owner.canbearoused == 1 ? "arousal0" : "") + arousal.hud = src + infodisplay += arousal + + staminas = new /obj/screen/staminas() + staminas.hud = src + infodisplay += staminas + + if(!CONFIG_GET(flag/disable_stambuffer)) + staminabuffer = new /obj/screen/staminabuffer() + staminabuffer.hud = src + infodisplay += staminabuffer + //END OF CIT CHANGES + + healthdoll = new /obj/screen/healthdoll() + healthdoll.hud = src + infodisplay += healthdoll + + pull_icon = new /obj/screen/pull() + pull_icon.icon = ui_style + pull_icon.hud = src + pull_icon.update_icon() + pull_icon.screen_loc = ui_pull_resist + static_inventory += pull_icon + + lingchemdisplay = new /obj/screen/ling/chems() + lingchemdisplay.hud = src + infodisplay += lingchemdisplay + + lingstingdisplay = new /obj/screen/ling/sting() + lingstingdisplay.hud = src + infodisplay += lingstingdisplay + + devilsouldisplay = new /obj/screen/devil/soul_counter + devilsouldisplay.hud = src + infodisplay += devilsouldisplay + + blood_display = new /obj/screen/bloodsucker/blood_counter // Blood Volume + blood_display.hud = src + infodisplay += blood_display + + vamprank_display = new /obj/screen/bloodsucker/rank_counter // Vampire Rank + vamprank_display.hud = src + infodisplay += vamprank_display + + sunlight_display = new /obj/screen/bloodsucker/sunlight_counter // Sunlight + sunlight_display.hud = src + infodisplay += sunlight_display + + zone_select = new /obj/screen/zone_sel() + zone_select.icon = ui_style + zone_select.hud = src + zone_select.update_icon() + static_inventory += zone_select + + for(var/obj/screen/inventory/inv in (static_inventory + toggleable_inventory)) + if(inv.slot_id) + inv.hud = src + inv_slots[inv.slot_id] = inv + inv.update_icon() + + update_locked_slots() + +/datum/hud/human/update_locked_slots() + if(!mymob) + return + var/mob/living/carbon/human/H = mymob + if(!istype(H) || !H.dna.species) + return + var/datum/species/S = H.dna.species + for(var/obj/screen/inventory/inv in (static_inventory + toggleable_inventory)) + if(inv.slot_id) + if(inv.slot_id in S.no_equip) + inv.alpha = 128 + else + inv.alpha = initial(inv.alpha) + +/datum/hud/human/hidden_inventory_update(mob/viewer) + if(!mymob) + return + var/mob/living/carbon/human/H = mymob + + var/mob/screenmob = viewer || H + + if(screenmob.hud_used.inventory_shown && screenmob.hud_used.hud_shown) + if(H.shoes) + H.shoes.screen_loc = ui_shoes + screenmob.client.screen += H.shoes + if(H.gloves) + H.gloves.screen_loc = ui_gloves + screenmob.client.screen += H.gloves + if(H.ears) + H.ears.screen_loc = ui_ears + screenmob.client.screen += H.ears + if(H.glasses) + H.glasses.screen_loc = ui_glasses + screenmob.client.screen += H.glasses + if(H.w_uniform) + H.w_uniform.screen_loc = ui_iclothing + screenmob.client.screen += H.w_uniform + if(H.wear_suit) + H.wear_suit.screen_loc = ui_oclothing + screenmob.client.screen += H.wear_suit + if(H.wear_mask) + H.wear_mask.screen_loc = ui_mask + screenmob.client.screen += H.wear_mask + if(H.wear_neck) + H.wear_neck.screen_loc = ui_neck + screenmob.client.screen += H.wear_neck + if(H.head) + H.head.screen_loc = ui_head + screenmob.client.screen += H.head + else + if(H.shoes) screenmob.client.screen -= H.shoes + if(H.gloves) screenmob.client.screen -= H.gloves + if(H.ears) screenmob.client.screen -= H.ears + if(H.glasses) screenmob.client.screen -= H.glasses + if(H.w_uniform) screenmob.client.screen -= H.w_uniform + if(H.wear_suit) screenmob.client.screen -= H.wear_suit + if(H.wear_mask) screenmob.client.screen -= H.wear_mask + if(H.wear_neck) screenmob.client.screen -= H.wear_neck + if(H.head) screenmob.client.screen -= H.head + + + +/datum/hud/human/persistent_inventory_update(mob/viewer) + if(!mymob) + return + ..() + var/mob/living/carbon/human/H = mymob + + var/mob/screenmob = viewer || H + + if(screenmob.hud_used) + if(screenmob.hud_used.hud_shown) + if(H.s_store) + H.s_store.screen_loc = ui_sstore1 + screenmob.client.screen += H.s_store + if(H.wear_id) + H.wear_id.screen_loc = ui_id + screenmob.client.screen += H.wear_id + if(H.belt) + H.belt.screen_loc = ui_belt + screenmob.client.screen += H.belt + if(H.back) + H.back.screen_loc = ui_back + screenmob.client.screen += H.back + if(H.l_store) + H.l_store.screen_loc = ui_storage1 + screenmob.client.screen += H.l_store + if(H.r_store) + H.r_store.screen_loc = ui_storage2 + screenmob.client.screen += H.r_store + else + if(H.s_store) + screenmob.client.screen -= H.s_store + if(H.wear_id) + screenmob.client.screen -= H.wear_id + if(H.belt) + screenmob.client.screen -= H.belt + if(H.back) + screenmob.client.screen -= H.back + if(H.l_store) + screenmob.client.screen -= H.l_store + if(H.r_store) + screenmob.client.screen -= H.r_store + + if(hud_version != HUD_STYLE_NOHUD) + for(var/obj/item/I in H.held_items) + I.screen_loc = ui_hand_position(H.get_held_index_of_item(I)) + screenmob.client.screen += I + else + for(var/obj/item/I in H.held_items) + I.screen_loc = null + screenmob.client.screen -= I + + +/mob/living/carbon/human/verb/toggle_hotkey_verbs() + set category = "OOC" + set name = "Toggle hotkey buttons" + set desc = "This disables or enables the user interface buttons which can be used with hotkeys." + + if(hud_used.hotkey_ui_hidden) + client.screen += hud_used.hotkeybuttons + hud_used.hotkey_ui_hidden = FALSE + else + client.screen -= hud_used.hotkeybuttons + hud_used.hotkey_ui_hidden = TRUE diff --git a/code/_onclick/hud/monkey.dm b/code/_onclick/hud/monkey.dm index 3d3c3cf64a..d665330aac 100644 --- a/code/_onclick/hud/monkey.dm +++ b/code/_onclick/hud/monkey.dm @@ -1,165 +1,165 @@ -/datum/hud/monkey/New(mob/living/carbon/monkey/owner) - ..() - var/obj/screen/using - var/obj/screen/inventory/inv_box - - action_intent = new /obj/screen/act_intent() - action_intent.icon = ui_style - action_intent.icon_state = mymob.a_intent - action_intent.screen_loc = ui_acti - action_intent.hud = src - static_inventory += action_intent - - using = new /obj/screen/mov_intent() - using.icon = ui_style - using.icon_state = (mymob.m_intent == MOVE_INTENT_RUN ? "running" : "walking") - using.screen_loc = ui_movi - using.hud = src - static_inventory += using - - using = new/obj/screen/language_menu - using.icon = ui_style - using.hud = src - static_inventory += using - - using = new /obj/screen/drop() - using.icon = ui_style - using.screen_loc = ui_drop_throw - using.hud = src - static_inventory += using - - build_hand_slots() - - using = new /obj/screen/swap_hand() - using.icon = ui_style - using.icon_state = "swap_1_m" //extra wide! - using.screen_loc = ui_swaphand_position(owner,1) - using.hud = src - static_inventory += using - - using = new /obj/screen/swap_hand() - using.icon = ui_style - using.icon_state = "swap_2" - using.screen_loc = ui_swaphand_position(owner,2) - using.hud = src - static_inventory += using - - inv_box = new /obj/screen/inventory() - inv_box.name = "mask" - inv_box.icon = ui_style - inv_box.icon_state = "mask" -// inv_box.icon_full = "template" - inv_box.screen_loc = ui_monkey_mask - inv_box.slot_id = SLOT_WEAR_MASK - static_inventory += inv_box - - inv_box = new /obj/screen/inventory() - inv_box.name = "neck" - inv_box.icon = ui_style - inv_box.icon_state = "neck" -// inv_box.icon_full = "template" - inv_box.screen_loc = ui_monkey_neck - inv_box.slot_id = SLOT_NECK - static_inventory += inv_box - - inv_box = new /obj/screen/inventory() - inv_box.name = "head" - inv_box.icon = ui_style - inv_box.icon_state = "head" -// inv_box.icon_full = "template" - inv_box.screen_loc = ui_monkey_head - inv_box.slot_id = SLOT_HEAD - static_inventory += inv_box - - inv_box = new /obj/screen/inventory() - inv_box.name = "back" - inv_box.icon = ui_style - inv_box.icon_state = "back" - inv_box.screen_loc = ui_monkey_back - inv_box.slot_id = SLOT_BACK - static_inventory += inv_box - - throw_icon = new /obj/screen/throw_catch() - throw_icon.icon = ui_style - throw_icon.screen_loc = ui_drop_throw - throw_icon.hud = src - hotkeybuttons += throw_icon - - internals = new /obj/screen/internals() - internals.hud = src - infodisplay += internals - - healths = new /obj/screen/healths() - healths.hud = src - infodisplay += healths - - pull_icon = new /obj/screen/pull() - pull_icon.icon = ui_style - pull_icon.screen_loc = ui_pull_resist - pull_icon.hud = src - pull_icon.update_icon() - static_inventory += pull_icon - - lingchemdisplay = new /obj/screen/ling/chems() - lingchemdisplay.hud = src - infodisplay += lingchemdisplay - - lingstingdisplay = new /obj/screen/ling/sting() - lingstingdisplay.hud = src - infodisplay += lingstingdisplay - - - zone_select = new /obj/screen/zone_sel() - zone_select.icon = ui_style - zone_select.hud = src - zone_select.update_icon() - static_inventory += zone_select - - mymob.client.screen = list() - - using = new /obj/screen/resist() - using.icon = ui_style - using.screen_loc = ui_pull_resist - using.hud = src - hotkeybuttons += using - - for(var/obj/screen/inventory/inv in (static_inventory + toggleable_inventory)) - if(inv.slot_id) - inv.hud = src - inv_slots[inv.slot_id] = inv - inv.update_icon() - -/datum/hud/monkey/persistent_inventory_update() - if(!mymob) - return - var/mob/living/carbon/monkey/M = mymob - - if(hud_shown) - if(M.back) - M.back.screen_loc = ui_monkey_back - M.client.screen += M.back - if(M.wear_mask) - M.wear_mask.screen_loc = ui_monkey_mask - M.client.screen += M.wear_mask - if(M.wear_neck) - M.wear_neck.screen_loc = ui_monkey_neck - M.client.screen += M.wear_neck - if(M.head) - M.head.screen_loc = ui_monkey_head - M.client.screen += M.head - else - if(M.back) - M.back.screen_loc = null - if(M.wear_mask) - M.wear_mask.screen_loc = null - if(M.head) - M.head.screen_loc = null - - if(hud_version != HUD_STYLE_NOHUD) - for(var/obj/item/I in M.held_items) - I.screen_loc = ui_hand_position(M.get_held_index_of_item(I)) - M.client.screen += I - else - for(var/obj/item/I in M.held_items) - I.screen_loc = null - M.client.screen -= I +/datum/hud/monkey/New(mob/living/carbon/monkey/owner) + ..() + var/obj/screen/using + var/obj/screen/inventory/inv_box + + action_intent = new /obj/screen/act_intent() + action_intent.icon = ui_style + action_intent.icon_state = mymob.a_intent + action_intent.screen_loc = ui_acti + action_intent.hud = src + static_inventory += action_intent + + using = new /obj/screen/mov_intent() + using.icon = ui_style + using.icon_state = (mymob.m_intent == MOVE_INTENT_RUN ? "running" : "walking") + using.screen_loc = ui_movi + using.hud = src + static_inventory += using + + using = new/obj/screen/language_menu + using.icon = ui_style + using.hud = src + static_inventory += using + + using = new /obj/screen/drop() + using.icon = ui_style + using.screen_loc = ui_drop_throw + using.hud = src + static_inventory += using + + build_hand_slots() + + using = new /obj/screen/swap_hand() + using.icon = ui_style + using.icon_state = "swap_1_m" //extra wide! + using.screen_loc = ui_swaphand_position(owner,1) + using.hud = src + static_inventory += using + + using = new /obj/screen/swap_hand() + using.icon = ui_style + using.icon_state = "swap_2" + using.screen_loc = ui_swaphand_position(owner,2) + using.hud = src + static_inventory += using + + inv_box = new /obj/screen/inventory() + inv_box.name = "mask" + inv_box.icon = ui_style + inv_box.icon_state = "mask" +// inv_box.icon_full = "template" + inv_box.screen_loc = ui_monkey_mask + inv_box.slot_id = SLOT_WEAR_MASK + static_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "neck" + inv_box.icon = ui_style + inv_box.icon_state = "neck" +// inv_box.icon_full = "template" + inv_box.screen_loc = ui_monkey_neck + inv_box.slot_id = SLOT_NECK + static_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "head" + inv_box.icon = ui_style + inv_box.icon_state = "head" +// inv_box.icon_full = "template" + inv_box.screen_loc = ui_monkey_head + inv_box.slot_id = SLOT_HEAD + static_inventory += inv_box + + inv_box = new /obj/screen/inventory() + inv_box.name = "back" + inv_box.icon = ui_style + inv_box.icon_state = "back" + inv_box.screen_loc = ui_monkey_back + inv_box.slot_id = SLOT_BACK + static_inventory += inv_box + + throw_icon = new /obj/screen/throw_catch() + throw_icon.icon = ui_style + throw_icon.screen_loc = ui_drop_throw + throw_icon.hud = src + hotkeybuttons += throw_icon + + internals = new /obj/screen/internals() + internals.hud = src + infodisplay += internals + + healths = new /obj/screen/healths() + healths.hud = src + infodisplay += healths + + pull_icon = new /obj/screen/pull() + pull_icon.icon = ui_style + pull_icon.screen_loc = ui_pull_resist + pull_icon.hud = src + pull_icon.update_icon() + static_inventory += pull_icon + + lingchemdisplay = new /obj/screen/ling/chems() + lingchemdisplay.hud = src + infodisplay += lingchemdisplay + + lingstingdisplay = new /obj/screen/ling/sting() + lingstingdisplay.hud = src + infodisplay += lingstingdisplay + + + zone_select = new /obj/screen/zone_sel() + zone_select.icon = ui_style + zone_select.hud = src + zone_select.update_icon() + static_inventory += zone_select + + mymob.client.screen = list() + + using = new /obj/screen/resist() + using.icon = ui_style + using.screen_loc = ui_pull_resist + using.hud = src + hotkeybuttons += using + + for(var/obj/screen/inventory/inv in (static_inventory + toggleable_inventory)) + if(inv.slot_id) + inv.hud = src + inv_slots[inv.slot_id] = inv + inv.update_icon() + +/datum/hud/monkey/persistent_inventory_update() + if(!mymob) + return + var/mob/living/carbon/monkey/M = mymob + + if(hud_shown) + if(M.back) + M.back.screen_loc = ui_monkey_back + M.client.screen += M.back + if(M.wear_mask) + M.wear_mask.screen_loc = ui_monkey_mask + M.client.screen += M.wear_mask + if(M.wear_neck) + M.wear_neck.screen_loc = ui_monkey_neck + M.client.screen += M.wear_neck + if(M.head) + M.head.screen_loc = ui_monkey_head + M.client.screen += M.head + else + if(M.back) + M.back.screen_loc = null + if(M.wear_mask) + M.wear_mask.screen_loc = null + if(M.head) + M.head.screen_loc = null + + if(hud_version != HUD_STYLE_NOHUD) + for(var/obj/item/I in M.held_items) + I.screen_loc = ui_hand_position(M.get_held_index_of_item(I)) + M.client.screen += I + else + for(var/obj/item/I in M.held_items) + I.screen_loc = null + M.client.screen -= I diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 00c89644b6..9859e7acdf 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -1,307 +1,307 @@ -/obj/screen/robot - icon = 'icons/mob/screen_cyborg.dmi' - -/obj/screen/robot/module - name = "cyborg module" - icon_state = "nomod" - -/obj/screen/robot/Click() - if(isobserver(usr)) - return 1 - -/obj/screen/robot/module/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - if(R.module.type != /obj/item/robot_module) - R.hud_used.toggle_show_robot_modules() - return 1 - R.pick_module() - -/obj/screen/robot/module1 - name = "module1" - icon_state = "inv1" - -/obj/screen/robot/module1/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_module(1) - -/obj/screen/robot/module2 - name = "module2" - icon_state = "inv2" - -/obj/screen/robot/module2/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_module(2) - -/obj/screen/robot/module3 - name = "module3" - icon_state = "inv3" - -/obj/screen/robot/module3/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_module(3) - -/obj/screen/robot/radio - name = "radio" - icon_state = "radio" - -/obj/screen/robot/radio/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.radio.interact(R) - -/obj/screen/robot/store - name = "store" - icon_state = "store" - -/obj/screen/robot/store/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.uneq_active() - -/obj/screen/robot/lamp - name = "headlamp" - icon_state = "lamp0" - -/obj/screen/robot/lamp/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.control_headlamp() - -/obj/screen/robot/thrusters - name = "ion thrusters" - icon_state = "ionpulse0" - -/obj/screen/robot/thrusters/Click() - if(..()) - return - var/mob/living/silicon/robot/R = usr - R.toggle_ionpulse() - -/obj/screen/robot/sensors - name = "Sensor Augmentation" - icon_state = "cyborg_sensor" - -/obj/screen/robot/sensors/Click() - if(..()) - return - var/mob/living/silicon/S = usr - S.toggle_sensors() - -/obj/screen/robot/language_menu - name = "silicon language selection" - icon_state = "talk_wheel" - -/obj/screen/robot/language_menu/Click() - if(..()) - return - var/mob/living/silicon/S = usr - S.open_language_menu(usr) - -/datum/hud/robot - ui_style = 'icons/mob/screen_cyborg.dmi' - -/datum/hud/robot/New(mob/owner) - ..() - var/mob/living/silicon/robot/mymobR = mymob - var/obj/screen/using - - using = new/obj/screen/robot/language_menu - using.screen_loc = ui_borg_language_menu - using.hud = src - static_inventory += using - -//Radio - using = new /obj/screen/robot/radio() - using.screen_loc = ui_borg_radio - using.hud = src - static_inventory += using - -//Module select - using = new /obj/screen/robot/module1() - using.screen_loc = ui_inv1 - using.hud = src - static_inventory += using - mymobR.inv1 = using - - using = new /obj/screen/robot/module2() - using.screen_loc = ui_inv2 - using.hud = src - static_inventory += using - mymobR.inv2 = using - - using = new /obj/screen/robot/module3() - using.screen_loc = ui_inv3 - using.hud = src - static_inventory += using - mymobR.inv3 = using - -//End of module select - -//Photography stuff - using = new /obj/screen/ai/image_take() - using.screen_loc = ui_borg_camera - using.hud = src - static_inventory += using - - using = new /obj/screen/ai/image_view() - using.screen_loc = ui_borg_album - using.hud = src - static_inventory += using - -//Sec/Med HUDs - using = new /obj/screen/robot/sensors() - using.screen_loc = ui_borg_sensor - using.hud = src - static_inventory += using - -//Headlamp control - using = new /obj/screen/robot/lamp() - using.screen_loc = ui_borg_lamp - using.hud = src - static_inventory += using - mymobR.lamp_button = using - -//Thrusters - using = new /obj/screen/robot/thrusters() - using.screen_loc = ui_borg_thrusters - using.hud = src - static_inventory += using - mymobR.thruster_button = using - -//Intent - action_intent = new /obj/screen/act_intent/robot() - action_intent.icon_state = mymob.a_intent - action_intent.hud = src - static_inventory += action_intent - -//Health - healths = new /obj/screen/healths/robot() - healths.hud = src - infodisplay += healths - -//Installed Module - mymobR.hands = new /obj/screen/robot/module() - mymobR.hands.screen_loc = ui_borg_module - static_inventory += mymobR.hands - -//Store - module_store_icon = new /obj/screen/robot/store() - module_store_icon.hud = src - module_store_icon.screen_loc = ui_borg_store - - pull_icon = new /obj/screen/pull() - pull_icon.icon = 'icons/mob/screen_cyborg.dmi' - pull_icon.hud = src - pull_icon.update_icon() - pull_icon.screen_loc = ui_borg_pull - hotkeybuttons += pull_icon - - - zone_select = new /obj/screen/zone_sel/robot() - zone_select.hud = src - zone_select.update_icon() - static_inventory += zone_select - - -/datum/hud/proc/toggle_show_robot_modules() - if(!iscyborg(mymob)) - return - - var/mob/living/silicon/robot/R = mymob - - R.shown_robot_modules = !R.shown_robot_modules - update_robot_modules_display() - -/datum/hud/proc/update_robot_modules_display(mob/viewer) - if(!iscyborg(mymob)) - return - - var/mob/living/silicon/robot/R = mymob - - var/mob/screenmob = viewer || R - - if(!R.module) - return - - if(!R.client) - return - - if(R.shown_robot_modules && screenmob.hud_used.hud_shown) - //Modules display is shown - screenmob.client.screen += module_store_icon //"store" icon - - if(!R.module.modules) - to_chat(usr, "Selected module has no modules to select") - return - - if(!R.robot_modules_background) - return - - var/display_rows = CEILING(length(R.module.get_inactive_modules()) / 8, 1) - R.robot_modules_background.screen_loc = "CENTER-4:16,SOUTH+1:7 to CENTER+3:16,SOUTH+[display_rows]:7" - screenmob.client.screen += R.robot_modules_background - - var/x = -4 //Start at CENTER-4,SOUTH+1 - var/y = 1 - - for(var/atom/movable/A in R.module.get_inactive_modules()) - //Module is not currently active - screenmob.client.screen += A - if(x < 0) - A.screen_loc = "CENTER[x]:16,SOUTH+[y]:7" - else - A.screen_loc = "CENTER+[x]:16,SOUTH+[y]:7" - A.layer = ABOVE_HUD_LAYER - A.plane = ABOVE_HUD_PLANE - - x++ - if(x == 4) - x = -4 - y++ - - else - //Modules display is hidden - screenmob.client.screen -= module_store_icon //"store" icon - - for(var/atom/A in R.module.get_inactive_modules()) - //Module is not currently active - screenmob.client.screen -= A - R.shown_robot_modules = 0 - screenmob.client.screen -= R.robot_modules_background - -/datum/hud/robot/persistent_inventory_update(mob/viewer) - if(!mymob) - return - var/mob/living/silicon/robot/R = mymob - - var/mob/screenmob = viewer || R - - if(screenmob.hud_used) - if(screenmob.hud_used.hud_shown) - for(var/i in 1 to R.held_items.len) - var/obj/item/I = R.held_items[i] - if(I) - switch(i) - if(1) - I.screen_loc = ui_inv1 - if(2) - I.screen_loc = ui_inv2 - if(3) - I.screen_loc = ui_inv3 - else - return - screenmob.client.screen += I - else - for(var/obj/item/I in R.held_items) - screenmob.client.screen -= I +/obj/screen/robot + icon = 'icons/mob/screen_cyborg.dmi' + +/obj/screen/robot/module + name = "cyborg module" + icon_state = "nomod" + +/obj/screen/robot/Click() + if(isobserver(usr)) + return 1 + +/obj/screen/robot/module/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + if(R.module.type != /obj/item/robot_module) + R.hud_used.toggle_show_robot_modules() + return 1 + R.pick_module() + +/obj/screen/robot/module1 + name = "module1" + icon_state = "inv1" + +/obj/screen/robot/module1/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.toggle_module(1) + +/obj/screen/robot/module2 + name = "module2" + icon_state = "inv2" + +/obj/screen/robot/module2/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.toggle_module(2) + +/obj/screen/robot/module3 + name = "module3" + icon_state = "inv3" + +/obj/screen/robot/module3/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.toggle_module(3) + +/obj/screen/robot/radio + name = "radio" + icon_state = "radio" + +/obj/screen/robot/radio/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.radio.interact(R) + +/obj/screen/robot/store + name = "store" + icon_state = "store" + +/obj/screen/robot/store/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.uneq_active() + +/obj/screen/robot/lamp + name = "headlamp" + icon_state = "lamp0" + +/obj/screen/robot/lamp/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.control_headlamp() + +/obj/screen/robot/thrusters + name = "ion thrusters" + icon_state = "ionpulse0" + +/obj/screen/robot/thrusters/Click() + if(..()) + return + var/mob/living/silicon/robot/R = usr + R.toggle_ionpulse() + +/obj/screen/robot/sensors + name = "Sensor Augmentation" + icon_state = "cyborg_sensor" + +/obj/screen/robot/sensors/Click() + if(..()) + return + var/mob/living/silicon/S = usr + S.toggle_sensors() + +/obj/screen/robot/language_menu + name = "silicon language selection" + icon_state = "talk_wheel" + +/obj/screen/robot/language_menu/Click() + if(..()) + return + var/mob/living/silicon/S = usr + S.open_language_menu(usr) + +/datum/hud/robot + ui_style = 'icons/mob/screen_cyborg.dmi' + +/datum/hud/robot/New(mob/owner) + ..() + var/mob/living/silicon/robot/mymobR = mymob + var/obj/screen/using + + using = new/obj/screen/robot/language_menu + using.screen_loc = ui_borg_language_menu + using.hud = src + static_inventory += using + +//Radio + using = new /obj/screen/robot/radio() + using.screen_loc = ui_borg_radio + using.hud = src + static_inventory += using + +//Module select + using = new /obj/screen/robot/module1() + using.screen_loc = ui_inv1 + using.hud = src + static_inventory += using + mymobR.inv1 = using + + using = new /obj/screen/robot/module2() + using.screen_loc = ui_inv2 + using.hud = src + static_inventory += using + mymobR.inv2 = using + + using = new /obj/screen/robot/module3() + using.screen_loc = ui_inv3 + using.hud = src + static_inventory += using + mymobR.inv3 = using + +//End of module select + +//Photography stuff + using = new /obj/screen/ai/image_take() + using.screen_loc = ui_borg_camera + using.hud = src + static_inventory += using + + using = new /obj/screen/ai/image_view() + using.screen_loc = ui_borg_album + using.hud = src + static_inventory += using + +//Sec/Med HUDs + using = new /obj/screen/robot/sensors() + using.screen_loc = ui_borg_sensor + using.hud = src + static_inventory += using + +//Headlamp control + using = new /obj/screen/robot/lamp() + using.screen_loc = ui_borg_lamp + using.hud = src + static_inventory += using + mymobR.lamp_button = using + +//Thrusters + using = new /obj/screen/robot/thrusters() + using.screen_loc = ui_borg_thrusters + using.hud = src + static_inventory += using + mymobR.thruster_button = using + +//Intent + action_intent = new /obj/screen/act_intent/robot() + action_intent.icon_state = mymob.a_intent + action_intent.hud = src + static_inventory += action_intent + +//Health + healths = new /obj/screen/healths/robot() + healths.hud = src + infodisplay += healths + +//Installed Module + mymobR.hands = new /obj/screen/robot/module() + mymobR.hands.screen_loc = ui_borg_module + static_inventory += mymobR.hands + +//Store + module_store_icon = new /obj/screen/robot/store() + module_store_icon.hud = src + module_store_icon.screen_loc = ui_borg_store + + pull_icon = new /obj/screen/pull() + pull_icon.icon = 'icons/mob/screen_cyborg.dmi' + pull_icon.hud = src + pull_icon.update_icon() + pull_icon.screen_loc = ui_borg_pull + hotkeybuttons += pull_icon + + + zone_select = new /obj/screen/zone_sel/robot() + zone_select.hud = src + zone_select.update_icon() + static_inventory += zone_select + + +/datum/hud/proc/toggle_show_robot_modules() + if(!iscyborg(mymob)) + return + + var/mob/living/silicon/robot/R = mymob + + R.shown_robot_modules = !R.shown_robot_modules + update_robot_modules_display() + +/datum/hud/proc/update_robot_modules_display(mob/viewer) + if(!iscyborg(mymob)) + return + + var/mob/living/silicon/robot/R = mymob + + var/mob/screenmob = viewer || R + + if(!R.module) + return + + if(!R.client) + return + + if(R.shown_robot_modules && screenmob.hud_used.hud_shown) + //Modules display is shown + screenmob.client.screen += module_store_icon //"store" icon + + if(!R.module.modules) + to_chat(usr, "Selected module has no modules to select") + return + + if(!R.robot_modules_background) + return + + var/display_rows = CEILING(length(R.module.get_inactive_modules()) / 8, 1) + R.robot_modules_background.screen_loc = "CENTER-4:16,SOUTH+1:7 to CENTER+3:16,SOUTH+[display_rows]:7" + screenmob.client.screen += R.robot_modules_background + + var/x = -4 //Start at CENTER-4,SOUTH+1 + var/y = 1 + + for(var/atom/movable/A in R.module.get_inactive_modules()) + //Module is not currently active + screenmob.client.screen += A + if(x < 0) + A.screen_loc = "CENTER[x]:16,SOUTH+[y]:7" + else + A.screen_loc = "CENTER+[x]:16,SOUTH+[y]:7" + A.layer = ABOVE_HUD_LAYER + A.plane = ABOVE_HUD_PLANE + + x++ + if(x == 4) + x = -4 + y++ + + else + //Modules display is hidden + screenmob.client.screen -= module_store_icon //"store" icon + + for(var/atom/A in R.module.get_inactive_modules()) + //Module is not currently active + screenmob.client.screen -= A + R.shown_robot_modules = 0 + screenmob.client.screen -= R.robot_modules_background + +/datum/hud/robot/persistent_inventory_update(mob/viewer) + if(!mymob) + return + var/mob/living/silicon/robot/R = mymob + + var/mob/screenmob = viewer || R + + if(screenmob.hud_used) + if(screenmob.hud_used.hud_shown) + for(var/i in 1 to R.held_items.len) + var/obj/item/I = R.held_items[i] + if(I) + switch(i) + if(1) + I.screen_loc = ui_inv1 + if(2) + I.screen_loc = ui_inv2 + if(3) + I.screen_loc = ui_inv3 + else + return + screenmob.client.screen += I + else + for(var/obj/item/I in R.held_items) + screenmob.client.screen -= I diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index dec743d35c..c8926507bc 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -1,715 +1,715 @@ -/* - Screen objects - Todo: improve/re-implement - - Screen objects are only used for the hud and should not appear anywhere "in-game". - They are used with the client/screen list and the screen_loc var. - For more information, see the byond documentation on the screen_loc and screen vars. -*/ -/obj/screen - name = "" - icon = 'icons/mob/screen_gen.dmi' - layer = HUD_LAYER - plane = HUD_PLANE - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - appearance_flags = APPEARANCE_UI - var/obj/master = null //A reference to the object in the slot. Grabs or items, generally. - var/datum/hud/hud = null // A reference to the owner HUD, if any. - -/obj/screen/take_damage() - return - -/obj/screen/Destroy() - master = null - hud = null - return ..() - -/obj/screen/examine(mob/user) - return list() - -/obj/screen/orbit() - return - -/obj/screen/proc/component_click(obj/screen/component_button/component, params) - return - -/obj/screen/text - icon = null - icon_state = null - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - screen_loc = "CENTER-7,CENTER-7" - maptext_height = 480 - maptext_width = 480 - -/obj/screen/swap_hand - layer = HUD_LAYER - plane = HUD_PLANE - name = "swap hand" - -/obj/screen/swap_hand/Click() - // At this point in client Click() code we have passed the 1/10 sec check and little else - // We don't even know if it's a middle click - if(world.time <= usr.next_move) - return 1 - - if(usr.incapacitated()) - return 1 - - if(ismob(usr)) - var/mob/M = usr - M.swap_hand() - return 1 - -/obj/screen/craft - name = "crafting menu" - icon = 'icons/mob/screen_midnight.dmi' - icon_state = "craft" - screen_loc = ui_crafting - -/obj/screen/craft/Click() - var/mob/living/M = usr - if(isobserver(usr)) - return - M.OpenCraftingMenu() - -/obj/screen/area_creator - name = "create new area" - icon = 'icons/mob/screen_midnight.dmi' - icon_state = "area_edit" - screen_loc = ui_building - -/obj/screen/area_creator/Click() - if(usr.incapacitated() || (isobserver(usr) && !IsAdminGhost(usr))) - return TRUE - var/area/A = get_area(usr) - if(!A.outdoors) - to_chat(usr, "There is already a defined structure here.") - return TRUE - create_area(usr) - -/obj/screen/language_menu - name = "language menu" - icon = 'icons/mob/screen_midnight.dmi' - icon_state = "talk_wheel" - screen_loc = ui_language_menu - -/obj/screen/language_menu/Click() - var/mob/M = usr - var/datum/language_holder/H = M.get_language_holder() - H.open_language_menu(usr) - -/obj/screen/inventory - var/slot_id // The indentifier for the slot. It has nothing to do with ID cards. - var/icon_empty // Icon when empty. For now used only by humans. - var/icon_full // Icon when contains an item. For now used only by humans. - var/list/object_overlays = list() - layer = HUD_LAYER - plane = HUD_PLANE - -/obj/screen/inventory/Click(location, control, params) - // At this point in client Click() code we have passed the 1/10 sec check and little else - // We don't even know if it's a middle click - if(world.time <= usr.next_move) - return TRUE - - if(usr.incapacitated()) - return TRUE - if(ismecha(usr.loc)) // stops inventory actions in a mech - return TRUE - - if(hud?.mymob && slot_id) - var/obj/item/inv_item = hud.mymob.get_item_by_slot(slot_id) - if(inv_item) - return inv_item.Click(location, control, params) - - if(usr.attack_ui(slot_id)) - usr.update_inv_hands() - return TRUE - -/obj/screen/inventory/MouseEntered() - ..() - add_overlays() - -/obj/screen/inventory/MouseExited() - ..() - cut_overlay(object_overlays) - object_overlays.Cut() - -/obj/screen/inventory/update_icon_state() - if(!icon_empty) - icon_empty = icon_state - - if(hud?.mymob && slot_id && icon_full) - if(hud.mymob.get_item_by_slot(slot_id)) - icon_state = icon_full - else - icon_state = icon_empty - -/obj/screen/inventory/proc/add_overlays() - var/mob/user = hud?.mymob - - if(!user || !slot_id) - return - - var/obj/item/holding = user.get_active_held_item() - - if(!holding || user.get_item_by_slot(slot_id)) - return - - var/image/item_overlay = image(holding) - item_overlay.alpha = 92 - - if(!user.can_equip(holding, slot_id, TRUE)) - item_overlay.color = "#FF0000" - else - item_overlay.color = "#00ff00" - - object_overlays += item_overlay - add_overlay(object_overlays) - -/obj/screen/inventory/hand - var/mutable_appearance/handcuff_overlay - var/static/mutable_appearance/blocked_overlay = mutable_appearance('icons/mob/screen_gen.dmi', "blocked") - var/held_index = 0 - -/obj/screen/inventory/hand/update_icon() - . = ..() - - if(!handcuff_overlay) - var/state = (!(held_index % 2)) ? "markus" : "gabrielle" - handcuff_overlay = mutable_appearance('icons/mob/screen_gen.dmi', state) - - cut_overlay(list(handcuff_overlay, blocked_overlay, "hand_active")) - - if(!hud?.mymob) - return - - if(iscarbon(hud.mymob)) - var/mob/living/carbon/C = hud.mymob - if(C.handcuffed) - add_overlay(handcuff_overlay) - - if(held_index) - if(!C.has_hand_for_held_index(held_index)) - add_overlay(blocked_overlay) - - if(held_index == hud.mymob.active_hand_index) - add_overlay("hand_active") - - -/obj/screen/inventory/hand/Click(location, control, params) - // At this point in client Click() code we have passed the 1/10 sec check and little else - // We don't even know if it's a middle click - var/mob/user = hud?.mymob - if(usr != user) - return TRUE - if(world.time <= user.next_move) - return TRUE - if(user.incapacitated()) - return TRUE - if (ismecha(user.loc)) // stops inventory actions in a mech - return TRUE - - if(user.active_hand_index == held_index) - var/obj/item/I = user.get_active_held_item() - if(I) - I.Click(location, control, params) - else - user.swap_hand(held_index) - return TRUE - -/obj/screen/close - name = "close" - layer = ABOVE_HUD_LAYER - plane = ABOVE_HUD_PLANE - icon_state = "backpack_close" - -/obj/screen/close/Initialize(mapload, new_master) - . = ..() - master = new_master - -/obj/screen/close/Click() - var/datum/component/storage/S = master - S.hide_from(usr) - return TRUE - -/obj/screen/drop - name = "drop" - icon = 'icons/mob/screen_midnight.dmi' - icon_state = "act_drop" - layer = HUD_LAYER - plane = HUD_PLANE - -/obj/screen/drop/Click() - if(usr.stat == CONSCIOUS) - usr.dropItemToGround(usr.get_active_held_item()) - -/obj/screen/act_intent - name = "intent" - icon_state = "help" - screen_loc = ui_acti - -/obj/screen/act_intent/Click(location, control, params) - usr.a_intent_change(INTENT_HOTKEY_RIGHT) - -/obj/screen/act_intent/segmented/Click(location, control, params) - if(usr.client.prefs.toggles & INTENT_STYLE) - var/_x = text2num(params2list(params)["icon-x"]) - var/_y = text2num(params2list(params)["icon-y"]) - - if(_x<=16 && _y<=16) - usr.a_intent_change(INTENT_HARM) - - else if(_x<=16 && _y>=17) - usr.a_intent_change(INTENT_HELP) - - else if(_x>=17 && _y<=16) - usr.a_intent_change(INTENT_GRAB) - - else if(_x>=17 && _y>=17) - usr.a_intent_change(INTENT_DISARM) - else - return ..() - -/obj/screen/act_intent/alien - icon = 'icons/mob/screen_alien.dmi' - screen_loc = ui_movi - -/obj/screen/act_intent/robot - icon = 'icons/mob/screen_cyborg.dmi' - screen_loc = ui_borg_intents - -/obj/screen/internals - name = "toggle internals" - icon_state = "internal0" - screen_loc = ui_internal - -/obj/screen/internals/Click() - if(!iscarbon(usr)) - return - var/mob/living/carbon/C = usr - if(C.incapacitated()) - return - - if(C.internal) - C.internal = null - to_chat(C, "You are no longer running on internals.") - icon_state = "internal0" - else - if(!C.getorganslot(ORGAN_SLOT_BREATHING_TUBE)) - var/obj/item/clothing/check - var/internals = FALSE - - for(check in GET_INTERNAL_SLOTS(C)) - if(istype(check, /obj/item/clothing/mask)) - var/obj/item/clothing/mask/M = check - if(M.mask_adjusted) - M.adjustmask(C) - if(CHECK_BITFIELD(check.clothing_flags, ALLOWINTERNALS)) - internals = TRUE - if(!internals) - to_chat(C, "You are not wearing an internals mask!") - return - - var/obj/item/I = C.is_holding_item_of_type(/obj/item/tank) - if(I) - to_chat(C, "You are now running on internals from [I] in your [C.get_held_index_name(C.get_held_index_of_item(I))].") - C.internal = I - else if(ishuman(C)) - var/mob/living/carbon/human/H = C - if(istype(H.s_store, /obj/item/tank)) - to_chat(H, "You are now running on internals from [H.s_store] on your [H.wear_suit.name].") - H.internal = H.s_store - else if(istype(H.belt, /obj/item/tank)) - to_chat(H, "You are now running on internals from [H.belt] on your belt.") - H.internal = H.belt - else if(istype(H.l_store, /obj/item/tank)) - to_chat(H, "You are now running on internals from [H.l_store] in your left pocket.") - H.internal = H.l_store - else if(istype(H.r_store, /obj/item/tank)) - to_chat(H, "You are now running on internals from [H.r_store] in your right pocket.") - H.internal = H.r_store - - //Separate so CO2 jetpacks are a little less cumbersome. - if(!C.internal && istype(C.back, /obj/item/tank)) - to_chat(C, "You are now running on internals from [C.back] on your back.") - C.internal = C.back - - if(C.internal) - icon_state = "internal1" - else - to_chat(C, "You don't have an oxygen tank!") - return - C.update_action_buttons_icon() - -/obj/screen/mov_intent - name = "run/walk toggle" - icon = 'icons/mob/screen_midnight.dmi' - icon_state = "running" - -/obj/screen/mov_intent/Click() - toggle(usr) - -/obj/screen/mov_intent/update_icon_state() - switch(hud?.mymob?.m_intent) - if(MOVE_INTENT_WALK) - icon_state = "walking" - if(MOVE_INTENT_RUN) - icon_state = "running" - -/obj/screen/mov_intent/proc/toggle(mob/user) - if(isobserver(user)) - return - user.toggle_move_intent(user) - -/obj/screen/pull - name = "stop pulling" - icon = 'icons/mob/screen_midnight.dmi' - icon_state = "pull" - -/obj/screen/pull/Click() - if(isobserver(usr)) - return - usr.stop_pulling() - -/obj/screen/pull/update_icon_state() - if(hud?.mymob?.pulling) - icon_state = "pull" - else - icon_state = "pull0" - -/obj/screen/resist - name = "resist" - icon = 'icons/mob/screen_midnight.dmi' - icon_state = "act_resist" - layer = HUD_LAYER - plane = HUD_PLANE - -/obj/screen/resist/Click() - if(isliving(usr)) - var/mob/living/L = usr - L.resist() - -/obj/screen/rest - name = "rest" - icon = 'icons/mob/screen_midnight.dmi' - icon_state = "act_rest" - layer = HUD_LAYER - plane = HUD_PLANE - -/obj/screen/rest/Click() - if(isliving(usr)) - var/mob/living/L = usr - L.lay_down() - -/obj/screen/rest/update_icon_state() - var/mob/living/user = hud?.mymob - if(!istype(user)) - return - if(!user.resting) - icon_state = "act_rest" - else - icon_state = "act_rest0" - -/obj/screen/storage - name = "storage" - icon_state = "block" - screen_loc = "7,7 to 10,8" - layer = HUD_LAYER - plane = HUD_PLANE - -/obj/screen/storage/Initialize(mapload, new_master) - . = ..() - master = new_master - -/obj/screen/storage/Click(location, control, params) - if(world.time <= usr.next_move) - return TRUE - if(usr.incapacitated()) - return TRUE - if (ismecha(usr.loc)) // stops inventory actions in a mech - return TRUE - if(master) - var/obj/item/I = usr.get_active_held_item() - if(I) - master.attackby(null, I, usr, params) - return TRUE - -/obj/screen/throw_catch - name = "throw/catch" - icon = 'icons/mob/screen_midnight.dmi' - icon_state = "act_throw_off" - -/obj/screen/throw_catch/Click() - if(iscarbon(usr)) - var/mob/living/carbon/C = usr - C.toggle_throw_mode() - -/obj/screen/zone_sel - name = "damage zone" - icon_state = "zone_sel" - screen_loc = ui_zonesel - var/overlay_icon = 'icons/mob/screen_gen.dmi' - var/static/list/hover_overlays_cache = list() - var/hovering - -/obj/screen/zone_sel/Click(location, control,params) - if(isobserver(usr)) - return - - var/list/PL = params2list(params) - var/icon_x = text2num(PL["icon-x"]) - var/icon_y = text2num(PL["icon-y"]) - var/choice = get_zone_at(icon_x, icon_y) - if (!choice) - return 1 - - return set_selected_zone(choice, usr) - -/obj/screen/zone_sel/MouseEntered(location, control, params) - MouseMove(location, control, params) - -/obj/screen/zone_sel/MouseMove(location, control, params) - if(isobserver(usr)) - return - - var/list/PL = params2list(params) - var/icon_x = text2num(PL["icon-x"]) - var/icon_y = text2num(PL["icon-y"]) - var/choice = get_zone_at(icon_x, icon_y) - - if(hovering == choice) - return - vis_contents -= hover_overlays_cache[hovering] - hovering = choice - - var/obj/effect/overlay/zone_sel/overlay_object = hover_overlays_cache[choice] - if(!overlay_object) - overlay_object = new - overlay_object.icon_state = "[choice]" - hover_overlays_cache[choice] = overlay_object - vis_contents += overlay_object - -/obj/effect/overlay/zone_sel - icon = 'icons/mob/screen_gen.dmi' - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - alpha = 128 - anchored = TRUE - layer = ABOVE_HUD_LAYER - plane = ABOVE_HUD_PLANE - -/obj/screen/zone_sel/MouseExited(location, control, params) - if(!isobserver(usr) && hovering) - vis_contents -= hover_overlays_cache[hovering] - hovering = null - -/obj/screen/zone_sel/proc/get_zone_at(icon_x, icon_y) - switch(icon_y) - if(1 to 9) //Legs - switch(icon_x) - if(10 to 15) - return BODY_ZONE_R_LEG - if(17 to 22) - return BODY_ZONE_L_LEG - if(10 to 13) //Hands and groin - switch(icon_x) - if(8 to 11) - return BODY_ZONE_R_ARM - if(12 to 20) - return BODY_ZONE_PRECISE_GROIN - if(21 to 24) - return BODY_ZONE_L_ARM - if(14 to 22) //Chest and arms to shoulders - switch(icon_x) - if(8 to 11) - return BODY_ZONE_R_ARM - if(12 to 20) - return BODY_ZONE_CHEST - if(21 to 24) - return BODY_ZONE_L_ARM - if(23 to 30) //Head, but we need to check for eye or mouth - if(icon_x in 12 to 20) - switch(icon_y) - if(23 to 24) - if(icon_x in 15 to 17) - return BODY_ZONE_PRECISE_MOUTH - if(26) //Eyeline, eyes are on 15 and 17 - if(icon_x in 14 to 18) - return BODY_ZONE_PRECISE_EYES - if(25 to 27) - if(icon_x in 15 to 17) - return BODY_ZONE_PRECISE_EYES - return BODY_ZONE_HEAD - -/obj/screen/zone_sel/proc/set_selected_zone(choice, mob/user) - if(user != hud?.mymob) - return - - if(choice != hud.mymob.zone_selected) - hud.mymob.zone_selected = choice - update_icon() - - return TRUE - -/obj/screen/zone_sel/update_overlays() - . = ..() - if(!hud?.mymob) - return - . += mutable_appearance(overlay_icon, "[hud.mymob.zone_selected]") - -/obj/screen/zone_sel/alien - icon = 'icons/mob/screen_alien.dmi' - overlay_icon = 'icons/mob/screen_alien.dmi' - -/obj/screen/zone_sel/robot - icon = 'icons/mob/screen_cyborg.dmi' - - -/obj/screen/flash - name = "flash" - icon_state = "blank" - blend_mode = BLEND_ADD - screen_loc = "WEST,SOUTH to EAST,NORTH" - layer = FLASH_LAYER - plane = FULLSCREEN_PLANE - -/obj/screen/damageoverlay - icon = 'icons/mob/screen_full.dmi' - icon_state = "oxydamageoverlay0" - name = "dmg" - blend_mode = BLEND_MULTIPLY - screen_loc = "CENTER-7,CENTER-7" - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - layer = UI_DAMAGE_LAYER - plane = FULLSCREEN_PLANE - -/obj/screen/healths - name = "health" - icon_state = "health0" - screen_loc = ui_health - -/obj/screen/healths/alien - icon = 'icons/mob/screen_alien.dmi' - screen_loc = ui_alien_health - -/obj/screen/healths/robot - icon = 'icons/mob/screen_cyborg.dmi' - screen_loc = ui_borg_health - -/obj/screen/healths/blob - name = "blob health" - icon_state = "block" - screen_loc = ui_internal - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - -/obj/screen/healths/blob/naut - name = "health" - icon = 'icons/mob/blob.dmi' - icon_state = "nauthealth" - -/obj/screen/healths/blob/naut/core - name = "overmind health" - screen_loc = ui_health - icon_state = "corehealth" - -/obj/screen/healths/guardian - name = "summoner health" - icon = 'icons/mob/guardian.dmi' - icon_state = "base" - screen_loc = ui_health - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - -/obj/screen/healths/clock - icon = 'icons/mob/actions.dmi' - icon_state = "bg_clock" - screen_loc = ui_health - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - -/obj/screen/healths/clock/gear - icon = 'icons/mob/clockwork_mobs.dmi' - icon_state = "bg_gear" - screen_loc = ui_internal - -/obj/screen/healths/revenant - name = "essence" - icon = 'icons/mob/actions.dmi' - icon_state = "bg_revenant" - screen_loc = ui_health - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - -/obj/screen/healths/construct - icon = 'icons/mob/screen_construct.dmi' - icon_state = "artificer_health0" - screen_loc = ui_construct_health - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - -/obj/screen/healths/lavaland_elite - icon = 'icons/mob/screen_elite.dmi' - icon_state = "elite_health0" - screen_loc = ui_health - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - -/obj/screen/healthdoll - name = "health doll" - screen_loc = ui_healthdoll - -/obj/screen/mood - name = "mood" - icon_state = "mood5" - screen_loc = ui_mood - -/obj/screen/splash - icon = 'icons/blank_title.png' - icon_state = "" - screen_loc = "1,1" - layer = SPLASHSCREEN_LAYER - plane = SPLASHSCREEN_PLANE - var/client/holder - -/obj/screen/splash/New(client/C, visible, use_previous_title) //TODO: Make this use INITIALIZE_IMMEDIATE, except its not easy - . = ..() - - holder = C - - if(!visible) - alpha = 0 - - if(!use_previous_title) - if(SStitle.icon) - icon = SStitle.icon - else - if(!SStitle.previous_icon) - qdel(src) - return - icon = SStitle.previous_icon - - holder.screen += src - -/obj/screen/splash/proc/Fade(out, qdel_after = TRUE) - if(QDELETED(src)) - return - if(out) - animate(src, alpha = 0, time = 30) - else - alpha = 0 - animate(src, alpha = 255, time = 30) - if(qdel_after) - QDEL_IN(src, 30) - -/obj/screen/splash/Destroy() - if(holder) - holder.screen -= src - holder = null - return ..() - - -/obj/screen/component_button - var/obj/screen/parent - -/obj/screen/component_button/Initialize(mapload, obj/screen/parent) - . = ..() - src.parent = parent - -/obj/screen/component_button/Click(params) - if(parent) - parent.component_click(src, params) +/* + Screen objects + Todo: improve/re-implement + + Screen objects are only used for the hud and should not appear anywhere "in-game". + They are used with the client/screen list and the screen_loc var. + For more information, see the byond documentation on the screen_loc and screen vars. +*/ +/obj/screen + name = "" + icon = 'icons/mob/screen_gen.dmi' + layer = HUD_LAYER + plane = HUD_PLANE + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + appearance_flags = APPEARANCE_UI + var/obj/master = null //A reference to the object in the slot. Grabs or items, generally. + var/datum/hud/hud = null // A reference to the owner HUD, if any. + +/obj/screen/take_damage() + return + +/obj/screen/Destroy() + master = null + hud = null + return ..() + +/obj/screen/examine(mob/user) + return list() + +/obj/screen/orbit() + return + +/obj/screen/proc/component_click(obj/screen/component_button/component, params) + return + +/obj/screen/text + icon = null + icon_state = null + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + screen_loc = "CENTER-7,CENTER-7" + maptext_height = 480 + maptext_width = 480 + +/obj/screen/swap_hand + layer = HUD_LAYER + plane = HUD_PLANE + name = "swap hand" + +/obj/screen/swap_hand/Click() + // At this point in client Click() code we have passed the 1/10 sec check and little else + // We don't even know if it's a middle click + if(world.time <= usr.next_move) + return 1 + + if(usr.incapacitated()) + return 1 + + if(ismob(usr)) + var/mob/M = usr + M.swap_hand() + return 1 + +/obj/screen/craft + name = "crafting menu" + icon = 'icons/mob/screen_midnight.dmi' + icon_state = "craft" + screen_loc = ui_crafting + +/obj/screen/craft/Click() + var/mob/living/M = usr + if(isobserver(usr)) + return + M.OpenCraftingMenu() + +/obj/screen/area_creator + name = "create new area" + icon = 'icons/mob/screen_midnight.dmi' + icon_state = "area_edit" + screen_loc = ui_building + +/obj/screen/area_creator/Click() + if(usr.incapacitated() || (isobserver(usr) && !IsAdminGhost(usr))) + return TRUE + var/area/A = get_area(usr) + if(!A.outdoors) + to_chat(usr, "There is already a defined structure here.") + return TRUE + create_area(usr) + +/obj/screen/language_menu + name = "language menu" + icon = 'icons/mob/screen_midnight.dmi' + icon_state = "talk_wheel" + screen_loc = ui_language_menu + +/obj/screen/language_menu/Click() + var/mob/M = usr + var/datum/language_holder/H = M.get_language_holder() + H.open_language_menu(usr) + +/obj/screen/inventory + var/slot_id // The indentifier for the slot. It has nothing to do with ID cards. + var/icon_empty // Icon when empty. For now used only by humans. + var/icon_full // Icon when contains an item. For now used only by humans. + var/list/object_overlays = list() + layer = HUD_LAYER + plane = HUD_PLANE + +/obj/screen/inventory/Click(location, control, params) + // At this point in client Click() code we have passed the 1/10 sec check and little else + // We don't even know if it's a middle click + if(world.time <= usr.next_move) + return TRUE + + if(usr.incapacitated()) + return TRUE + if(ismecha(usr.loc)) // stops inventory actions in a mech + return TRUE + + if(hud?.mymob && slot_id) + var/obj/item/inv_item = hud.mymob.get_item_by_slot(slot_id) + if(inv_item) + return inv_item.Click(location, control, params) + + if(usr.attack_ui(slot_id)) + usr.update_inv_hands() + return TRUE + +/obj/screen/inventory/MouseEntered() + ..() + add_overlays() + +/obj/screen/inventory/MouseExited() + ..() + cut_overlay(object_overlays) + object_overlays.Cut() + +/obj/screen/inventory/update_icon_state() + if(!icon_empty) + icon_empty = icon_state + + if(hud?.mymob && slot_id && icon_full) + if(hud.mymob.get_item_by_slot(slot_id)) + icon_state = icon_full + else + icon_state = icon_empty + +/obj/screen/inventory/proc/add_overlays() + var/mob/user = hud?.mymob + + if(!user || !slot_id) + return + + var/obj/item/holding = user.get_active_held_item() + + if(!holding || user.get_item_by_slot(slot_id)) + return + + var/image/item_overlay = image(holding) + item_overlay.alpha = 92 + + if(!user.can_equip(holding, slot_id, TRUE)) + item_overlay.color = "#FF0000" + else + item_overlay.color = "#00ff00" + + object_overlays += item_overlay + add_overlay(object_overlays) + +/obj/screen/inventory/hand + var/mutable_appearance/handcuff_overlay + var/static/mutable_appearance/blocked_overlay = mutable_appearance('icons/mob/screen_gen.dmi', "blocked") + var/held_index = 0 + +/obj/screen/inventory/hand/update_icon() + . = ..() + + if(!handcuff_overlay) + var/state = (!(held_index % 2)) ? "markus" : "gabrielle" + handcuff_overlay = mutable_appearance('icons/mob/screen_gen.dmi', state) + + cut_overlay(list(handcuff_overlay, blocked_overlay, "hand_active")) + + if(!hud?.mymob) + return + + if(iscarbon(hud.mymob)) + var/mob/living/carbon/C = hud.mymob + if(C.handcuffed) + add_overlay(handcuff_overlay) + + if(held_index) + if(!C.has_hand_for_held_index(held_index)) + add_overlay(blocked_overlay) + + if(held_index == hud.mymob.active_hand_index) + add_overlay("hand_active") + + +/obj/screen/inventory/hand/Click(location, control, params) + // At this point in client Click() code we have passed the 1/10 sec check and little else + // We don't even know if it's a middle click + var/mob/user = hud?.mymob + if(usr != user) + return TRUE + if(world.time <= user.next_move) + return TRUE + if(user.incapacitated()) + return TRUE + if (ismecha(user.loc)) // stops inventory actions in a mech + return TRUE + + if(user.active_hand_index == held_index) + var/obj/item/I = user.get_active_held_item() + if(I) + I.Click(location, control, params) + else + user.swap_hand(held_index) + return TRUE + +/obj/screen/close + name = "close" + layer = ABOVE_HUD_LAYER + plane = ABOVE_HUD_PLANE + icon_state = "backpack_close" + +/obj/screen/close/Initialize(mapload, new_master) + . = ..() + master = new_master + +/obj/screen/close/Click() + var/datum/component/storage/S = master + S.hide_from(usr) + return TRUE + +/obj/screen/drop + name = "drop" + icon = 'icons/mob/screen_midnight.dmi' + icon_state = "act_drop" + layer = HUD_LAYER + plane = HUD_PLANE + +/obj/screen/drop/Click() + if(usr.stat == CONSCIOUS) + usr.dropItemToGround(usr.get_active_held_item()) + +/obj/screen/act_intent + name = "intent" + icon_state = "help" + screen_loc = ui_acti + +/obj/screen/act_intent/Click(location, control, params) + usr.a_intent_change(INTENT_HOTKEY_RIGHT) + +/obj/screen/act_intent/segmented/Click(location, control, params) + if(usr.client.prefs.toggles & INTENT_STYLE) + var/_x = text2num(params2list(params)["icon-x"]) + var/_y = text2num(params2list(params)["icon-y"]) + + if(_x<=16 && _y<=16) + usr.a_intent_change(INTENT_HARM) + + else if(_x<=16 && _y>=17) + usr.a_intent_change(INTENT_HELP) + + else if(_x>=17 && _y<=16) + usr.a_intent_change(INTENT_GRAB) + + else if(_x>=17 && _y>=17) + usr.a_intent_change(INTENT_DISARM) + else + return ..() + +/obj/screen/act_intent/alien + icon = 'icons/mob/screen_alien.dmi' + screen_loc = ui_movi + +/obj/screen/act_intent/robot + icon = 'icons/mob/screen_cyborg.dmi' + screen_loc = ui_borg_intents + +/obj/screen/internals + name = "toggle internals" + icon_state = "internal0" + screen_loc = ui_internal + +/obj/screen/internals/Click() + if(!iscarbon(usr)) + return + var/mob/living/carbon/C = usr + if(C.incapacitated()) + return + + if(C.internal) + C.internal = null + to_chat(C, "You are no longer running on internals.") + icon_state = "internal0" + else + if(!C.getorganslot(ORGAN_SLOT_BREATHING_TUBE)) + var/obj/item/clothing/check + var/internals = FALSE + + for(check in GET_INTERNAL_SLOTS(C)) + if(istype(check, /obj/item/clothing/mask)) + var/obj/item/clothing/mask/M = check + if(M.mask_adjusted) + M.adjustmask(C) + if(CHECK_BITFIELD(check.clothing_flags, ALLOWINTERNALS)) + internals = TRUE + if(!internals) + to_chat(C, "You are not wearing an internals mask!") + return + + var/obj/item/I = C.is_holding_item_of_type(/obj/item/tank) + if(I) + to_chat(C, "You are now running on internals from [I] in your [C.get_held_index_name(C.get_held_index_of_item(I))].") + C.internal = I + else if(ishuman(C)) + var/mob/living/carbon/human/H = C + if(istype(H.s_store, /obj/item/tank)) + to_chat(H, "You are now running on internals from [H.s_store] on your [H.wear_suit.name].") + H.internal = H.s_store + else if(istype(H.belt, /obj/item/tank)) + to_chat(H, "You are now running on internals from [H.belt] on your belt.") + H.internal = H.belt + else if(istype(H.l_store, /obj/item/tank)) + to_chat(H, "You are now running on internals from [H.l_store] in your left pocket.") + H.internal = H.l_store + else if(istype(H.r_store, /obj/item/tank)) + to_chat(H, "You are now running on internals from [H.r_store] in your right pocket.") + H.internal = H.r_store + + //Separate so CO2 jetpacks are a little less cumbersome. + if(!C.internal && istype(C.back, /obj/item/tank)) + to_chat(C, "You are now running on internals from [C.back] on your back.") + C.internal = C.back + + if(C.internal) + icon_state = "internal1" + else + to_chat(C, "You don't have an oxygen tank!") + return + C.update_action_buttons_icon() + +/obj/screen/mov_intent + name = "run/walk toggle" + icon = 'icons/mob/screen_midnight.dmi' + icon_state = "running" + +/obj/screen/mov_intent/Click() + toggle(usr) + +/obj/screen/mov_intent/update_icon_state() + switch(hud?.mymob?.m_intent) + if(MOVE_INTENT_WALK) + icon_state = "walking" + if(MOVE_INTENT_RUN) + icon_state = "running" + +/obj/screen/mov_intent/proc/toggle(mob/user) + if(isobserver(user)) + return + user.toggle_move_intent(user) + +/obj/screen/pull + name = "stop pulling" + icon = 'icons/mob/screen_midnight.dmi' + icon_state = "pull" + +/obj/screen/pull/Click() + if(isobserver(usr)) + return + usr.stop_pulling() + +/obj/screen/pull/update_icon_state() + if(hud?.mymob?.pulling) + icon_state = "pull" + else + icon_state = "pull0" + +/obj/screen/resist + name = "resist" + icon = 'icons/mob/screen_midnight.dmi' + icon_state = "act_resist" + layer = HUD_LAYER + plane = HUD_PLANE + +/obj/screen/resist/Click() + if(isliving(usr)) + var/mob/living/L = usr + L.resist() + +/obj/screen/rest + name = "rest" + icon = 'icons/mob/screen_midnight.dmi' + icon_state = "act_rest" + layer = HUD_LAYER + plane = HUD_PLANE + +/obj/screen/rest/Click() + if(isliving(usr)) + var/mob/living/L = usr + L.lay_down() + +/obj/screen/rest/update_icon_state() + var/mob/living/user = hud?.mymob + if(!istype(user)) + return + if(!user.resting) + icon_state = "act_rest" + else + icon_state = "act_rest0" + +/obj/screen/storage + name = "storage" + icon_state = "block" + screen_loc = "7,7 to 10,8" + layer = HUD_LAYER + plane = HUD_PLANE + +/obj/screen/storage/Initialize(mapload, new_master) + . = ..() + master = new_master + +/obj/screen/storage/Click(location, control, params) + if(world.time <= usr.next_move) + return TRUE + if(usr.incapacitated()) + return TRUE + if (ismecha(usr.loc)) // stops inventory actions in a mech + return TRUE + if(master) + var/obj/item/I = usr.get_active_held_item() + if(I) + master.attackby(null, I, usr, params) + return TRUE + +/obj/screen/throw_catch + name = "throw/catch" + icon = 'icons/mob/screen_midnight.dmi' + icon_state = "act_throw_off" + +/obj/screen/throw_catch/Click() + if(iscarbon(usr)) + var/mob/living/carbon/C = usr + C.toggle_throw_mode() + +/obj/screen/zone_sel + name = "damage zone" + icon_state = "zone_sel" + screen_loc = ui_zonesel + var/overlay_icon = 'icons/mob/screen_gen.dmi' + var/static/list/hover_overlays_cache = list() + var/hovering + +/obj/screen/zone_sel/Click(location, control,params) + if(isobserver(usr)) + return + + var/list/PL = params2list(params) + var/icon_x = text2num(PL["icon-x"]) + var/icon_y = text2num(PL["icon-y"]) + var/choice = get_zone_at(icon_x, icon_y) + if (!choice) + return 1 + + return set_selected_zone(choice, usr) + +/obj/screen/zone_sel/MouseEntered(location, control, params) + MouseMove(location, control, params) + +/obj/screen/zone_sel/MouseMove(location, control, params) + if(isobserver(usr)) + return + + var/list/PL = params2list(params) + var/icon_x = text2num(PL["icon-x"]) + var/icon_y = text2num(PL["icon-y"]) + var/choice = get_zone_at(icon_x, icon_y) + + if(hovering == choice) + return + vis_contents -= hover_overlays_cache[hovering] + hovering = choice + + var/obj/effect/overlay/zone_sel/overlay_object = hover_overlays_cache[choice] + if(!overlay_object) + overlay_object = new + overlay_object.icon_state = "[choice]" + hover_overlays_cache[choice] = overlay_object + vis_contents += overlay_object + +/obj/effect/overlay/zone_sel + icon = 'icons/mob/screen_gen.dmi' + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + alpha = 128 + anchored = TRUE + layer = ABOVE_HUD_LAYER + plane = ABOVE_HUD_PLANE + +/obj/screen/zone_sel/MouseExited(location, control, params) + if(!isobserver(usr) && hovering) + vis_contents -= hover_overlays_cache[hovering] + hovering = null + +/obj/screen/zone_sel/proc/get_zone_at(icon_x, icon_y) + switch(icon_y) + if(1 to 9) //Legs + switch(icon_x) + if(10 to 15) + return BODY_ZONE_R_LEG + if(17 to 22) + return BODY_ZONE_L_LEG + if(10 to 13) //Hands and groin + switch(icon_x) + if(8 to 11) + return BODY_ZONE_R_ARM + if(12 to 20) + return BODY_ZONE_PRECISE_GROIN + if(21 to 24) + return BODY_ZONE_L_ARM + if(14 to 22) //Chest and arms to shoulders + switch(icon_x) + if(8 to 11) + return BODY_ZONE_R_ARM + if(12 to 20) + return BODY_ZONE_CHEST + if(21 to 24) + return BODY_ZONE_L_ARM + if(23 to 30) //Head, but we need to check for eye or mouth + if(icon_x in 12 to 20) + switch(icon_y) + if(23 to 24) + if(icon_x in 15 to 17) + return BODY_ZONE_PRECISE_MOUTH + if(26) //Eyeline, eyes are on 15 and 17 + if(icon_x in 14 to 18) + return BODY_ZONE_PRECISE_EYES + if(25 to 27) + if(icon_x in 15 to 17) + return BODY_ZONE_PRECISE_EYES + return BODY_ZONE_HEAD + +/obj/screen/zone_sel/proc/set_selected_zone(choice, mob/user) + if(user != hud?.mymob) + return + + if(choice != hud.mymob.zone_selected) + hud.mymob.zone_selected = choice + update_icon() + + return TRUE + +/obj/screen/zone_sel/update_overlays() + . = ..() + if(!hud?.mymob) + return + . += mutable_appearance(overlay_icon, "[hud.mymob.zone_selected]") + +/obj/screen/zone_sel/alien + icon = 'icons/mob/screen_alien.dmi' + overlay_icon = 'icons/mob/screen_alien.dmi' + +/obj/screen/zone_sel/robot + icon = 'icons/mob/screen_cyborg.dmi' + + +/obj/screen/flash + name = "flash" + icon_state = "blank" + blend_mode = BLEND_ADD + screen_loc = "WEST,SOUTH to EAST,NORTH" + layer = FLASH_LAYER + plane = FULLSCREEN_PLANE + +/obj/screen/damageoverlay + icon = 'icons/mob/screen_full.dmi' + icon_state = "oxydamageoverlay0" + name = "dmg" + blend_mode = BLEND_MULTIPLY + screen_loc = "CENTER-7,CENTER-7" + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + layer = UI_DAMAGE_LAYER + plane = FULLSCREEN_PLANE + +/obj/screen/healths + name = "health" + icon_state = "health0" + screen_loc = ui_health + +/obj/screen/healths/alien + icon = 'icons/mob/screen_alien.dmi' + screen_loc = ui_alien_health + +/obj/screen/healths/robot + icon = 'icons/mob/screen_cyborg.dmi' + screen_loc = ui_borg_health + +/obj/screen/healths/blob + name = "blob health" + icon_state = "block" + screen_loc = ui_internal + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +/obj/screen/healths/blob/naut + name = "health" + icon = 'icons/mob/blob.dmi' + icon_state = "nauthealth" + +/obj/screen/healths/blob/naut/core + name = "overmind health" + screen_loc = ui_health + icon_state = "corehealth" + +/obj/screen/healths/guardian + name = "summoner health" + icon = 'icons/mob/guardian.dmi' + icon_state = "base" + screen_loc = ui_health + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +/obj/screen/healths/clock + icon = 'icons/mob/actions.dmi' + icon_state = "bg_clock" + screen_loc = ui_health + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +/obj/screen/healths/clock/gear + icon = 'icons/mob/clockwork_mobs.dmi' + icon_state = "bg_gear" + screen_loc = ui_internal + +/obj/screen/healths/revenant + name = "essence" + icon = 'icons/mob/actions.dmi' + icon_state = "bg_revenant" + screen_loc = ui_health + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +/obj/screen/healths/construct + icon = 'icons/mob/screen_construct.dmi' + icon_state = "artificer_health0" + screen_loc = ui_construct_health + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +/obj/screen/healths/lavaland_elite + icon = 'icons/mob/screen_elite.dmi' + icon_state = "elite_health0" + screen_loc = ui_health + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +/obj/screen/healthdoll + name = "health doll" + screen_loc = ui_healthdoll + +/obj/screen/mood + name = "mood" + icon_state = "mood5" + screen_loc = ui_mood + +/obj/screen/splash + icon = 'icons/blank_title.png' + icon_state = "" + screen_loc = "1,1" + layer = SPLASHSCREEN_LAYER + plane = SPLASHSCREEN_PLANE + var/client/holder + +/obj/screen/splash/New(client/C, visible, use_previous_title) //TODO: Make this use INITIALIZE_IMMEDIATE, except its not easy + . = ..() + + holder = C + + if(!visible) + alpha = 0 + + if(!use_previous_title) + if(SStitle.icon) + icon = SStitle.icon + else + if(!SStitle.previous_icon) + qdel(src) + return + icon = SStitle.previous_icon + + holder.screen += src + +/obj/screen/splash/proc/Fade(out, qdel_after = TRUE) + if(QDELETED(src)) + return + if(out) + animate(src, alpha = 0, time = 30) + else + alpha = 0 + animate(src, alpha = 255, time = 30) + if(qdel_after) + QDEL_IN(src, 30) + +/obj/screen/splash/Destroy() + if(holder) + holder.screen -= src + holder = null + return ..() + + +/obj/screen/component_button + var/obj/screen/parent + +/obj/screen/component_button/Initialize(mapload, obj/screen/parent) + . = ..() + src.parent = parent + +/obj/screen/component_button/Click(params) + if(parent) + parent.component_click(src, params) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index e6b2a63673..cda19dbaac 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -1,167 +1,167 @@ - -/obj/item/proc/melee_attack_chain(mob/user, atom/target, params) - if(!tool_attack_chain(user, target) && pre_attack(target, user, params)) - // Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example) - var/resolved = target.attackby(src, user, params) - if(!resolved && target && !QDELETED(src)) - afterattack(target, user, 1, params) // 1: clicking something Adjacent - - -//Checks if the item can work as a tool, calling the appropriate tool behavior on the target -/obj/item/proc/tool_attack_chain(mob/user, atom/target) - if(!tool_behaviour) - return FALSE - - return target.tool_act(user, src, tool_behaviour) - - -// Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown. -/obj/item/proc/attack_self(mob/user) - if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF, user) & COMPONENT_NO_INTERACT) - return - interact(user) - -/obj/item/proc/pre_attack(atom/A, mob/living/user, params) //do stuff before attackby! - if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, A, user, params) & COMPONENT_NO_ATTACK) - return FALSE - return TRUE //return FALSE to avoid calling attackby after this proc does stuff - -// No comment -/atom/proc/attackby(obj/item/W, mob/user, params) - if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, W, user, params) & COMPONENT_NO_AFTERATTACK) - return TRUE - return FALSE - -/obj/attackby(obj/item/I, mob/living/user, params) - return ..() || ((obj_flags & CAN_BE_HIT) && I.attack_obj(src, user)) - -/mob/living/attackby(obj/item/I, mob/living/user, params) - if(..()) - return TRUE - user.changeNext_move(CLICK_CD_MELEE) - return I.attack(src, user) - - -/obj/item/proc/attack(mob/living/M, mob/living/user) - if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, M, user) & COMPONENT_ITEM_NO_ATTACK) - return - SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, M, user) - if(item_flags & NOBLUDGEON) - return - - if(user.getStaminaLoss() >= STAMINA_SOFTCRIT) // CIT CHANGE - makes it impossible to attack in stamina softcrit - to_chat(user, "You're too exhausted.") // CIT CHANGE - ditto - return // CIT CHANGE - ditto - - if(force && damtype != STAMINA && HAS_TRAIT(user, TRAIT_PACIFISM)) - to_chat(user, "You don't want to harm other living beings!") - return - - if(!force) - playsound(loc, 'sound/weapons/tap.ogg', get_clamped_volume(), 1, -1) - else if(hitsound) - playsound(loc, hitsound, get_clamped_volume(), 1, -1) - - M.lastattacker = user.real_name - M.lastattackerckey = user.ckey - - user.do_attack_animation(M) - M.attacked_by(src, user) - - log_combat(user, M, "attacked", src.name, "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])") - add_fingerprint(user) - - user.adjustStaminaLossBuffered(getweight()*0.8)//CIT CHANGE - makes attacking things cause stamina loss - -//the equivalent of the standard version of attack() but for object targets. -/obj/item/proc/attack_obj(obj/O, mob/living/user) - if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_OBJ, O, user) & COMPONENT_NO_ATTACK_OBJ) - return - if(item_flags & NOBLUDGEON) - return - if(user.getStaminaLoss() >= STAMINA_SOFTCRIT) // CIT CHANGE - makes it impossible to attack in stamina softcrit - to_chat(user, "You're too exhausted.") // CIT CHANGE - ditto - return // CIT CHANGE - ditto - user.adjustStaminaLossBuffered(getweight()*1.2)//CIT CHANGE - makes attacking things cause stamina loss - user.changeNext_move(CLICK_CD_MELEE) - user.do_attack_animation(O) - O.attacked_by(src, user) - -/atom/movable/proc/attacked_by() - return - -/obj/attacked_by(obj/item/I, mob/living/user) - if(I.force) - visible_message("[user] has hit [src] with [I]!", null, null, COMBAT_MESSAGE_RANGE) - //only witnesses close by and the victim see a hit message. - log_combat(user, src, "attacked", I) - take_damage(I.force, I.damtype, "melee", 1) - -/mob/living/attacked_by(obj/item/I, mob/living/user) - //CIT CHANGES START HERE - combatmode and resting checks - var/totitemdamage = I.force - if(iscarbon(user)) - var/mob/living/carbon/tempcarb = user - if(!tempcarb.combatmode) - totitemdamage *= 0.5 - if(user.resting) - totitemdamage *= 0.5 - //CIT CHANGES END HERE - if(user != src && check_shields(I, totitemdamage, "the [I.name]", MELEE_ATTACK, I.armour_penetration)) - return FALSE - send_item_attack_message(I, user) - if(I.force) - apply_damage(totitemdamage, I.damtype) //CIT CHANGE - replaces I.force with totitemdamage - if(I.damtype == BRUTE && !HAS_TRAIT(src, TRAIT_NOMARROW)) - if(prob(33)) - I.add_mob_blood(src) - var/turf/location = get_turf(src) - if(iscarbon(src)) - var/mob/living/carbon/C = src - C.bleed(totitemdamage) - else - add_splatter_floor(location) - if(totitemdamage >= 10 && get_dist(user, src) <= 1) //people with TK won't get smeared with blood - user.add_mob_blood(src) - return TRUE //successful attack - -/mob/living/simple_animal/attacked_by(obj/item/I, mob/living/user) - if(I.force < force_threshold || I.damtype == STAMINA) - playsound(loc, 'sound/weapons/tap.ogg', I.get_clamped_volume(), 1, -1) - else - return ..() - -// Proximity_flag is 1 if this afterattack was called on something adjacent, in your square, or on your person. -// Click parameters is the params string from byond Click() code, see that documentation. -/obj/item/proc/afterattack(atom/target, mob/user, proximity_flag, click_parameters) - SEND_SIGNAL(src, COMSIG_ITEM_AFTERATTACK, target, user, proximity_flag, click_parameters) - SEND_SIGNAL(user, COMSIG_MOB_ITEM_AFTERATTACK, target, user, proximity_flag, click_parameters) - -/obj/item/proc/get_clamped_volume() - if(w_class) - if(force) - return CLAMP((force + w_class) * 4, 30, 100)// Add the item's force to its weight class and multiply by 4, then clamp the value between 30 and 100 - else - return CLAMP(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100 - -/mob/living/proc/send_item_attack_message(obj/item/I, mob/living/user, hit_area) - var/message_verb = "attacked" - if(I.attack_verb && I.attack_verb.len) - message_verb = "[pick(I.attack_verb)]" - else if(!I.force) - return - var/message_hit_area = "" - if(hit_area) - message_hit_area = " in the [hit_area]" - var/attack_message = "[src] has been [message_verb][message_hit_area] with [I]." - if(user in viewers(src, null)) - attack_message = "[user] has [message_verb] [src][message_hit_area] with [I]!" - visible_message("[attack_message]",\ - "[attack_message]", null, COMBAT_MESSAGE_RANGE) - if(hit_area == BODY_ZONE_HEAD) - if(prob(2)) - playsound(src, 'sound/weapons/dink.ogg', 30, 1) - return 1 - -/obj/item/proc/getweight() - return total_mass || w_class * 1.25 + +/obj/item/proc/melee_attack_chain(mob/user, atom/target, params) + if(!tool_attack_chain(user, target) && pre_attack(target, user, params)) + // Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example) + var/resolved = target.attackby(src, user, params) + if(!resolved && target && !QDELETED(src)) + afterattack(target, user, 1, params) // 1: clicking something Adjacent + + +//Checks if the item can work as a tool, calling the appropriate tool behavior on the target +/obj/item/proc/tool_attack_chain(mob/user, atom/target) + if(!tool_behaviour) + return FALSE + + return target.tool_act(user, src, tool_behaviour) + + +// Called when the item is in the active hand, and clicked; alternately, there is an 'activate held object' verb or you can hit pagedown. +/obj/item/proc/attack_self(mob/user) + if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF, user) & COMPONENT_NO_INTERACT) + return + interact(user) + +/obj/item/proc/pre_attack(atom/A, mob/living/user, params) //do stuff before attackby! + if(SEND_SIGNAL(src, COMSIG_ITEM_PRE_ATTACK, A, user, params) & COMPONENT_NO_ATTACK) + return FALSE + return TRUE //return FALSE to avoid calling attackby after this proc does stuff + +// No comment +/atom/proc/attackby(obj/item/W, mob/user, params) + if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, W, user, params) & COMPONENT_NO_AFTERATTACK) + return TRUE + return FALSE + +/obj/attackby(obj/item/I, mob/living/user, params) + return ..() || ((obj_flags & CAN_BE_HIT) && I.attack_obj(src, user)) + +/mob/living/attackby(obj/item/I, mob/living/user, params) + if(..()) + return TRUE + user.changeNext_move(CLICK_CD_MELEE) + return I.attack(src, user) + + +/obj/item/proc/attack(mob/living/M, mob/living/user) + if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK, M, user) & COMPONENT_ITEM_NO_ATTACK) + return + SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK, M, user) + if(item_flags & NOBLUDGEON) + return + + if(user.getStaminaLoss() >= STAMINA_SOFTCRIT) // CIT CHANGE - makes it impossible to attack in stamina softcrit + to_chat(user, "You're too exhausted.") // CIT CHANGE - ditto + return // CIT CHANGE - ditto + + if(force && damtype != STAMINA && HAS_TRAIT(user, TRAIT_PACIFISM)) + to_chat(user, "You don't want to harm other living beings!") + return + + if(!force) + playsound(loc, 'sound/weapons/tap.ogg', get_clamped_volume(), 1, -1) + else if(hitsound) + playsound(loc, hitsound, get_clamped_volume(), 1, -1) + + M.lastattacker = user.real_name + M.lastattackerckey = user.ckey + + user.do_attack_animation(M) + M.attacked_by(src, user) + + log_combat(user, M, "attacked", src.name, "(INTENT: [uppertext(user.a_intent)]) (DAMTYPE: [uppertext(damtype)])") + add_fingerprint(user) + + user.adjustStaminaLossBuffered(getweight()*0.8)//CIT CHANGE - makes attacking things cause stamina loss + +//the equivalent of the standard version of attack() but for object targets. +/obj/item/proc/attack_obj(obj/O, mob/living/user) + if(SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_OBJ, O, user) & COMPONENT_NO_ATTACK_OBJ) + return + if(item_flags & NOBLUDGEON) + return + if(user.getStaminaLoss() >= STAMINA_SOFTCRIT) // CIT CHANGE - makes it impossible to attack in stamina softcrit + to_chat(user, "You're too exhausted.") // CIT CHANGE - ditto + return // CIT CHANGE - ditto + user.adjustStaminaLossBuffered(getweight()*1.2)//CIT CHANGE - makes attacking things cause stamina loss + user.changeNext_move(CLICK_CD_MELEE) + user.do_attack_animation(O) + O.attacked_by(src, user) + +/atom/movable/proc/attacked_by() + return + +/obj/attacked_by(obj/item/I, mob/living/user) + if(I.force) + visible_message("[user] has hit [src] with [I]!", null, null, COMBAT_MESSAGE_RANGE) + //only witnesses close by and the victim see a hit message. + log_combat(user, src, "attacked", I) + take_damage(I.force, I.damtype, "melee", 1) + +/mob/living/attacked_by(obj/item/I, mob/living/user) + //CIT CHANGES START HERE - combatmode and resting checks + var/totitemdamage = I.force + if(iscarbon(user)) + var/mob/living/carbon/tempcarb = user + if(!tempcarb.combatmode) + totitemdamage *= 0.5 + if(user.resting) + totitemdamage *= 0.5 + //CIT CHANGES END HERE + if(user != src && check_shields(I, totitemdamage, "the [I.name]", MELEE_ATTACK, I.armour_penetration)) + return FALSE + send_item_attack_message(I, user) + if(I.force) + apply_damage(totitemdamage, I.damtype) //CIT CHANGE - replaces I.force with totitemdamage + if(I.damtype == BRUTE && !HAS_TRAIT(src, TRAIT_NOMARROW)) + if(prob(33)) + I.add_mob_blood(src) + var/turf/location = get_turf(src) + if(iscarbon(src)) + var/mob/living/carbon/C = src + C.bleed(totitemdamage) + else + add_splatter_floor(location) + if(totitemdamage >= 10 && get_dist(user, src) <= 1) //people with TK won't get smeared with blood + user.add_mob_blood(src) + return TRUE //successful attack + +/mob/living/simple_animal/attacked_by(obj/item/I, mob/living/user) + if(I.force < force_threshold || I.damtype == STAMINA) + playsound(loc, 'sound/weapons/tap.ogg', I.get_clamped_volume(), 1, -1) + else + return ..() + +// Proximity_flag is 1 if this afterattack was called on something adjacent, in your square, or on your person. +// Click parameters is the params string from byond Click() code, see that documentation. +/obj/item/proc/afterattack(atom/target, mob/user, proximity_flag, click_parameters) + SEND_SIGNAL(src, COMSIG_ITEM_AFTERATTACK, target, user, proximity_flag, click_parameters) + SEND_SIGNAL(user, COMSIG_MOB_ITEM_AFTERATTACK, target, user, proximity_flag, click_parameters) + +/obj/item/proc/get_clamped_volume() + if(w_class) + if(force) + return CLAMP((force + w_class) * 4, 30, 100)// Add the item's force to its weight class and multiply by 4, then clamp the value between 30 and 100 + else + return CLAMP(w_class * 6, 10, 100) // Multiply the item's weight class by 6, then clamp the value between 10 and 100 + +/mob/living/proc/send_item_attack_message(obj/item/I, mob/living/user, hit_area) + var/message_verb = "attacked" + if(I.attack_verb && I.attack_verb.len) + message_verb = "[pick(I.attack_verb)]" + else if(!I.force) + return + var/message_hit_area = "" + if(hit_area) + message_hit_area = " in the [hit_area]" + var/attack_message = "[src] has been [message_verb][message_hit_area] with [I]." + if(user in viewers(src, null)) + attack_message = "[user] has [message_verb] [src][message_hit_area] with [I]!" + visible_message("[attack_message]",\ + "[attack_message]", null, COMBAT_MESSAGE_RANGE) + if(hit_area == BODY_ZONE_HEAD) + if(prob(2)) + playsound(src, 'sound/weapons/dink.ogg', 30, 1) + return 1 + +/obj/item/proc/getweight() + return total_mass || w_class * 1.25 diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index f76a745fd2..d596b5fabf 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -1,83 +1,83 @@ -/mob/dead/observer/DblClickOn(var/atom/A, var/params) - if(can_reenter_corpse && mind && mind.current) - if(A == mind.current || (mind.current in A)) // double click your corpse or whatever holds it - reenter_corpse() // (cloning scanner, body bag, closet, mech, etc) - return // seems legit. - - // Things you might plausibly want to follow - if(ismovableatom(A)) - ManualFollow(A) - - // Otherwise jump - else if(A.loc) - forceMove(get_turf(A)) - update_parallax_contents() - -/mob/dead/observer/ClickOn(var/atom/A, var/params) - if(check_click_intercept(params,A)) - return - - var/list/modifiers = params2list(params) - if(modifiers["shift"] && modifiers["middle"]) - ShiftMiddleClickOn(A) - return - if(modifiers["shift"] && modifiers["ctrl"]) - CtrlShiftClickOn(A) - return - if(modifiers["middle"]) - MiddleClickOn(A) - return - if(modifiers["shift"]) - ShiftClickOn(A) - return - if(modifiers["alt"]) - altclick_listed_turf(A) - return - if(modifiers["ctrl"]) - CtrlClickOn(A) - return - - if(world.time <= next_move) - return - // You are responsible for checking config.ghost_interaction when you override this function - // Not all of them require checking, see below - A.attack_ghost(src) - -// Oh by the way this didn't work with old click code which is why clicking shit didn't spam you -/atom/proc/attack_ghost(mob/dead/observer/user) - if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_GHOST, user) & COMPONENT_NO_ATTACK_HAND) - return TRUE - if(user.client) - if(IsAdminGhost(user)) - attack_ai(user) - else if(user.client.prefs.inquisitive_ghost) - user.examinate(src) - return FALSE - -/mob/living/attack_ghost(mob/dead/observer/user) - if(user.client && user.health_scan) - healthscan(user, src, 1, TRUE) - return ..() - -// --------------------------------------- -// And here are some good things for free: -// Now you can click through portals, wormholes, gateways, and teleporters while observing. -Sayu - -/obj/machinery/gateway/centerstation/attack_ghost(mob/user) - if(awaygate) - user.forceMove(awaygate.loc) - else - to_chat(user, "[src] has no destination.") - return ..() - -/obj/machinery/gateway/centeraway/attack_ghost(mob/user) - if(stationgate) - user.forceMove(stationgate.loc) - else - to_chat(user, "[src] has no destination.") - return ..() - -/obj/machinery/teleport/hub/attack_ghost(mob/user) - if(power_station && power_station.engaged && power_station.teleporter_console && power_station.teleporter_console.target) - user.forceMove(get_turf(power_station.teleporter_console.target)) - return ..() +/mob/dead/observer/DblClickOn(var/atom/A, var/params) + if(can_reenter_corpse && mind && mind.current) + if(A == mind.current || (mind.current in A)) // double click your corpse or whatever holds it + reenter_corpse() // (cloning scanner, body bag, closet, mech, etc) + return // seems legit. + + // Things you might plausibly want to follow + if(ismovableatom(A)) + ManualFollow(A) + + // Otherwise jump + else if(A.loc) + forceMove(get_turf(A)) + update_parallax_contents() + +/mob/dead/observer/ClickOn(var/atom/A, var/params) + if(check_click_intercept(params,A)) + return + + var/list/modifiers = params2list(params) + if(modifiers["shift"] && modifiers["middle"]) + ShiftMiddleClickOn(A) + return + if(modifiers["shift"] && modifiers["ctrl"]) + CtrlShiftClickOn(A) + return + if(modifiers["middle"]) + MiddleClickOn(A) + return + if(modifiers["shift"]) + ShiftClickOn(A) + return + if(modifiers["alt"]) + altclick_listed_turf(A) + return + if(modifiers["ctrl"]) + CtrlClickOn(A) + return + + if(world.time <= next_move) + return + // You are responsible for checking config.ghost_interaction when you override this function + // Not all of them require checking, see below + A.attack_ghost(src) + +// Oh by the way this didn't work with old click code which is why clicking shit didn't spam you +/atom/proc/attack_ghost(mob/dead/observer/user) + if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_GHOST, user) & COMPONENT_NO_ATTACK_HAND) + return TRUE + if(user.client) + if(IsAdminGhost(user)) + attack_ai(user) + else if(user.client.prefs.inquisitive_ghost) + user.examinate(src) + return FALSE + +/mob/living/attack_ghost(mob/dead/observer/user) + if(user.client && user.health_scan) + healthscan(user, src, 1, TRUE) + return ..() + +// --------------------------------------- +// And here are some good things for free: +// Now you can click through portals, wormholes, gateways, and teleporters while observing. -Sayu + +/obj/machinery/gateway/centerstation/attack_ghost(mob/user) + if(awaygate) + user.forceMove(awaygate.loc) + else + to_chat(user, "[src] has no destination.") + return ..() + +/obj/machinery/gateway/centeraway/attack_ghost(mob/user) + if(stationgate) + user.forceMove(stationgate.loc) + else + to_chat(user, "[src] has no destination.") + return ..() + +/obj/machinery/teleport/hub/attack_ghost(mob/user) + if(power_station && power_station.engaged && power_station.teleporter_console && power_station.teleporter_console.target) + user.forceMove(get_turf(power_station.teleporter_console.target)) + return ..() diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 6ee7d51091..7e194d5889 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -1,260 +1,260 @@ -/* - Humans: - Adds an exception for gloves, to allow special glove types like the ninja ones. - - Otherwise pretty standard. -*/ -/mob/living/carbon/human/UnarmedAttack(atom/A, proximity) - - if(!has_active_hand()) //can't attack without a hand. - to_chat(src, "You look at your arm and sigh.") - return - - // Special glove functions: - // If the gloves do anything, have them return 1 to stop - // normal attack_hand() here. - var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines - if(proximity && istype(G) && G.Touch(A,1)) - return - - var/override = 0 - - for(var/datum/mutation/human/HM in dna.mutations) - override += HM.on_attack_hand(src, A, proximity) - - if(override) - return - - SEND_SIGNAL(src, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, A) - A.attack_hand(src) - -//Return TRUE to cancel other attack hand effects that respect it. -/atom/proc/attack_hand(mob/user) - . = FALSE - if(!(interaction_flags_atom & INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND)) - add_fingerprint(user) - if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, user) & COMPONENT_NO_ATTACK_HAND) - . = TRUE - if(interaction_flags_atom & INTERACT_ATOM_ATTACK_HAND) - . = _try_interact(user) - -//Return a non FALSE value to cancel whatever called this from propagating, if it respects it. -/atom/proc/_try_interact(mob/user) - if(IsAdminGhost(user)) //admin abuse - return interact(user) - if(can_interact(user)) - return interact(user) - return FALSE - -/atom/proc/can_interact(mob/user) - if(!user.can_interact_with(src)) - return FALSE - if((interaction_flags_atom & INTERACT_ATOM_REQUIRES_DEXTERITY) && !user.IsAdvancedToolUser()) - to_chat(user, "You don't have the dexterity to do this!") - return FALSE - if(!(interaction_flags_atom & INTERACT_ATOM_IGNORE_INCAPACITATED) && user.incapacitated((interaction_flags_atom & INTERACT_ATOM_IGNORE_RESTRAINED), !(interaction_flags_atom & INTERACT_ATOM_CHECK_GRAB))) - return FALSE - return TRUE - -/atom/ui_status(mob/user) - . = ..() - if(!can_interact(user)) - . = min(., UI_UPDATE) - -/atom/movable/can_interact(mob/user) - . = ..() - if(!.) - return - if(!anchored && (interaction_flags_atom & INTERACT_ATOM_REQUIRES_ANCHORED)) - return FALSE - -/atom/proc/interact(mob/user) - if(interaction_flags_atom & INTERACT_ATOM_NO_FINGERPRINT_INTERACT) - add_hiddenprint(user) - else - add_fingerprint(user) - if(interaction_flags_atom & INTERACT_ATOM_UI_INTERACT) - return ui_interact(user) - return FALSE - -/* -/mob/living/carbon/human/RestrainedClickOn(var/atom/A) ---carbons will handle this - return -*/ - -/mob/living/carbon/RestrainedClickOn(atom/A) - return 0 - -/mob/living/carbon/human/RangedAttack(atom/A, mouseparams) - . = ..() - if(gloves) - var/obj/item/clothing/gloves/G = gloves - if(istype(G) && G.Touch(A,0)) // for magic gloves - return - if (istype(glasses) && glasses.ranged_attack(src,A,mouseparams)) - return - - for(var/datum/mutation/human/HM in dna.mutations) - HM.on_ranged_attack(src, A, mouseparams) - - if(isturf(A) && get_dist(src,A) <= 1) - src.Move_Pulled(A) - return - -/* - Animals & All Unspecified -*/ -/mob/living/UnarmedAttack(atom/A) - A.attack_animal(src) - -/atom/proc/attack_animal(mob/user) - return - -/mob/living/RestrainedClickOn(atom/A) - return - -/* - Monkeys -*/ -/mob/living/carbon/monkey/UnarmedAttack(atom/A) - A.attack_paw(src) - -/atom/proc/attack_paw(mob/user) - if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_PAW, user) & COMPONENT_NO_ATTACK_HAND) - return TRUE - return FALSE - -/* - Monkey RestrainedClickOn() was apparently the - one and only use of all of the restrained click code - (except to stop you from doing things while handcuffed); - moving it here instead of various hand_p's has simplified - things considerably -*/ -/mob/living/carbon/monkey/RestrainedClickOn(atom/A) - if(..()) - return - if(a_intent != INTENT_HARM || !ismob(A)) - return - if(is_muzzled()) - return - var/mob/living/carbon/ML = A - if(istype(ML)) - var/dam_zone = pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) - var/obj/item/bodypart/affecting = null - if(ishuman(ML)) - var/mob/living/carbon/human/H = ML - affecting = H.get_bodypart(ran_zone(dam_zone)) - var/armor = ML.run_armor_check(affecting, "melee") - if(prob(75)) - ML.apply_damage(rand(1,3), BRUTE, affecting, armor) - ML.visible_message("[name] bites [ML]!", \ - "[name] bites [ML]!") - if(armor >= 2) - return - for(var/thing in diseases) - var/datum/disease/D = thing - ML.ForceContractDisease(D) - else - ML.visible_message("[src] has attempted to bite [ML]!") - -/* - Aliens - Defaults to same as monkey in most places -*/ -/mob/living/carbon/alien/UnarmedAttack(atom/A) - A.attack_alien(src) - -/atom/proc/attack_alien(mob/living/carbon/alien/user) - attack_paw(user) - return - -/mob/living/carbon/alien/RestrainedClickOn(atom/A) - return - -// Babby aliens -/mob/living/carbon/alien/larva/UnarmedAttack(atom/A) - A.attack_larva(src) -/atom/proc/attack_larva(mob/user) - return - - -/* - Slimes - Nothing happening here -*/ -/mob/living/simple_animal/slime/UnarmedAttack(atom/A) - A.attack_slime(src) -/atom/proc/attack_slime(mob/user) - return -/mob/living/simple_animal/slime/RestrainedClickOn(atom/A) - return - - -/* - Drones -*/ -/mob/living/simple_animal/drone/UnarmedAttack(atom/A) - A.attack_drone(src) - -/atom/proc/attack_drone(mob/living/simple_animal/drone/user) - attack_hand(user) //defaults to attack_hand. Override it when you don't want drones to do same stuff as humans. - -/mob/living/simple_animal/slime/RestrainedClickOn(atom/A) - return - - -/* - True Devil -*/ - -/mob/living/carbon/true_devil/UnarmedAttack(atom/A, proximity) - A.attack_hand(src) - -/* - Brain -*/ - -/mob/living/brain/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default - return - - -/* - pAI -*/ - -/mob/living/silicon/pai/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default - return - - -/* - Simple animals -*/ - -/mob/living/simple_animal/UnarmedAttack(atom/A, proximity) - if(!dextrous) - return ..() - if(!ismob(A)) - A.attack_hand(src) - update_inv_hands() - - -/* - Hostile animals -*/ - -/mob/living/simple_animal/hostile/UnarmedAttack(atom/A) - target = A - if(dextrous && !ismob(A)) - ..() - else - AttackingTarget() - - - -/* - New Players: - Have no reason to click on anything at all. -*/ -/mob/dead/new_player/ClickOn() - return +/* + Humans: + Adds an exception for gloves, to allow special glove types like the ninja ones. + + Otherwise pretty standard. +*/ +/mob/living/carbon/human/UnarmedAttack(atom/A, proximity) + + if(!has_active_hand()) //can't attack without a hand. + to_chat(src, "You look at your arm and sigh.") + return + + // Special glove functions: + // If the gloves do anything, have them return 1 to stop + // normal attack_hand() here. + var/obj/item/clothing/gloves/G = gloves // not typecast specifically enough in defines + if(proximity && istype(G) && G.Touch(A,1)) + return + + var/override = 0 + + for(var/datum/mutation/human/HM in dna.mutations) + override += HM.on_attack_hand(src, A, proximity) + + if(override) + return + + SEND_SIGNAL(src, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, A) + A.attack_hand(src) + +//Return TRUE to cancel other attack hand effects that respect it. +/atom/proc/attack_hand(mob/user) + . = FALSE + if(!(interaction_flags_atom & INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND)) + add_fingerprint(user) + if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_HAND, user) & COMPONENT_NO_ATTACK_HAND) + . = TRUE + if(interaction_flags_atom & INTERACT_ATOM_ATTACK_HAND) + . = _try_interact(user) + +//Return a non FALSE value to cancel whatever called this from propagating, if it respects it. +/atom/proc/_try_interact(mob/user) + if(IsAdminGhost(user)) //admin abuse + return interact(user) + if(can_interact(user)) + return interact(user) + return FALSE + +/atom/proc/can_interact(mob/user) + if(!user.can_interact_with(src)) + return FALSE + if((interaction_flags_atom & INTERACT_ATOM_REQUIRES_DEXTERITY) && !user.IsAdvancedToolUser()) + to_chat(user, "You don't have the dexterity to do this!") + return FALSE + if(!(interaction_flags_atom & INTERACT_ATOM_IGNORE_INCAPACITATED) && user.incapacitated((interaction_flags_atom & INTERACT_ATOM_IGNORE_RESTRAINED), !(interaction_flags_atom & INTERACT_ATOM_CHECK_GRAB))) + return FALSE + return TRUE + +/atom/ui_status(mob/user) + . = ..() + if(!can_interact(user)) + . = min(., UI_UPDATE) + +/atom/movable/can_interact(mob/user) + . = ..() + if(!.) + return + if(!anchored && (interaction_flags_atom & INTERACT_ATOM_REQUIRES_ANCHORED)) + return FALSE + +/atom/proc/interact(mob/user) + if(interaction_flags_atom & INTERACT_ATOM_NO_FINGERPRINT_INTERACT) + add_hiddenprint(user) + else + add_fingerprint(user) + if(interaction_flags_atom & INTERACT_ATOM_UI_INTERACT) + return ui_interact(user) + return FALSE + +/* +/mob/living/carbon/human/RestrainedClickOn(var/atom/A) ---carbons will handle this + return +*/ + +/mob/living/carbon/RestrainedClickOn(atom/A) + return 0 + +/mob/living/carbon/human/RangedAttack(atom/A, mouseparams) + . = ..() + if(gloves) + var/obj/item/clothing/gloves/G = gloves + if(istype(G) && G.Touch(A,0)) // for magic gloves + return + if (istype(glasses) && glasses.ranged_attack(src,A,mouseparams)) + return + + for(var/datum/mutation/human/HM in dna.mutations) + HM.on_ranged_attack(src, A, mouseparams) + + if(isturf(A) && get_dist(src,A) <= 1) + src.Move_Pulled(A) + return + +/* + Animals & All Unspecified +*/ +/mob/living/UnarmedAttack(atom/A) + A.attack_animal(src) + +/atom/proc/attack_animal(mob/user) + return + +/mob/living/RestrainedClickOn(atom/A) + return + +/* + Monkeys +*/ +/mob/living/carbon/monkey/UnarmedAttack(atom/A) + A.attack_paw(src) + +/atom/proc/attack_paw(mob/user) + if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_PAW, user) & COMPONENT_NO_ATTACK_HAND) + return TRUE + return FALSE + +/* + Monkey RestrainedClickOn() was apparently the + one and only use of all of the restrained click code + (except to stop you from doing things while handcuffed); + moving it here instead of various hand_p's has simplified + things considerably +*/ +/mob/living/carbon/monkey/RestrainedClickOn(atom/A) + if(..()) + return + if(a_intent != INTENT_HARM || !ismob(A)) + return + if(is_muzzled()) + return + var/mob/living/carbon/ML = A + if(istype(ML)) + var/dam_zone = pick(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_L_HAND, BODY_ZONE_PRECISE_R_HAND, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) + var/obj/item/bodypart/affecting = null + if(ishuman(ML)) + var/mob/living/carbon/human/H = ML + affecting = H.get_bodypart(ran_zone(dam_zone)) + var/armor = ML.run_armor_check(affecting, "melee") + if(prob(75)) + ML.apply_damage(rand(1,3), BRUTE, affecting, armor) + ML.visible_message("[name] bites [ML]!", \ + "[name] bites [ML]!") + if(armor >= 2) + return + for(var/thing in diseases) + var/datum/disease/D = thing + ML.ForceContractDisease(D) + else + ML.visible_message("[src] has attempted to bite [ML]!") + +/* + Aliens + Defaults to same as monkey in most places +*/ +/mob/living/carbon/alien/UnarmedAttack(atom/A) + A.attack_alien(src) + +/atom/proc/attack_alien(mob/living/carbon/alien/user) + attack_paw(user) + return + +/mob/living/carbon/alien/RestrainedClickOn(atom/A) + return + +// Babby aliens +/mob/living/carbon/alien/larva/UnarmedAttack(atom/A) + A.attack_larva(src) +/atom/proc/attack_larva(mob/user) + return + + +/* + Slimes + Nothing happening here +*/ +/mob/living/simple_animal/slime/UnarmedAttack(atom/A) + A.attack_slime(src) +/atom/proc/attack_slime(mob/user) + return +/mob/living/simple_animal/slime/RestrainedClickOn(atom/A) + return + + +/* + Drones +*/ +/mob/living/simple_animal/drone/UnarmedAttack(atom/A) + A.attack_drone(src) + +/atom/proc/attack_drone(mob/living/simple_animal/drone/user) + attack_hand(user) //defaults to attack_hand. Override it when you don't want drones to do same stuff as humans. + +/mob/living/simple_animal/slime/RestrainedClickOn(atom/A) + return + + +/* + True Devil +*/ + +/mob/living/carbon/true_devil/UnarmedAttack(atom/A, proximity) + A.attack_hand(src) + +/* + Brain +*/ + +/mob/living/brain/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default + return + + +/* + pAI +*/ + +/mob/living/silicon/pai/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default + return + + +/* + Simple animals +*/ + +/mob/living/simple_animal/UnarmedAttack(atom/A, proximity) + if(!dextrous) + return ..() + if(!ismob(A)) + A.attack_hand(src) + update_inv_hands() + + +/* + Hostile animals +*/ + +/mob/living/simple_animal/hostile/UnarmedAttack(atom/A) + target = A + if(dextrous && !ismob(A)) + ..() + else + AttackingTarget() + + + +/* + New Players: + Have no reason to click on anything at all. +*/ +/mob/dead/new_player/ClickOn() + return diff --git a/code/controllers/configuration/config_entry.dm b/code/controllers/configuration/config_entry.dm index 3f07eed029..d97e7c379a 100644 --- a/code/controllers/configuration/config_entry.dm +++ b/code/controllers/configuration/config_entry.dm @@ -1,240 +1,240 @@ -#define VALUE_MODE_NUM 0 -#define VALUE_MODE_TEXT 1 -#define VALUE_MODE_FLAG 2 -#define VALUE_MODE_NUM_LIST 3 - -#define KEY_MODE_TEXT 0 -#define KEY_MODE_TYPE 1 - -/datum/config_entry - var/name //read-only, this is determined by the last portion of the derived entry type - var/config_entry_value - var/default //read-only, just set value directly - - var/resident_file //the file which this was loaded from, if any - var/modified = FALSE //set to TRUE if the default has been overridden by a config entry - - var/deprecated_by //the /datum/config_entry type that supercedes this one - - var/protection = NONE - var/abstract_type = /datum/config_entry //do not instantiate if type matches this - - var/vv_VAS = TRUE //Force validate and set on VV. VAS proccall guard will run regardless. - var/postload_required = FALSE //requires running OnPostload() - - var/dupes_allowed = FALSE - -/datum/config_entry/New() - if(type == abstract_type) - CRASH("Abstract config entry [type] instatiated!") - name = lowertext(type2top(type)) - if(islist(config_entry_value)) - var/list/L = config_entry_value - default = L.Copy() - else - default = config_entry_value - -/datum/config_entry/Destroy() - config.RemoveEntry(src) - return ..() - -/datum/config_entry/can_vv_get(var_name) - . = ..() - if(var_name == NAMEOF(src, config_entry_value) || var_name == NAMEOF(src, default)) - . &= !(protection & CONFIG_ENTRY_HIDDEN) - -/datum/config_entry/vv_edit_var(var_name, var_value) - var/static/list/banned_edits = list(NAMEOF(src, name), NAMEOF(src, vv_VAS), NAMEOF(src, default), NAMEOF(src, resident_file), NAMEOF(src, protection), NAMEOF(src, abstract_type), NAMEOF(src, modified), NAMEOF(src, dupes_allowed)) - if(var_name == NAMEOF(src, config_entry_value)) - if(protection & CONFIG_ENTRY_LOCKED) - return FALSE - if(vv_VAS) - . = ValidateAndSet("[var_value]") - if(.) - datum_flags |= DF_VAR_EDITED - return - else - return ..() - if(var_name in banned_edits) - return FALSE - return ..() - -/datum/config_entry/proc/VASProcCallGuard(str_val) - . = !((protection & CONFIG_ENTRY_LOCKED) && IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "ValidateAndSet" && GLOB.LastAdminCalledTargetRef == "[REF(src)]") - if(!.) - log_admin_private("Config set of [type] to [str_val] attempted by [key_name(usr)]") - -/datum/config_entry/proc/ValidateAndSet(str_val) - VASProcCallGuard(str_val) - CRASH("Invalid config entry type!") - -/datum/config_entry/proc/ValidateListEntry(key_name, key_value) - return TRUE - -/datum/config_entry/proc/DeprecationUpdate(value) - return - -/datum/config_entry/proc/OnPostload() - return - -/datum/config_entry/string - config_entry_value = "" - abstract_type = /datum/config_entry/string - var/auto_trim = TRUE - -/datum/config_entry/string/vv_edit_var(var_name, var_value) - return var_name != "auto_trim" && ..() - -/datum/config_entry/string/ValidateAndSet(str_val, during_load) - if(!VASProcCallGuard(str_val)) - return FALSE - config_entry_value = auto_trim ? trim(str_val) : str_val - return TRUE - -/datum/config_entry/number - config_entry_value = 0 - abstract_type = /datum/config_entry/number - var/integer = TRUE - var/max_val = INFINITY - var/min_val = -INFINITY - -/datum/config_entry/number/ValidateAndSet(str_val) - if(!VASProcCallGuard(str_val)) - return FALSE - var/temp = text2num(trim(str_val)) - if(!isnull(temp)) - config_entry_value = CLAMP(integer ? round(temp) : temp, min_val, max_val) - if(config_entry_value != temp && !(datum_flags & DF_VAR_EDITED)) - log_config("Changing [name] from [temp] to [config_entry_value]!") - return TRUE - return FALSE - -/datum/config_entry/number/vv_edit_var(var_name, var_value) - var/static/list/banned_edits = list("max_val", "min_val", "integer") - return !(var_name in banned_edits) && ..() - -/datum/config_entry/flag - config_entry_value = FALSE - abstract_type = /datum/config_entry/flag - -/datum/config_entry/flag/ValidateAndSet(str_val) - if(!VASProcCallGuard(str_val)) - return FALSE - config_entry_value = text2num(trim(str_val)) != 0 - return TRUE - -/datum/config_entry/number_list - abstract_type = /datum/config_entry/number_list - config_entry_value = list() - -/datum/config_entry/number_list/ValidateAndSet(str_val) - if(!VASProcCallGuard(str_val)) - return FALSE - str_val = trim(str_val) - var/list/new_list = list() - var/list/values = splittext(str_val," ") - for(var/I in values) - var/temp = text2num(I) - if(isnull(temp)) - return FALSE - new_list += temp - if(!new_list.len) - return FALSE - config_entry_value = new_list - return TRUE - -/datum/config_entry/keyed_list - abstract_type = /datum/config_entry/keyed_list - config_entry_value = list() - dupes_allowed = TRUE - vv_VAS = FALSE //VAS will not allow things like deleting from lists, it'll just bug horribly. - var/key_mode - var/value_mode - var/splitter = " " - var/lowercase = TRUE - -/datum/config_entry/keyed_list/New() - . = ..() - if(isnull(key_mode) || isnull(value_mode)) - CRASH("Keyed list of type [type] created with null key or value mode!") - -/datum/config_entry/keyed_list/ValidateAndSet(str_val) - if(!VASProcCallGuard(str_val)) - return FALSE - - str_val = trim(str_val) - var/key_pos = findtext(str_val, splitter) - var/key_name = null - var/key_value = null - - if(key_pos || value_mode == VALUE_MODE_FLAG) - key_name = copytext(str_val, 1, key_pos) - if(lowercase) - key_name = lowertext(key_name) - key_value = copytext(str_val, key_pos + 1) - var/new_key - var/new_value - var/continue_check_value - var/continue_check_key - switch(key_mode) - if(KEY_MODE_TEXT) - new_key = key_name - continue_check_key = new_key - if(KEY_MODE_TYPE) - new_key = key_name - if(!ispath(new_key)) - new_key = text2path(new_key) - continue_check_key = ispath(new_key) - switch(value_mode) - if(VALUE_MODE_FLAG) - new_value = TRUE - continue_check_value = TRUE - if(VALUE_MODE_NUM) - new_value = text2num(key_value) - continue_check_value = !isnull(new_value) - if(VALUE_MODE_TEXT) - new_value = key_value - continue_check_value = new_value - if(VALUE_MODE_NUM_LIST) - // this is all copy+pasted from number list up there, but it's super basic so I don't see it being changed soon - var/list/new_list = list() - var/list/values = splittext(key_value," ") - for(var/I in values) - var/temp = text2num(I) - if(isnull(temp)) - log_admin("invalid number list entry in [key_name]: [I]") - continue_check_value = FALSE - new_list += temp - new_value = new_list - continue_check_value = new_list.len - if(continue_check_value && continue_check_key && ValidateListEntry(new_key, new_value)) - config_entry_value[new_key] = new_value - return TRUE - return FALSE - -/datum/config_entry/keyed_list/vv_edit_var(var_name, var_value) - return var_name != "splitter" && ..() - -//snowflake for donator things being on one line smh -/datum/config_entry/multi_keyed_flag - vv_VAS = FALSE - abstract_type = /datum/config_entry/multi_keyed_flag - config_entry_value = list() - var/delimiter = "|" - -/datum/config_entry/multi_keyed_flag/vv_edit_var(var_name, var_value) - if(var_name == NAMEOF(src, delimiter)) - return FALSE - return ..() - -/datum/config_entry/multi_keyed_flag/ValidateAndSet(str_val) - if(!VASProcCallGuard(str_val)) - return FALSE - str_val = trim(str_val) - var/list/keys = splittext(str_val, delimiter) - for(var/i in keys) - config_entry_value[process_key(i)] = TRUE - return length(keys)? TRUE : FALSE - -/datum/config_entry/multi_keyed_flag/proc/process_key(key) - return trim(key) +#define VALUE_MODE_NUM 0 +#define VALUE_MODE_TEXT 1 +#define VALUE_MODE_FLAG 2 +#define VALUE_MODE_NUM_LIST 3 + +#define KEY_MODE_TEXT 0 +#define KEY_MODE_TYPE 1 + +/datum/config_entry + var/name //read-only, this is determined by the last portion of the derived entry type + var/config_entry_value + var/default //read-only, just set value directly + + var/resident_file //the file which this was loaded from, if any + var/modified = FALSE //set to TRUE if the default has been overridden by a config entry + + var/deprecated_by //the /datum/config_entry type that supercedes this one + + var/protection = NONE + var/abstract_type = /datum/config_entry //do not instantiate if type matches this + + var/vv_VAS = TRUE //Force validate and set on VV. VAS proccall guard will run regardless. + var/postload_required = FALSE //requires running OnPostload() + + var/dupes_allowed = FALSE + +/datum/config_entry/New() + if(type == abstract_type) + CRASH("Abstract config entry [type] instatiated!") + name = lowertext(type2top(type)) + if(islist(config_entry_value)) + var/list/L = config_entry_value + default = L.Copy() + else + default = config_entry_value + +/datum/config_entry/Destroy() + config.RemoveEntry(src) + return ..() + +/datum/config_entry/can_vv_get(var_name) + . = ..() + if(var_name == NAMEOF(src, config_entry_value) || var_name == NAMEOF(src, default)) + . &= !(protection & CONFIG_ENTRY_HIDDEN) + +/datum/config_entry/vv_edit_var(var_name, var_value) + var/static/list/banned_edits = list(NAMEOF(src, name), NAMEOF(src, vv_VAS), NAMEOF(src, default), NAMEOF(src, resident_file), NAMEOF(src, protection), NAMEOF(src, abstract_type), NAMEOF(src, modified), NAMEOF(src, dupes_allowed)) + if(var_name == NAMEOF(src, config_entry_value)) + if(protection & CONFIG_ENTRY_LOCKED) + return FALSE + if(vv_VAS) + . = ValidateAndSet("[var_value]") + if(.) + datum_flags |= DF_VAR_EDITED + return + else + return ..() + if(var_name in banned_edits) + return FALSE + return ..() + +/datum/config_entry/proc/VASProcCallGuard(str_val) + . = !((protection & CONFIG_ENTRY_LOCKED) && IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "ValidateAndSet" && GLOB.LastAdminCalledTargetRef == "[REF(src)]") + if(!.) + log_admin_private("Config set of [type] to [str_val] attempted by [key_name(usr)]") + +/datum/config_entry/proc/ValidateAndSet(str_val) + VASProcCallGuard(str_val) + CRASH("Invalid config entry type!") + +/datum/config_entry/proc/ValidateListEntry(key_name, key_value) + return TRUE + +/datum/config_entry/proc/DeprecationUpdate(value) + return + +/datum/config_entry/proc/OnPostload() + return + +/datum/config_entry/string + config_entry_value = "" + abstract_type = /datum/config_entry/string + var/auto_trim = TRUE + +/datum/config_entry/string/vv_edit_var(var_name, var_value) + return var_name != "auto_trim" && ..() + +/datum/config_entry/string/ValidateAndSet(str_val, during_load) + if(!VASProcCallGuard(str_val)) + return FALSE + config_entry_value = auto_trim ? trim(str_val) : str_val + return TRUE + +/datum/config_entry/number + config_entry_value = 0 + abstract_type = /datum/config_entry/number + var/integer = TRUE + var/max_val = INFINITY + var/min_val = -INFINITY + +/datum/config_entry/number/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE + var/temp = text2num(trim(str_val)) + if(!isnull(temp)) + config_entry_value = CLAMP(integer ? round(temp) : temp, min_val, max_val) + if(config_entry_value != temp && !(datum_flags & DF_VAR_EDITED)) + log_config("Changing [name] from [temp] to [config_entry_value]!") + return TRUE + return FALSE + +/datum/config_entry/number/vv_edit_var(var_name, var_value) + var/static/list/banned_edits = list("max_val", "min_val", "integer") + return !(var_name in banned_edits) && ..() + +/datum/config_entry/flag + config_entry_value = FALSE + abstract_type = /datum/config_entry/flag + +/datum/config_entry/flag/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE + config_entry_value = text2num(trim(str_val)) != 0 + return TRUE + +/datum/config_entry/number_list + abstract_type = /datum/config_entry/number_list + config_entry_value = list() + +/datum/config_entry/number_list/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE + str_val = trim(str_val) + var/list/new_list = list() + var/list/values = splittext(str_val," ") + for(var/I in values) + var/temp = text2num(I) + if(isnull(temp)) + return FALSE + new_list += temp + if(!new_list.len) + return FALSE + config_entry_value = new_list + return TRUE + +/datum/config_entry/keyed_list + abstract_type = /datum/config_entry/keyed_list + config_entry_value = list() + dupes_allowed = TRUE + vv_VAS = FALSE //VAS will not allow things like deleting from lists, it'll just bug horribly. + var/key_mode + var/value_mode + var/splitter = " " + var/lowercase = TRUE + +/datum/config_entry/keyed_list/New() + . = ..() + if(isnull(key_mode) || isnull(value_mode)) + CRASH("Keyed list of type [type] created with null key or value mode!") + +/datum/config_entry/keyed_list/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE + + str_val = trim(str_val) + var/key_pos = findtext(str_val, splitter) + var/key_name = null + var/key_value = null + + if(key_pos || value_mode == VALUE_MODE_FLAG) + key_name = copytext(str_val, 1, key_pos) + if(lowercase) + key_name = lowertext(key_name) + key_value = copytext(str_val, key_pos + 1) + var/new_key + var/new_value + var/continue_check_value + var/continue_check_key + switch(key_mode) + if(KEY_MODE_TEXT) + new_key = key_name + continue_check_key = new_key + if(KEY_MODE_TYPE) + new_key = key_name + if(!ispath(new_key)) + new_key = text2path(new_key) + continue_check_key = ispath(new_key) + switch(value_mode) + if(VALUE_MODE_FLAG) + new_value = TRUE + continue_check_value = TRUE + if(VALUE_MODE_NUM) + new_value = text2num(key_value) + continue_check_value = !isnull(new_value) + if(VALUE_MODE_TEXT) + new_value = key_value + continue_check_value = new_value + if(VALUE_MODE_NUM_LIST) + // this is all copy+pasted from number list up there, but it's super basic so I don't see it being changed soon + var/list/new_list = list() + var/list/values = splittext(key_value," ") + for(var/I in values) + var/temp = text2num(I) + if(isnull(temp)) + log_admin("invalid number list entry in [key_name]: [I]") + continue_check_value = FALSE + new_list += temp + new_value = new_list + continue_check_value = new_list.len + if(continue_check_value && continue_check_key && ValidateListEntry(new_key, new_value)) + config_entry_value[new_key] = new_value + return TRUE + return FALSE + +/datum/config_entry/keyed_list/vv_edit_var(var_name, var_value) + return var_name != "splitter" && ..() + +//snowflake for donator things being on one line smh +/datum/config_entry/multi_keyed_flag + vv_VAS = FALSE + abstract_type = /datum/config_entry/multi_keyed_flag + config_entry_value = list() + var/delimiter = "|" + +/datum/config_entry/multi_keyed_flag/vv_edit_var(var_name, var_value) + if(var_name == NAMEOF(src, delimiter)) + return FALSE + return ..() + +/datum/config_entry/multi_keyed_flag/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE + str_val = trim(str_val) + var/list/keys = splittext(str_val, delimiter) + for(var/i in keys) + config_entry_value[process_key(i)] = TRUE + return length(keys)? TRUE : FALSE + +/datum/config_entry/multi_keyed_flag/proc/process_key(key) + return trim(key) diff --git a/code/controllers/configuration/configuration.dm b/code/controllers/configuration/configuration.dm index 730a3f17f4..0caa86f68c 100644 --- a/code/controllers/configuration/configuration.dm +++ b/code/controllers/configuration/configuration.dm @@ -1,384 +1,384 @@ -/datum/controller/configuration - name = "Configuration" - - var/directory = "config" - - var/warned_deprecated_configs = FALSE - var/hiding_entries_by_type = TRUE //Set for readability, admins can set this to FALSE if they want to debug it - var/list/entries - var/list/entries_by_type - - var/list/maplist - var/datum/map_config/defaultmap - - var/list/modes // allowed modes - var/list/gamemode_cache - var/list/votable_modes // votable modes - var/list/storyteller_cache - var/list/mode_names - var/list/mode_reports - var/list/mode_false_report_weight - - var/motd - -/datum/controller/configuration/proc/admin_reload() - if(IsAdminAdvancedProcCall()) - return - log_admin("[key_name_admin(usr)] has forcefully reloaded the configuration from disk.") - message_admins("[key_name_admin(usr)] has forcefully reloaded the configuration from disk.") - full_wipe() - Load(world.params[OVERRIDE_CONFIG_DIRECTORY_PARAMETER]) - -/datum/controller/configuration/proc/Load(_directory) - if(IsAdminAdvancedProcCall()) //If admin proccall is detected down the line it will horribly break everything. - return - if(_directory) - directory = _directory - if(entries) - CRASH("/datum/controller/configuration/Load() called more than once!") - InitEntries() - LoadModes() - storyteller_cache = typecacheof(/datum/dynamic_storyteller, TRUE) - if(fexists("[directory]/config.txt") && LoadEntries("config.txt") <= 1) - var/list/legacy_configs = list("game_options.txt", "dbconfig.txt", "comms.txt") - for(var/I in legacy_configs) - if(fexists("[directory]/[I]")) - log_config("No $include directives found in config.txt! Loading legacy [legacy_configs.Join("/")] files...") - for(var/J in legacy_configs) - LoadEntries(J) - break - loadmaplist(CONFIG_MAPS_FILE) - LoadMOTD() - -/datum/controller/configuration/proc/full_wipe() - if(IsAdminAdvancedProcCall()) - return - entries_by_type.Cut() - QDEL_LIST_ASSOC_VAL(entries) - entries = null - QDEL_LIST_ASSOC_VAL(maplist) - maplist = null - QDEL_NULL(defaultmap) - -/datum/controller/configuration/Destroy() - full_wipe() - config = null - - return ..() - -/datum/controller/configuration/proc/InitEntries() - var/list/_entries = list() - entries = _entries - var/list/_entries_by_type = list() - entries_by_type = _entries_by_type - - for(var/I in typesof(/datum/config_entry)) //typesof is faster in this case - var/datum/config_entry/E = I - if(initial(E.abstract_type) == I) - continue - E = new I - var/esname = E.name - var/datum/config_entry/test = _entries[esname] - if(test) - log_config("Error: [test.type] has the same name as [E.type]: [esname]! Not initializing [E.type]!") - qdel(E) - continue - _entries[esname] = E - _entries_by_type[I] = E - -/datum/controller/configuration/proc/RemoveEntry(datum/config_entry/CE) - entries -= CE.name - entries_by_type -= CE.type - -/datum/controller/configuration/proc/LoadEntries(filename, list/stack = list()) - if(IsAdminAdvancedProcCall()) - return - - var/filename_to_test = world.system_type == MS_WINDOWS ? lowertext(filename) : filename - if(filename_to_test in stack) - log_config("Warning: Config recursion detected ([english_list(stack)]), breaking!") - return - stack = stack + filename_to_test - - log_config("Loading config file [filename]...") - var/list/lines = world.file2list("[directory]/[filename]") - var/list/_entries = entries - var/list/postload_required = list() - for(var/L in lines) - L = trim(L) - if(!L) - continue - - var/firstchar = copytext(L, 1, 2) - if(firstchar == "#") - continue - - var/lockthis = firstchar == "@" - if(lockthis) - L = copytext(L, 2) - - var/pos = findtext(L, " ") - var/entry = null - var/value = null - - if(pos) - entry = lowertext(copytext(L, 1, pos)) - value = copytext(L, pos + 1) - else - entry = lowertext(L) - - if(!entry) - continue - - if(entry == "$include") - if(!value) - log_config("Warning: Invalid $include directive: [value]") - else - LoadEntries(value, stack) - ++. - continue - - var/datum/config_entry/E = _entries[entry] - if(!E) - log_config("Unknown setting in configuration: '[entry]'") - continue - - if(lockthis) - E.protection |= CONFIG_ENTRY_LOCKED - - if(E.deprecated_by) - var/datum/config_entry/new_ver = entries_by_type[E.deprecated_by] - var/new_value = E.DeprecationUpdate(value) - var/good_update = istext(new_value) - log_config("Entry [entry] is deprecated and will be removed soon. Migrate to [new_ver.name]![good_update ? " Suggested new value is: [new_value]" : ""]") - if(!warned_deprecated_configs) - addtimer(CALLBACK(GLOBAL_PROC, /proc/message_admins, "This server is using deprecated configuration settings. Please check the logs and update accordingly."), 0) - warned_deprecated_configs = TRUE - if(good_update) - value = new_value - E = new_ver - else - warning("[new_ver.type] is deprecated but gave no proper return for DeprecationUpdate()") - - var/validated = E.ValidateAndSet(value, TRUE) - if(!validated) - log_config("Failed to validate setting \"[value]\" for [entry]") - else - if(E.modified && !E.dupes_allowed) - log_config("Duplicate setting for [entry] ([value], [E.resident_file]) detected! Using latest.") - if(E.postload_required) - postload_required[E] = TRUE - - E.resident_file = filename - - if(validated) - E.modified = TRUE - - for(var/i in postload_required) - var/datum/config_entry/E = i - E.OnPostload() - - ++. - -/datum/controller/configuration/can_vv_get(var_name) - return (var_name != NAMEOF(src, entries_by_type) || !hiding_entries_by_type) && ..() - -/datum/controller/configuration/vv_edit_var(var_name, var_value) - var/list/banned_edits = list(NAMEOF(src, entries_by_type), NAMEOF(src, entries), NAMEOF(src, directory)) - return !(var_name in banned_edits) && ..() - -/datum/controller/configuration/stat_entry() - if(!statclick) - statclick = new/obj/effect/statclick/debug(null, "Edit", src) - stat("[name]:", statclick) - -/datum/controller/configuration/proc/Get(entry_type) - var/datum/config_entry/E = entry_type - var/entry_is_abstract = initial(E.abstract_type) == entry_type - if(entry_is_abstract) - CRASH("Tried to retrieve an abstract config_entry: [entry_type]") - E = entries_by_type[entry_type] - if(!E) - CRASH("Missing config entry for [entry_type]!") - if((E.protection & CONFIG_ENTRY_HIDDEN) && IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "[REF(src)]") - log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]") - return - return E.config_entry_value - -/datum/controller/configuration/proc/Set(entry_type, new_val) - var/datum/config_entry/E = entry_type - var/entry_is_abstract = initial(E.abstract_type) == entry_type - if(entry_is_abstract) - CRASH("Tried to set an abstract config_entry: [entry_type]") - E = entries_by_type[entry_type] - if(!E) - CRASH("Missing config entry for [entry_type]!") - if((E.protection & CONFIG_ENTRY_LOCKED) && IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Set" && GLOB.LastAdminCalledTargetRef == "[REF(src)]") - log_admin_private("Config rewrite of [entry_type] to [new_val] attempted by [key_name(usr)]") - return - return E.ValidateAndSet("[new_val]") - -/datum/controller/configuration/proc/LoadModes() - gamemode_cache = typecacheof(/datum/game_mode, TRUE) - modes = list() - mode_names = list() - mode_reports = list() - mode_false_report_weight = list() - votable_modes = list() - var/list/probabilities = Get(/datum/config_entry/keyed_list/probability) - for(var/T in gamemode_cache) - // I wish I didn't have to instance the game modes in order to look up - // their information, but it is the only way (at least that I know of). - // for future reference: just use initial() lol - var/datum/game_mode/M = new T() - - if(M.config_tag) - if(!(M.config_tag in modes)) // ensure each mode is added only once - modes += M.config_tag - mode_names[M.config_tag] = M.name - mode_reports[M.config_tag] = M.generate_report() - if(probabilities[M.config_tag]>0) - mode_false_report_weight[M.config_tag] = M.false_report_weight - else - mode_false_report_weight[M.config_tag] = 1 - if(M.votable) - votable_modes += M.config_tag - qdel(M) - votable_modes += "secret" - -/datum/controller/configuration/proc/LoadMOTD() - motd = file2text("[directory]/motd.txt") - var/tm_info = GLOB.revdata.GetTestMergeInfo() - if(motd || tm_info) - motd = motd ? "[motd]
      [tm_info]" : tm_info - -/datum/controller/configuration/proc/loadmaplist(filename) - log_config("Loading config file [filename]...") - filename = "[directory]/[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 = load_map_config("_maps/[data].json") - if(currentmap.defaulted) - log_config("Failed to load map config for [data]!") - currentmap = null - if ("minplayers","minplayer") - currentmap.config_min_users = text2num(data) - if ("maxplayers","maxplayer") - currentmap.config_max_users = text2num(data) - if ("weight","voteweight") - currentmap.voteweight = text2num(data) - if ("default","defaultmap") - defaultmap = currentmap - if ("endmap") - LAZYINITLIST(maplist) - maplist[currentmap.map_name] = currentmap - currentmap = null - if ("disabled") - currentmap = null - else - log_config("Unknown command in map vote config: '[command]'") - - -/datum/controller/configuration/proc/pick_mode(mode_name) - // I wish I didn't have to instance the game modes in order to look up - // their information, but it is the only way (at least that I know of). - // ^ This guy didn't try hard enough - for(var/T in gamemode_cache) - var/datum/game_mode/M = T - var/ct = initial(M.config_tag) - if(ct && ct == mode_name) - return new T - return new /datum/game_mode/extended() - -/datum/controller/configuration/proc/pick_storyteller(storyteller_name) - for(var/T in storyteller_cache) - var/datum/dynamic_storyteller/S = T - var/name = initial(S.name) - if(name && name == storyteller_name) - return T - return /datum/dynamic_storyteller/classic - -/datum/controller/configuration/proc/get_runnable_modes() - var/list/datum/game_mode/runnable_modes = new - var/list/probabilities = Get(/datum/config_entry/keyed_list/probability) - var/list/min_pop = Get(/datum/config_entry/keyed_list/min_pop) - var/list/max_pop = Get(/datum/config_entry/keyed_list/max_pop) - var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust) - for(var/T in gamemode_cache) - var/datum/game_mode/M = new T() - if(!(M.config_tag in modes)) - qdel(M) - continue - if(probabilities[M.config_tag]<=0) - qdel(M) - continue - if(M.config_tag in SSvote.stored_modetier_results && SSvote.stored_modetier_results[M.config_tag] < Get(/datum/config_entry/number/dropped_modes)) - qdel(M) - continue - if(min_pop[M.config_tag]) - M.required_players = min_pop[M.config_tag] - if(max_pop[M.config_tag]) - M.maximum_players = max_pop[M.config_tag] - if(M.can_start()) - var/final_weight = probabilities[M.config_tag] - if(SSpersistence.saved_modes.len == 3 && repeated_mode_adjust.len == 3) - var/recent_round = min(SSpersistence.saved_modes.Find(M.config_tag),3) - var/adjustment = 0 - while(recent_round) - adjustment += repeated_mode_adjust[recent_round] - recent_round = SSpersistence.saved_modes.Find(M.config_tag,recent_round+1,0) - final_weight *= ((100-adjustment)/100) - runnable_modes[M] = final_weight - return runnable_modes - -/datum/controller/configuration/proc/get_runnable_midround_modes(crew) - var/list/datum/game_mode/runnable_modes = new - var/list/probabilities = Get(/datum/config_entry/keyed_list/probability) - var/list/min_pop = Get(/datum/config_entry/keyed_list/min_pop) - var/list/max_pop = Get(/datum/config_entry/keyed_list/max_pop) - for(var/T in (gamemode_cache - SSticker.mode.type)) - var/datum/game_mode/M = new T() - if(!(M.config_tag in modes)) - qdel(M) - continue - if(probabilities[M.config_tag]<=0) - qdel(M) - continue - if(min_pop[M.config_tag]) - M.required_players = min_pop[M.config_tag] - if(max_pop[M.config_tag]) - M.maximum_players = max_pop[M.config_tag] - if(M.required_players <= crew) - if(M.maximum_players >= 0 && M.maximum_players < crew) - continue - runnable_modes[M] = probabilities[M.config_tag] - return runnable_modes +/datum/controller/configuration + name = "Configuration" + + var/directory = "config" + + var/warned_deprecated_configs = FALSE + var/hiding_entries_by_type = TRUE //Set for readability, admins can set this to FALSE if they want to debug it + var/list/entries + var/list/entries_by_type + + var/list/maplist + var/datum/map_config/defaultmap + + var/list/modes // allowed modes + var/list/gamemode_cache + var/list/votable_modes // votable modes + var/list/storyteller_cache + var/list/mode_names + var/list/mode_reports + var/list/mode_false_report_weight + + var/motd + +/datum/controller/configuration/proc/admin_reload() + if(IsAdminAdvancedProcCall()) + return + log_admin("[key_name_admin(usr)] has forcefully reloaded the configuration from disk.") + message_admins("[key_name_admin(usr)] has forcefully reloaded the configuration from disk.") + full_wipe() + Load(world.params[OVERRIDE_CONFIG_DIRECTORY_PARAMETER]) + +/datum/controller/configuration/proc/Load(_directory) + if(IsAdminAdvancedProcCall()) //If admin proccall is detected down the line it will horribly break everything. + return + if(_directory) + directory = _directory + if(entries) + CRASH("/datum/controller/configuration/Load() called more than once!") + InitEntries() + LoadModes() + storyteller_cache = typecacheof(/datum/dynamic_storyteller, TRUE) + if(fexists("[directory]/config.txt") && LoadEntries("config.txt") <= 1) + var/list/legacy_configs = list("game_options.txt", "dbconfig.txt", "comms.txt") + for(var/I in legacy_configs) + if(fexists("[directory]/[I]")) + log_config("No $include directives found in config.txt! Loading legacy [legacy_configs.Join("/")] files...") + for(var/J in legacy_configs) + LoadEntries(J) + break + loadmaplist(CONFIG_MAPS_FILE) + LoadMOTD() + +/datum/controller/configuration/proc/full_wipe() + if(IsAdminAdvancedProcCall()) + return + entries_by_type.Cut() + QDEL_LIST_ASSOC_VAL(entries) + entries = null + QDEL_LIST_ASSOC_VAL(maplist) + maplist = null + QDEL_NULL(defaultmap) + +/datum/controller/configuration/Destroy() + full_wipe() + config = null + + return ..() + +/datum/controller/configuration/proc/InitEntries() + var/list/_entries = list() + entries = _entries + var/list/_entries_by_type = list() + entries_by_type = _entries_by_type + + for(var/I in typesof(/datum/config_entry)) //typesof is faster in this case + var/datum/config_entry/E = I + if(initial(E.abstract_type) == I) + continue + E = new I + var/esname = E.name + var/datum/config_entry/test = _entries[esname] + if(test) + log_config("Error: [test.type] has the same name as [E.type]: [esname]! Not initializing [E.type]!") + qdel(E) + continue + _entries[esname] = E + _entries_by_type[I] = E + +/datum/controller/configuration/proc/RemoveEntry(datum/config_entry/CE) + entries -= CE.name + entries_by_type -= CE.type + +/datum/controller/configuration/proc/LoadEntries(filename, list/stack = list()) + if(IsAdminAdvancedProcCall()) + return + + var/filename_to_test = world.system_type == MS_WINDOWS ? lowertext(filename) : filename + if(filename_to_test in stack) + log_config("Warning: Config recursion detected ([english_list(stack)]), breaking!") + return + stack = stack + filename_to_test + + log_config("Loading config file [filename]...") + var/list/lines = world.file2list("[directory]/[filename]") + var/list/_entries = entries + var/list/postload_required = list() + for(var/L in lines) + L = trim(L) + if(!L) + continue + + var/firstchar = copytext(L, 1, 2) + if(firstchar == "#") + continue + + var/lockthis = firstchar == "@" + if(lockthis) + L = copytext(L, 2) + + var/pos = findtext(L, " ") + var/entry = null + var/value = null + + if(pos) + entry = lowertext(copytext(L, 1, pos)) + value = copytext(L, pos + 1) + else + entry = lowertext(L) + + if(!entry) + continue + + if(entry == "$include") + if(!value) + log_config("Warning: Invalid $include directive: [value]") + else + LoadEntries(value, stack) + ++. + continue + + var/datum/config_entry/E = _entries[entry] + if(!E) + log_config("Unknown setting in configuration: '[entry]'") + continue + + if(lockthis) + E.protection |= CONFIG_ENTRY_LOCKED + + if(E.deprecated_by) + var/datum/config_entry/new_ver = entries_by_type[E.deprecated_by] + var/new_value = E.DeprecationUpdate(value) + var/good_update = istext(new_value) + log_config("Entry [entry] is deprecated and will be removed soon. Migrate to [new_ver.name]![good_update ? " Suggested new value is: [new_value]" : ""]") + if(!warned_deprecated_configs) + addtimer(CALLBACK(GLOBAL_PROC, /proc/message_admins, "This server is using deprecated configuration settings. Please check the logs and update accordingly."), 0) + warned_deprecated_configs = TRUE + if(good_update) + value = new_value + E = new_ver + else + warning("[new_ver.type] is deprecated but gave no proper return for DeprecationUpdate()") + + var/validated = E.ValidateAndSet(value, TRUE) + if(!validated) + log_config("Failed to validate setting \"[value]\" for [entry]") + else + if(E.modified && !E.dupes_allowed) + log_config("Duplicate setting for [entry] ([value], [E.resident_file]) detected! Using latest.") + if(E.postload_required) + postload_required[E] = TRUE + + E.resident_file = filename + + if(validated) + E.modified = TRUE + + for(var/i in postload_required) + var/datum/config_entry/E = i + E.OnPostload() + + ++. + +/datum/controller/configuration/can_vv_get(var_name) + return (var_name != NAMEOF(src, entries_by_type) || !hiding_entries_by_type) && ..() + +/datum/controller/configuration/vv_edit_var(var_name, var_value) + var/list/banned_edits = list(NAMEOF(src, entries_by_type), NAMEOF(src, entries), NAMEOF(src, directory)) + return !(var_name in banned_edits) && ..() + +/datum/controller/configuration/stat_entry() + if(!statclick) + statclick = new/obj/effect/statclick/debug(null, "Edit", src) + stat("[name]:", statclick) + +/datum/controller/configuration/proc/Get(entry_type) + var/datum/config_entry/E = entry_type + var/entry_is_abstract = initial(E.abstract_type) == entry_type + if(entry_is_abstract) + CRASH("Tried to retrieve an abstract config_entry: [entry_type]") + E = entries_by_type[entry_type] + if(!E) + CRASH("Missing config entry for [entry_type]!") + if((E.protection & CONFIG_ENTRY_HIDDEN) && IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Get" && GLOB.LastAdminCalledTargetRef == "[REF(src)]") + log_admin_private("Config access of [entry_type] attempted by [key_name(usr)]") + return + return E.config_entry_value + +/datum/controller/configuration/proc/Set(entry_type, new_val) + var/datum/config_entry/E = entry_type + var/entry_is_abstract = initial(E.abstract_type) == entry_type + if(entry_is_abstract) + CRASH("Tried to set an abstract config_entry: [entry_type]") + E = entries_by_type[entry_type] + if(!E) + CRASH("Missing config entry for [entry_type]!") + if((E.protection & CONFIG_ENTRY_LOCKED) && IsAdminAdvancedProcCall() && GLOB.LastAdminCalledProc == "Set" && GLOB.LastAdminCalledTargetRef == "[REF(src)]") + log_admin_private("Config rewrite of [entry_type] to [new_val] attempted by [key_name(usr)]") + return + return E.ValidateAndSet("[new_val]") + +/datum/controller/configuration/proc/LoadModes() + gamemode_cache = typecacheof(/datum/game_mode, TRUE) + modes = list() + mode_names = list() + mode_reports = list() + mode_false_report_weight = list() + votable_modes = list() + var/list/probabilities = Get(/datum/config_entry/keyed_list/probability) + for(var/T in gamemode_cache) + // I wish I didn't have to instance the game modes in order to look up + // their information, but it is the only way (at least that I know of). + // for future reference: just use initial() lol + var/datum/game_mode/M = new T() + + if(M.config_tag) + if(!(M.config_tag in modes)) // ensure each mode is added only once + modes += M.config_tag + mode_names[M.config_tag] = M.name + mode_reports[M.config_tag] = M.generate_report() + if(probabilities[M.config_tag]>0) + mode_false_report_weight[M.config_tag] = M.false_report_weight + else + mode_false_report_weight[M.config_tag] = 1 + if(M.votable) + votable_modes += M.config_tag + qdel(M) + votable_modes += "secret" + +/datum/controller/configuration/proc/LoadMOTD() + motd = file2text("[directory]/motd.txt") + var/tm_info = GLOB.revdata.GetTestMergeInfo() + if(motd || tm_info) + motd = motd ? "[motd]
      [tm_info]" : tm_info + +/datum/controller/configuration/proc/loadmaplist(filename) + log_config("Loading config file [filename]...") + filename = "[directory]/[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 = load_map_config("_maps/[data].json") + if(currentmap.defaulted) + log_config("Failed to load map config for [data]!") + currentmap = null + if ("minplayers","minplayer") + currentmap.config_min_users = text2num(data) + if ("maxplayers","maxplayer") + currentmap.config_max_users = text2num(data) + if ("weight","voteweight") + currentmap.voteweight = text2num(data) + if ("default","defaultmap") + defaultmap = currentmap + if ("endmap") + LAZYINITLIST(maplist) + maplist[currentmap.map_name] = currentmap + currentmap = null + if ("disabled") + currentmap = null + else + log_config("Unknown command in map vote config: '[command]'") + + +/datum/controller/configuration/proc/pick_mode(mode_name) + // I wish I didn't have to instance the game modes in order to look up + // their information, but it is the only way (at least that I know of). + // ^ This guy didn't try hard enough + for(var/T in gamemode_cache) + var/datum/game_mode/M = T + var/ct = initial(M.config_tag) + if(ct && ct == mode_name) + return new T + return new /datum/game_mode/extended() + +/datum/controller/configuration/proc/pick_storyteller(storyteller_name) + for(var/T in storyteller_cache) + var/datum/dynamic_storyteller/S = T + var/name = initial(S.name) + if(name && name == storyteller_name) + return T + return /datum/dynamic_storyteller/classic + +/datum/controller/configuration/proc/get_runnable_modes() + var/list/datum/game_mode/runnable_modes = new + var/list/probabilities = Get(/datum/config_entry/keyed_list/probability) + var/list/min_pop = Get(/datum/config_entry/keyed_list/min_pop) + var/list/max_pop = Get(/datum/config_entry/keyed_list/max_pop) + var/list/repeated_mode_adjust = Get(/datum/config_entry/number_list/repeated_mode_adjust) + for(var/T in gamemode_cache) + var/datum/game_mode/M = new T() + if(!(M.config_tag in modes)) + qdel(M) + continue + if(probabilities[M.config_tag]<=0) + qdel(M) + continue + if(M.config_tag in SSvote.stored_modetier_results && SSvote.stored_modetier_results[M.config_tag] < Get(/datum/config_entry/number/dropped_modes)) + qdel(M) + continue + if(min_pop[M.config_tag]) + M.required_players = min_pop[M.config_tag] + if(max_pop[M.config_tag]) + M.maximum_players = max_pop[M.config_tag] + if(M.can_start()) + var/final_weight = probabilities[M.config_tag] + if(SSpersistence.saved_modes.len == 3 && repeated_mode_adjust.len == 3) + var/recent_round = min(SSpersistence.saved_modes.Find(M.config_tag),3) + var/adjustment = 0 + while(recent_round) + adjustment += repeated_mode_adjust[recent_round] + recent_round = SSpersistence.saved_modes.Find(M.config_tag,recent_round+1,0) + final_weight *= ((100-adjustment)/100) + runnable_modes[M] = final_weight + return runnable_modes + +/datum/controller/configuration/proc/get_runnable_midround_modes(crew) + var/list/datum/game_mode/runnable_modes = new + var/list/probabilities = Get(/datum/config_entry/keyed_list/probability) + var/list/min_pop = Get(/datum/config_entry/keyed_list/min_pop) + var/list/max_pop = Get(/datum/config_entry/keyed_list/max_pop) + for(var/T in (gamemode_cache - SSticker.mode.type)) + var/datum/game_mode/M = new T() + if(!(M.config_tag in modes)) + qdel(M) + continue + if(probabilities[M.config_tag]<=0) + qdel(M) + continue + if(min_pop[M.config_tag]) + M.required_players = min_pop[M.config_tag] + if(max_pop[M.config_tag]) + M.maximum_players = max_pop[M.config_tag] + if(M.required_players <= crew) + if(M.maximum_players >= 0 && M.maximum_players < crew) + continue + runnable_modes[M] = probabilities[M.config_tag] + return runnable_modes diff --git a/code/controllers/configuration/entries/comms.dm b/code/controllers/configuration/entries/comms.dm index a1de1c962e..012c3ec9fe 100644 --- a/code/controllers/configuration/entries/comms.dm +++ b/code/controllers/configuration/entries/comms.dm @@ -1,28 +1,28 @@ -/datum/config_entry/string/comms_key - protection = CONFIG_ENTRY_HIDDEN - -/datum/config_entry/string/comms_key/ValidateAndSet(str_val) - return str_val != "default_pwd" && length(str_val) > 6 && ..() - -/datum/config_entry/keyed_list/cross_server - key_mode = KEY_MODE_TEXT - value_mode = VALUE_MODE_TEXT - protection = CONFIG_ENTRY_LOCKED - -/datum/config_entry/keyed_list/cross_server/ValidateAndSet(str_val) - . = ..() - if(.) - var/list/newv = list() - for(var/I in config_entry_value) - newv[replacetext(I, "+", " ")] = config_entry_value[I] - config_entry_value = newv - -/datum/config_entry/keyed_list/cross_server/ValidateListEntry(key_name, key_value) - return key_value != "byond:\\address:port" && ..() - -/datum/config_entry/string/cross_comms_name - -/datum/config_entry/string/medal_hub_address - -/datum/config_entry/string/medal_hub_password +/datum/config_entry/string/comms_key + protection = CONFIG_ENTRY_HIDDEN + +/datum/config_entry/string/comms_key/ValidateAndSet(str_val) + return str_val != "default_pwd" && length(str_val) > 6 && ..() + +/datum/config_entry/keyed_list/cross_server + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_TEXT + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/keyed_list/cross_server/ValidateAndSet(str_val) + . = ..() + if(.) + var/list/newv = list() + for(var/I in config_entry_value) + newv[replacetext(I, "+", " ")] = config_entry_value[I] + config_entry_value = newv + +/datum/config_entry/keyed_list/cross_server/ValidateListEntry(key_name, key_value) + return key_value != "byond:\\address:port" && ..() + +/datum/config_entry/string/cross_comms_name + +/datum/config_entry/string/medal_hub_address + +/datum/config_entry/string/medal_hub_password protection = CONFIG_ENTRY_HIDDEN \ No newline at end of file diff --git a/code/controllers/configuration/entries/dbconfig.dm b/code/controllers/configuration/entries/dbconfig.dm index b034195241..3dd4f4b0bd 100644 --- a/code/controllers/configuration/entries/dbconfig.dm +++ b/code/controllers/configuration/entries/dbconfig.dm @@ -1,51 +1,51 @@ -/datum/config_entry/flag/sql_enabled // for sql switching - protection = CONFIG_ENTRY_LOCKED - -/datum/config_entry/string/address - config_entry_value = "localhost" - protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN - -/datum/config_entry/number/port - config_entry_value = 3306 - min_val = 0 - max_val = 65535 - protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN - -/datum/config_entry/string/feedback_database - config_entry_value = "test" - protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN - -/datum/config_entry/string/feedback_login - config_entry_value = "root" - protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN - -/datum/config_entry/string/feedback_password - protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN - -/datum/config_entry/string/feedback_tableprefix - protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN - -/datum/config_entry/number/query_debug_log_timeout - config_entry_value = 70 - min_val = 1 - protection = CONFIG_ENTRY_LOCKED - deprecated_by = /datum/config_entry/number/blocking_query_timeout - -/datum/config_entry/number/query_debug_log_timeout/DeprecationUpdate(value) - return value - -/datum/config_entry/number/async_query_timeout - config_entry_value = 10 - min_val = 0 - protection = CONFIG_ENTRY_LOCKED - -/datum/config_entry/number/blocking_query_timeout - config_entry_value = 5 - min_val = 0 - protection = CONFIG_ENTRY_LOCKED - -/datum/config_entry/number/bsql_thread_limit - config_entry_value = 50 - min_val = 1 - -/datum/config_entry/flag/bsql_debug +/datum/config_entry/flag/sql_enabled // for sql switching + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/address + config_entry_value = "localhost" + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +/datum/config_entry/number/port + config_entry_value = 3306 + min_val = 0 + max_val = 65535 + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +/datum/config_entry/string/feedback_database + config_entry_value = "test" + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +/datum/config_entry/string/feedback_login + config_entry_value = "root" + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +/datum/config_entry/string/feedback_password + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +/datum/config_entry/string/feedback_tableprefix + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +/datum/config_entry/number/query_debug_log_timeout + config_entry_value = 70 + min_val = 1 + protection = CONFIG_ENTRY_LOCKED + deprecated_by = /datum/config_entry/number/blocking_query_timeout + +/datum/config_entry/number/query_debug_log_timeout/DeprecationUpdate(value) + return value + +/datum/config_entry/number/async_query_timeout + config_entry_value = 10 + min_val = 0 + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/number/blocking_query_timeout + config_entry_value = 5 + min_val = 0 + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/number/bsql_thread_limit + config_entry_value = 50 + min_val = 1 + +/datum/config_entry/flag/bsql_debug diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index 8b6bbe83b4..940ba52946 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -1,402 +1,402 @@ -/datum/config_entry/number_list/repeated_mode_adjust - -/datum/config_entry/keyed_list/probability - key_mode = KEY_MODE_TEXT - value_mode = VALUE_MODE_NUM - -/datum/config_entry/keyed_list/probability/ValidateListEntry(key_name) - return key_name in config.modes - -/datum/config_entry/keyed_list/max_pop - key_mode = KEY_MODE_TEXT - value_mode = VALUE_MODE_NUM - -/datum/config_entry/keyed_list/max_pop/ValidateListEntry(key_name) - return key_name in config.modes - -/datum/config_entry/keyed_list/min_pop - key_mode = KEY_MODE_TEXT - value_mode = VALUE_MODE_NUM - -/datum/config_entry/keyed_list/min_pop/ValidateListEntry(key_name, key_value) - return key_name in config.modes - -/datum/config_entry/keyed_list/continuous // which roundtypes continue if all antagonists die - key_mode = KEY_MODE_TEXT - value_mode = VALUE_MODE_FLAG - -/datum/config_entry/keyed_list/continuous/ValidateListEntry(key_name, key_value) - return key_name in config.modes - -/datum/config_entry/keyed_list/midround_antag // which roundtypes use the midround antagonist system - key_mode = KEY_MODE_TEXT - value_mode = VALUE_MODE_FLAG - -/datum/config_entry/keyed_list/midround_antag/ValidateListEntry(key_name, key_value) - return key_name in config.modes - -/datum/config_entry/keyed_list/policy - key_mode = KEY_MODE_TEXT - value_mode = VALUE_MODE_TEXT - -/datum/config_entry/number/damage_multiplier - config_entry_value = 1 - integer = FALSE - -/datum/config_entry/number/minimal_access_threshold //If the number of players is larger than this threshold, minimal access will be turned on. - min_val = 0 - -/datum/config_entry/flag/jobs_have_minimal_access //determines whether jobs use minimal access or expanded access. - -/datum/config_entry/flag/assistants_have_maint_access - -/datum/config_entry/flag/security_has_maint_access - -/datum/config_entry/flag/everyone_has_maint_access - -/datum/config_entry/flag/sec_start_brig //makes sec start in brig instead of dept sec posts - -/datum/config_entry/flag/force_random_names - -/datum/config_entry/flag/humans_need_surnames - -/datum/config_entry/flag/allow_ai // allow ai job - -/datum/config_entry/flag/allow_ai_multicam //whether the AI can use their multicam - -/datum/config_entry/flag/disable_human_mood - -/datum/config_entry/flag/disable_borg_flash_knockdown //Should borg flashes be capable of knocking humanoid entities down? - -/datum/config_entry/flag/weaken_secborg //Brings secborgs and k9s back in-line with the other borg modules - -/datum/config_entry/flag/disable_secborg // disallow secborg module to be chosen. - -/datum/config_entry/flag/disable_peaceborg - -/datum/config_entry/number/minimum_secborg_alert //Minimum alert level for secborgs to be chosen. - config_entry_value = 3 - -/datum/config_entry/number/traitor_scaling_coeff //how much does the amount of players get divided by to determine traitors - config_entry_value = 6 - min_val = 1 - -/datum/config_entry/number/brother_scaling_coeff //how many players per brother team - config_entry_value = 25 - min_val = 1 - -/datum/config_entry/number/changeling_scaling_coeff //how much does the amount of players get divided by to determine changelings - config_entry_value = 6 - min_val = 1 - -/datum/config_entry/number/security_scaling_coeff //how much does the amount of players get divided by to determine open security officer positions - config_entry_value = 8 - min_val = 1 - -/datum/config_entry/number/abductor_scaling_coeff //how many players per abductor team - config_entry_value = 15 - min_val = 1 - -/datum/config_entry/number/traitor_objectives_amount - config_entry_value = 2 - min_val = 0 - -/datum/config_entry/number/brother_objectives_amount - config_entry_value = 2 - min_val = 0 - -/datum/config_entry/flag/reactionary_explosions //If we use reactionary explosions, explosions that react to walls and doors - -/datum/config_entry/flag/protect_roles_from_antagonist //If security and such can be traitor/cult/other - -/datum/config_entry/flag/protect_assistant_from_antagonist //If assistants can be traitor/cult/other - -/datum/config_entry/flag/enforce_human_authority //If non-human species are barred from joining as a head of staff - -/datum/config_entry/flag/allow_latejoin_antagonists // If late-joining players can be traitor/changeling - -/datum/config_entry/flag/use_antag_rep // see game_options.txt for details - -/datum/config_entry/number/antag_rep_maximum - config_entry_value = 200 - min_val = 0 - -/datum/config_entry/number/default_antag_tickets - config_entry_value = 100 - min_val = 0 - -/datum/config_entry/number/max_tickets_per_roll - config_entry_value = 100 - min_val = 0 - -/datum/config_entry/number/midround_antag_time_check // How late (in minutes you want the midround antag system to stay on, setting this to 0 will disable the system) - config_entry_value = 60 - min_val = 0 - -/datum/config_entry/number/midround_antag_life_check // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist - config_entry_value = 0.7 - integer = FALSE - min_val = 0 - max_val = 1 - -/datum/config_entry/number/suicide_reenter_round_timer - config_entry_value = 30 - min_val = 0 - -/datum/config_entry/number/roundstart_suicide_time_limit - config_entry_value = 30 - min_val = 0 - -/datum/config_entry/number/shuttle_refuel_delay - config_entry_value = 12000 - min_val = 0 - -/datum/config_entry/flag/show_game_type_odds //if set this allows players to see the odds of each roundtype on the get revision screen - -/datum/config_entry/keyed_list/roundstart_races //races you can play as from the get go. - key_mode = KEY_MODE_TEXT - value_mode = VALUE_MODE_FLAG - -/datum/config_entry/flag/join_with_mutant_humans //players can pick mutant bodyparts for humans before joining the game - -/datum/config_entry/flag/no_summon_guns //No - -/datum/config_entry/flag/no_summon_magic //Fun - -/datum/config_entry/flag/no_summon_events //Allowed - -/datum/config_entry/flag/no_intercept_report //Whether or not to send a communications intercept report roundstart. This may be overridden by gamemodes. - -/datum/config_entry/number/arrivals_shuttle_dock_window //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station - config_entry_value = 55 - min_val = 30 - -/datum/config_entry/flag/arrivals_shuttle_require_undocked //Require the arrivals shuttle to be undocked before latejoiners can join - -/datum/config_entry/flag/arrivals_shuttle_require_safe_latejoin //Require the arrivals shuttle to be operational in order for latejoiners to join - -/datum/config_entry/string/alert_green - config_entry_value = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced." - -/datum/config_entry/string/alert_blue_upto - config_entry_value = "The station has received reliable information about potential threats to the station. Security staff may have weapons visible, random searches are permitted." - -/datum/config_entry/string/alert_blue_downto - config_entry_value = "Significant confirmed threats have been neutralized. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still permitted." - -/datum/config_entry/string/alert_amber_upto - config_entry_value = "There are significant confirmed threats to the station. Security staff may have weapons unholstered at all times. Random searches are allowed and advised." - -/datum/config_entry/string/alert_amber_downto - config_entry_value = "The immediate threat has passed. Security is no longer authorized to use lethal force, but may continue to have weapons drawn. Access requirements have been restored." - -/datum/config_entry/string/alert_red_upto - config_entry_value = "There is an immediate serious threat to the station. Security is now authorized to use lethal force. Additionally, access requirements on some machines have been lifted." - -/datum/config_entry/string/alert_red_downto - config_entry_value = "The station's destruction has been averted. There is still however an immediate serious threat to the station. Security is still authorized to use lethal force." - -/datum/config_entry/string/alert_delta - config_entry_value = "Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill." - -/datum/config_entry/flag/revival_pod_plants - -/datum/config_entry/flag/revival_cloning - -/datum/config_entry/number/revival_brain_life - config_entry_value = -1 - min_val = -1 - -/datum/config_entry/flag/ooc_during_round - -/datum/config_entry/flag/emojis - -/datum/config_entry/keyed_list/multiplicative_movespeed - key_mode = KEY_MODE_TYPE - value_mode = VALUE_MODE_NUM - config_entry_value = list( //DEFAULTS - /mob/living/simple_animal = 1, - /mob/living/silicon/pai = 1, - /mob/living/carbon/alien/humanoid/hunter = -1, - /mob/living/carbon/alien/humanoid/royal/praetorian = 1, - /mob/living/carbon/alien/humanoid/royal/queen = 3 - ) - -/datum/config_entry/keyed_list/multiplicative_movespeed/ValidateAndSet() - . = ..() - if(.) - update_config_movespeed_type_lookup(TRUE) - -/datum/config_entry/keyed_list/multiplicative_movespeed/vv_edit_var(var_name, var_value) - . = ..() - if(. && (var_name == NAMEOF(src, config_entry_value))) - update_config_movespeed_type_lookup(TRUE) - -/datum/config_entry/number/movedelay //Used for modifying movement speed for mobs. - abstract_type = /datum/config_entry/number/movedelay - -/datum/config_entry/number/movedelay/ValidateAndSet() - . = ..() - if(.) - update_mob_config_movespeeds() - -/datum/config_entry/number/movedelay/vv_edit_var(var_name, var_value) - . = ..() - if(. && (var_name == NAMEOF(src, config_entry_value))) - update_mob_config_movespeeds() - -/datum/config_entry/number/movedelay/run_delay - -/datum/config_entry/number/movedelay/walk_delay - -/////////////////////////////////////////////////Outdated move delay -/datum/config_entry/number/outdated_movedelay - deprecated_by = /datum/config_entry/keyed_list/multiplicative_movespeed - abstract_type = /datum/config_entry/number/outdated_movedelay - - var/movedelay_type - -/datum/config_entry/number/outdated_movedelay/DeprecationUpdate(value) - return "[movedelay_type] [value]" - -/datum/config_entry/number/outdated_movedelay/human_delay - movedelay_type = /mob/living/carbon/human -/datum/config_entry/number/outdated_movedelay/robot_delay - movedelay_type = /mob/living/silicon/robot -/datum/config_entry/number/outdated_movedelay/monkey_delay - movedelay_type = /mob/living/carbon/monkey -/datum/config_entry/number/outdated_movedelay/alien_delay - movedelay_type = /mob/living/carbon/alien -/datum/config_entry/number/outdated_movedelay/slime_delay - movedelay_type = /mob/living/simple_animal/slime -/datum/config_entry/number/outdated_movedelay/animal_delay - movedelay_type = /mob/living/simple_animal -///////////////////////////////////////////////// - -/datum/config_entry/flag/roundstart_away //Will random away mission be loaded. - -/datum/config_entry/number/gateway_delay //How long the gateway takes before it activates. Default is half an hour. Only matters if roundstart_away is enabled. - config_entry_value = 18000 - min_val = 0 - -/datum/config_entry/flag/ghost_interaction - -/datum/config_entry/flag/silent_ai -/datum/config_entry/flag/silent_borg - -/datum/config_entry/flag/sandbox_autoclose // close the sandbox panel after spawning an item, potentially reducing griff - -/datum/config_entry/number/default_laws //Controls what laws the AI spawns with. - config_entry_value = 0 - min_val = 0 - max_val = 3 - -/datum/config_entry/number/silicon_max_law_amount - config_entry_value = 12 - min_val = 0 - -/datum/config_entry/keyed_list/random_laws - key_mode = KEY_MODE_TEXT - value_mode = VALUE_MODE_FLAG - -/datum/config_entry/keyed_list/law_weight - key_mode = KEY_MODE_TEXT - value_mode = VALUE_MODE_NUM - splitter = "," - -/datum/config_entry/number/overflow_cap - config_entry_value = -1 - min_val = -1 - -/datum/config_entry/string/overflow_job - config_entry_value = "Assistant" - -/datum/config_entry/flag/starlight -/datum/config_entry/flag/grey_assistants - -/datum/config_entry/number/lavaland_budget - config_entry_value = 60 - min_val = 0 - -/datum/config_entry/number/space_budget - config_entry_value = 16 - min_val = 0 - -/datum/config_entry/flag/allow_random_events // Enables random events mid-round when set - -/datum/config_entry/number/events_min_time_mul // Multipliers for random events minimal starting time and minimal players amounts - config_entry_value = 1 - min_val = 0 - integer = FALSE - -/datum/config_entry/number/events_min_players_mul - config_entry_value = 1 - min_val = 0 - integer = FALSE - -/datum/config_entry/number/mice_roundstart - config_entry_value = 10 - min_val = 0 - -/datum/config_entry/number/bombcap - config_entry_value = 14 - min_val = 4 - -/datum/config_entry/number/bombcap/ValidateAndSet(str_val) - . = ..() - if(.) - GLOB.MAX_EX_DEVESTATION_RANGE = round(config_entry_value / 4) - GLOB.MAX_EX_HEAVY_RANGE = round(config_entry_value / 2) - GLOB.MAX_EX_LIGHT_RANGE = config_entry_value - GLOB.MAX_EX_FLASH_RANGE = config_entry_value - GLOB.MAX_EX_FLAME_RANGE = config_entry_value - -/datum/config_entry/number/emergency_shuttle_autocall_threshold - min_val = 0 - max_val = 1 - integer = FALSE - -/datum/config_entry/flag/ic_printing - -/datum/config_entry/flag/roundstart_traits - -/datum/config_entry/flag/enable_night_shifts - -/datum/config_entry/flag/randomize_shift_time - -/datum/config_entry/flag/shift_time_realtime - -/datum/config_entry/keyed_list/antag_rep - key_mode = KEY_MODE_TEXT - value_mode = VALUE_MODE_NUM - -/datum/config_entry/number/monkeycap - config_entry_value = 64 - min_val = 0 - -/datum/config_entry/flag/disable_stambuffer - -/datum/config_entry/keyed_list/box_random_engine - key_mode = KEY_MODE_TEXT - value_mode = VALUE_MODE_NUM - lowercase = FALSE - splitter = "," - -/datum/config_entry/number/auto_transfer_delay - config_entry_value = 72000 - min_val = 0 - -/datum/config_entry/flag/pai_custom_holoforms - -/datum/config_entry/number/marauder_delay_non_reebe - config_entry_value = 1800 - min_val = 0 - -/datum/config_entry/flag/allow_clockwork_marauder_on_station - config_entry_value = TRUE - -/datum/config_entry/flag/modetier_voting - config_entry_value = TRUE - -/datum/config_entry/number/dropped_modes - config_entry_value = 3 +/datum/config_entry/number_list/repeated_mode_adjust + +/datum/config_entry/keyed_list/probability + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_NUM + +/datum/config_entry/keyed_list/probability/ValidateListEntry(key_name) + return key_name in config.modes + +/datum/config_entry/keyed_list/max_pop + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_NUM + +/datum/config_entry/keyed_list/max_pop/ValidateListEntry(key_name) + return key_name in config.modes + +/datum/config_entry/keyed_list/min_pop + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_NUM + +/datum/config_entry/keyed_list/min_pop/ValidateListEntry(key_name, key_value) + return key_name in config.modes + +/datum/config_entry/keyed_list/continuous // which roundtypes continue if all antagonists die + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_FLAG + +/datum/config_entry/keyed_list/continuous/ValidateListEntry(key_name, key_value) + return key_name in config.modes + +/datum/config_entry/keyed_list/midround_antag // which roundtypes use the midround antagonist system + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_FLAG + +/datum/config_entry/keyed_list/midround_antag/ValidateListEntry(key_name, key_value) + return key_name in config.modes + +/datum/config_entry/keyed_list/policy + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_TEXT + +/datum/config_entry/number/damage_multiplier + config_entry_value = 1 + integer = FALSE + +/datum/config_entry/number/minimal_access_threshold //If the number of players is larger than this threshold, minimal access will be turned on. + min_val = 0 + +/datum/config_entry/flag/jobs_have_minimal_access //determines whether jobs use minimal access or expanded access. + +/datum/config_entry/flag/assistants_have_maint_access + +/datum/config_entry/flag/security_has_maint_access + +/datum/config_entry/flag/everyone_has_maint_access + +/datum/config_entry/flag/sec_start_brig //makes sec start in brig instead of dept sec posts + +/datum/config_entry/flag/force_random_names + +/datum/config_entry/flag/humans_need_surnames + +/datum/config_entry/flag/allow_ai // allow ai job + +/datum/config_entry/flag/allow_ai_multicam //whether the AI can use their multicam + +/datum/config_entry/flag/disable_human_mood + +/datum/config_entry/flag/disable_borg_flash_knockdown //Should borg flashes be capable of knocking humanoid entities down? + +/datum/config_entry/flag/weaken_secborg //Brings secborgs and k9s back in-line with the other borg modules + +/datum/config_entry/flag/disable_secborg // disallow secborg module to be chosen. + +/datum/config_entry/flag/disable_peaceborg + +/datum/config_entry/number/minimum_secborg_alert //Minimum alert level for secborgs to be chosen. + config_entry_value = 3 + +/datum/config_entry/number/traitor_scaling_coeff //how much does the amount of players get divided by to determine traitors + config_entry_value = 6 + min_val = 1 + +/datum/config_entry/number/brother_scaling_coeff //how many players per brother team + config_entry_value = 25 + min_val = 1 + +/datum/config_entry/number/changeling_scaling_coeff //how much does the amount of players get divided by to determine changelings + config_entry_value = 6 + min_val = 1 + +/datum/config_entry/number/security_scaling_coeff //how much does the amount of players get divided by to determine open security officer positions + config_entry_value = 8 + min_val = 1 + +/datum/config_entry/number/abductor_scaling_coeff //how many players per abductor team + config_entry_value = 15 + min_val = 1 + +/datum/config_entry/number/traitor_objectives_amount + config_entry_value = 2 + min_val = 0 + +/datum/config_entry/number/brother_objectives_amount + config_entry_value = 2 + min_val = 0 + +/datum/config_entry/flag/reactionary_explosions //If we use reactionary explosions, explosions that react to walls and doors + +/datum/config_entry/flag/protect_roles_from_antagonist //If security and such can be traitor/cult/other + +/datum/config_entry/flag/protect_assistant_from_antagonist //If assistants can be traitor/cult/other + +/datum/config_entry/flag/enforce_human_authority //If non-human species are barred from joining as a head of staff + +/datum/config_entry/flag/allow_latejoin_antagonists // If late-joining players can be traitor/changeling + +/datum/config_entry/flag/use_antag_rep // see game_options.txt for details + +/datum/config_entry/number/antag_rep_maximum + config_entry_value = 200 + min_val = 0 + +/datum/config_entry/number/default_antag_tickets + config_entry_value = 100 + min_val = 0 + +/datum/config_entry/number/max_tickets_per_roll + config_entry_value = 100 + min_val = 0 + +/datum/config_entry/number/midround_antag_time_check // How late (in minutes you want the midround antag system to stay on, setting this to 0 will disable the system) + config_entry_value = 60 + min_val = 0 + +/datum/config_entry/number/midround_antag_life_check // A ratio of how many people need to be alive in order for the round not to immediately end in midround antagonist + config_entry_value = 0.7 + integer = FALSE + min_val = 0 + max_val = 1 + +/datum/config_entry/number/suicide_reenter_round_timer + config_entry_value = 30 + min_val = 0 + +/datum/config_entry/number/roundstart_suicide_time_limit + config_entry_value = 30 + min_val = 0 + +/datum/config_entry/number/shuttle_refuel_delay + config_entry_value = 12000 + min_val = 0 + +/datum/config_entry/flag/show_game_type_odds //if set this allows players to see the odds of each roundtype on the get revision screen + +/datum/config_entry/keyed_list/roundstart_races //races you can play as from the get go. + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_FLAG + +/datum/config_entry/flag/join_with_mutant_humans //players can pick mutant bodyparts for humans before joining the game + +/datum/config_entry/flag/no_summon_guns //No + +/datum/config_entry/flag/no_summon_magic //Fun + +/datum/config_entry/flag/no_summon_events //Allowed + +/datum/config_entry/flag/no_intercept_report //Whether or not to send a communications intercept report roundstart. This may be overridden by gamemodes. + +/datum/config_entry/number/arrivals_shuttle_dock_window //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station + config_entry_value = 55 + min_val = 30 + +/datum/config_entry/flag/arrivals_shuttle_require_undocked //Require the arrivals shuttle to be undocked before latejoiners can join + +/datum/config_entry/flag/arrivals_shuttle_require_safe_latejoin //Require the arrivals shuttle to be operational in order for latejoiners to join + +/datum/config_entry/string/alert_green + config_entry_value = "All threats to the station have passed. Security may not have weapons visible, privacy laws are once again fully enforced." + +/datum/config_entry/string/alert_blue_upto + config_entry_value = "The station has received reliable information about potential threats to the station. Security staff may have weapons visible, random searches are permitted." + +/datum/config_entry/string/alert_blue_downto + config_entry_value = "Significant confirmed threats have been neutralized. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still permitted." + +/datum/config_entry/string/alert_amber_upto + config_entry_value = "There are significant confirmed threats to the station. Security staff may have weapons unholstered at all times. Random searches are allowed and advised." + +/datum/config_entry/string/alert_amber_downto + config_entry_value = "The immediate threat has passed. Security is no longer authorized to use lethal force, but may continue to have weapons drawn. Access requirements have been restored." + +/datum/config_entry/string/alert_red_upto + config_entry_value = "There is an immediate serious threat to the station. Security is now authorized to use lethal force. Additionally, access requirements on some machines have been lifted." + +/datum/config_entry/string/alert_red_downto + config_entry_value = "The station's destruction has been averted. There is still however an immediate serious threat to the station. Security is still authorized to use lethal force." + +/datum/config_entry/string/alert_delta + config_entry_value = "Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill." + +/datum/config_entry/flag/revival_pod_plants + +/datum/config_entry/flag/revival_cloning + +/datum/config_entry/number/revival_brain_life + config_entry_value = -1 + min_val = -1 + +/datum/config_entry/flag/ooc_during_round + +/datum/config_entry/flag/emojis + +/datum/config_entry/keyed_list/multiplicative_movespeed + key_mode = KEY_MODE_TYPE + value_mode = VALUE_MODE_NUM + config_entry_value = list( //DEFAULTS + /mob/living/simple_animal = 1, + /mob/living/silicon/pai = 1, + /mob/living/carbon/alien/humanoid/hunter = -1, + /mob/living/carbon/alien/humanoid/royal/praetorian = 1, + /mob/living/carbon/alien/humanoid/royal/queen = 3 + ) + +/datum/config_entry/keyed_list/multiplicative_movespeed/ValidateAndSet() + . = ..() + if(.) + update_config_movespeed_type_lookup(TRUE) + +/datum/config_entry/keyed_list/multiplicative_movespeed/vv_edit_var(var_name, var_value) + . = ..() + if(. && (var_name == NAMEOF(src, config_entry_value))) + update_config_movespeed_type_lookup(TRUE) + +/datum/config_entry/number/movedelay //Used for modifying movement speed for mobs. + abstract_type = /datum/config_entry/number/movedelay + +/datum/config_entry/number/movedelay/ValidateAndSet() + . = ..() + if(.) + update_mob_config_movespeeds() + +/datum/config_entry/number/movedelay/vv_edit_var(var_name, var_value) + . = ..() + if(. && (var_name == NAMEOF(src, config_entry_value))) + update_mob_config_movespeeds() + +/datum/config_entry/number/movedelay/run_delay + +/datum/config_entry/number/movedelay/walk_delay + +/////////////////////////////////////////////////Outdated move delay +/datum/config_entry/number/outdated_movedelay + deprecated_by = /datum/config_entry/keyed_list/multiplicative_movespeed + abstract_type = /datum/config_entry/number/outdated_movedelay + + var/movedelay_type + +/datum/config_entry/number/outdated_movedelay/DeprecationUpdate(value) + return "[movedelay_type] [value]" + +/datum/config_entry/number/outdated_movedelay/human_delay + movedelay_type = /mob/living/carbon/human +/datum/config_entry/number/outdated_movedelay/robot_delay + movedelay_type = /mob/living/silicon/robot +/datum/config_entry/number/outdated_movedelay/monkey_delay + movedelay_type = /mob/living/carbon/monkey +/datum/config_entry/number/outdated_movedelay/alien_delay + movedelay_type = /mob/living/carbon/alien +/datum/config_entry/number/outdated_movedelay/slime_delay + movedelay_type = /mob/living/simple_animal/slime +/datum/config_entry/number/outdated_movedelay/animal_delay + movedelay_type = /mob/living/simple_animal +///////////////////////////////////////////////// + +/datum/config_entry/flag/roundstart_away //Will random away mission be loaded. + +/datum/config_entry/number/gateway_delay //How long the gateway takes before it activates. Default is half an hour. Only matters if roundstart_away is enabled. + config_entry_value = 18000 + min_val = 0 + +/datum/config_entry/flag/ghost_interaction + +/datum/config_entry/flag/silent_ai +/datum/config_entry/flag/silent_borg + +/datum/config_entry/flag/sandbox_autoclose // close the sandbox panel after spawning an item, potentially reducing griff + +/datum/config_entry/number/default_laws //Controls what laws the AI spawns with. + config_entry_value = 0 + min_val = 0 + max_val = 3 + +/datum/config_entry/number/silicon_max_law_amount + config_entry_value = 12 + min_val = 0 + +/datum/config_entry/keyed_list/random_laws + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_FLAG + +/datum/config_entry/keyed_list/law_weight + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_NUM + splitter = "," + +/datum/config_entry/number/overflow_cap + config_entry_value = -1 + min_val = -1 + +/datum/config_entry/string/overflow_job + config_entry_value = "Assistant" + +/datum/config_entry/flag/starlight +/datum/config_entry/flag/grey_assistants + +/datum/config_entry/number/lavaland_budget + config_entry_value = 60 + min_val = 0 + +/datum/config_entry/number/space_budget + config_entry_value = 16 + min_val = 0 + +/datum/config_entry/flag/allow_random_events // Enables random events mid-round when set + +/datum/config_entry/number/events_min_time_mul // Multipliers for random events minimal starting time and minimal players amounts + config_entry_value = 1 + min_val = 0 + integer = FALSE + +/datum/config_entry/number/events_min_players_mul + config_entry_value = 1 + min_val = 0 + integer = FALSE + +/datum/config_entry/number/mice_roundstart + config_entry_value = 10 + min_val = 0 + +/datum/config_entry/number/bombcap + config_entry_value = 14 + min_val = 4 + +/datum/config_entry/number/bombcap/ValidateAndSet(str_val) + . = ..() + if(.) + GLOB.MAX_EX_DEVESTATION_RANGE = round(config_entry_value / 4) + GLOB.MAX_EX_HEAVY_RANGE = round(config_entry_value / 2) + GLOB.MAX_EX_LIGHT_RANGE = config_entry_value + GLOB.MAX_EX_FLASH_RANGE = config_entry_value + GLOB.MAX_EX_FLAME_RANGE = config_entry_value + +/datum/config_entry/number/emergency_shuttle_autocall_threshold + min_val = 0 + max_val = 1 + integer = FALSE + +/datum/config_entry/flag/ic_printing + +/datum/config_entry/flag/roundstart_traits + +/datum/config_entry/flag/enable_night_shifts + +/datum/config_entry/flag/randomize_shift_time + +/datum/config_entry/flag/shift_time_realtime + +/datum/config_entry/keyed_list/antag_rep + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_NUM + +/datum/config_entry/number/monkeycap + config_entry_value = 64 + min_val = 0 + +/datum/config_entry/flag/disable_stambuffer + +/datum/config_entry/keyed_list/box_random_engine + key_mode = KEY_MODE_TEXT + value_mode = VALUE_MODE_NUM + lowercase = FALSE + splitter = "," + +/datum/config_entry/number/auto_transfer_delay + config_entry_value = 72000 + min_val = 0 + +/datum/config_entry/flag/pai_custom_holoforms + +/datum/config_entry/number/marauder_delay_non_reebe + config_entry_value = 1800 + min_val = 0 + +/datum/config_entry/flag/allow_clockwork_marauder_on_station + config_entry_value = TRUE + +/datum/config_entry/flag/modetier_voting + config_entry_value = TRUE + +/datum/config_entry/number/dropped_modes + config_entry_value = 3 diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index a412ad2f48..2a08ce77a8 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -1,431 +1,431 @@ -/datum/config_entry/flag/autoadmin // if autoadmin is enabled - protection = CONFIG_ENTRY_LOCKED - -/datum/config_entry/string/autoadmin_rank // the rank for autoadmins - config_entry_value = "Game Master" - protection = CONFIG_ENTRY_LOCKED - -/datum/config_entry/string/servername // server name (the name of the game window) - -/datum/config_entry/string/servertagline - config_entry_value = "We forgot to set the server's tagline in config.txt" - -/datum/config_entry/string/serversqlname // short form server name used for the DB - -/datum/config_entry/string/stationname // station name (the name of the station in-game) - -/datum/config_entry/number/lobby_countdown // In between round countdown. - config_entry_value = 120 - min_val = 0 - -/datum/config_entry/number/round_end_countdown // Post round murder death kill countdown - config_entry_value = 25 - min_val = 0 - -/datum/config_entry/flag/hub // if the game appears on the hub or not - -/datum/config_entry/flag/log_ooc // log OOC channel - -/datum/config_entry/flag/log_access // log login/logout - -/datum/config_entry/flag/log_say // log client say - -/datum/config_entry/flag/log_admin // log admin actions - protection = CONFIG_ENTRY_LOCKED - -/datum/config_entry/flag/log_prayer // log prayers - -/datum/config_entry/flag/log_law // log lawchanges - -/datum/config_entry/flag/log_game // log game events - -/datum/config_entry/flag/log_virus // log virology data - -/datum/config_entry/flag/log_vote // log voting - -/datum/config_entry/flag/log_whisper // log client whisper - -/datum/config_entry/flag/log_attack // log attack messages - -/datum/config_entry/flag/log_emote // log emotes - -/datum/config_entry/flag/log_adminchat // log admin chat messages - protection = CONFIG_ENTRY_LOCKED - -/datum/config_entry/flag/log_pda // log pda messages - -/datum/config_entry/flag/log_telecomms // log telecomms messages - -/datum/config_entry/flag/log_twitter // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases. - -/datum/config_entry/flag/log_world_topic // log all world.Topic() calls - -/datum/config_entry/flag/log_manifest // log crew manifest to seperate file - -/datum/config_entry/flag/log_job_debug // log roundstart divide occupations debug information to a file - -/datum/config_entry/flag/allow_admin_ooccolor // Allows admins with relevant permissions to have their own ooc colour - -/datum/config_entry/flag/allow_vote_restart // allow votes to restart - -/datum/config_entry/flag/allow_vote_mode // allow votes to change mode - -/datum/config_entry/number/vote_delay // minimum time between voting sessions (deciseconds, 10 minute default) - config_entry_value = 6000 - min_val = 0 - -/datum/config_entry/number/vote_period // length of voting period (deciseconds, default 1 minute) - config_entry_value = 600 - min_val = 0 - -/datum/config_entry/flag/default_no_vote // vote does not default to nochange/norestart - -/datum/config_entry/flag/no_dead_vote // dead people can't vote - -/datum/config_entry/flag/allow_metadata // Metadata is supported. - -/datum/config_entry/flag/popup_admin_pm // adminPMs to non-admins show in a pop-up 'reply' window when set - -/datum/config_entry/number/fps - config_entry_value = 20 - min_val = 1 - max_val = 100 //byond will start crapping out at 50, so this is just ridic - var/sync_validate = FALSE - -/datum/config_entry/number/fps/ValidateAndSet(str_val) - . = ..() - if(.) - sync_validate = TRUE - var/datum/config_entry/number/ticklag/TL = config.entries_by_type[/datum/config_entry/number/ticklag] - if(!TL.sync_validate) - TL.ValidateAndSet(10 / config_entry_value) - sync_validate = FALSE - -/datum/config_entry/number/ticklag - integer = FALSE - var/sync_validate = FALSE - -/datum/config_entry/number/ticklag/New() //ticklag weirdly just mirrors fps - var/datum/config_entry/CE = /datum/config_entry/number/fps - config_entry_value = 10 / initial(CE.config_entry_value) - ..() - -/datum/config_entry/number/ticklag/ValidateAndSet(str_val) - . = text2num(str_val) > 0 && ..() - if(.) - sync_validate = TRUE - var/datum/config_entry/number/fps/FPS = config.entries_by_type[/datum/config_entry/number/fps] - if(!FPS.sync_validate) - FPS.ValidateAndSet(10 / config_entry_value) - sync_validate = FALSE - -/datum/config_entry/flag/allow_holidays - -/datum/config_entry/number/tick_limit_mc_init //SSinitialization throttling - config_entry_value = TICK_LIMIT_MC_INIT_DEFAULT - min_val = 0 //oranges warned us - integer = FALSE - -/datum/config_entry/flag/admin_legacy_system //Defines whether the server uses the legacy admin system with admins.txt or the SQL system - protection = CONFIG_ENTRY_LOCKED - -/datum/config_entry/flag/protect_legacy_admins //Stops any admins loaded by the legacy system from having their rank edited by the permissions panel - protection = CONFIG_ENTRY_LOCKED - -/datum/config_entry/flag/protect_legacy_ranks //Stops any ranks loaded by the legacy system from having their flags edited by the permissions panel - protection = CONFIG_ENTRY_LOCKED - -/datum/config_entry/flag/enable_localhost_rank //Gives the !localhost! rank to any client connecting from 127.0.0.1 or ::1 - protection = CONFIG_ENTRY_LOCKED - -/datum/config_entry/flag/load_legacy_ranks_only //Loads admin ranks only from legacy admin_ranks.txt, while enabled ranks are mirrored to the database - protection = CONFIG_ENTRY_LOCKED - -/datum/config_entry/flag/mentors_mobname_only - -/datum/config_entry/flag/mentor_legacy_system //Defines whether the server uses the legacy mentor system with mentors.txt or the SQL system - protection = CONFIG_ENTRY_LOCKED - -/datum/config_entry/string/hostedby - -/datum/config_entry/flag/norespawn - -/datum/config_entry/flag/guest_jobban - -/datum/config_entry/flag/usewhitelist - -/datum/config_entry/flag/ban_legacy_system //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. - protection = CONFIG_ENTRY_LOCKED - -/datum/config_entry/flag/use_age_restriction_for_jobs //Do jobs use account age restrictions? --requires database - -/datum/config_entry/flag/use_account_age_for_jobs //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected. - -/datum/config_entry/flag/use_exp_tracking - -/datum/config_entry/flag/use_exp_restrictions_heads - -/datum/config_entry/number/use_exp_restrictions_heads_hours - config_entry_value = 0 - min_val = 0 - -/datum/config_entry/flag/use_exp_restrictions_heads_department - -/datum/config_entry/flag/use_exp_restrictions_other - -/datum/config_entry/flag/use_exp_restrictions_admin_bypass - -/datum/config_entry/string/server - -/datum/config_entry/string/banappeals - -/datum/config_entry/string/wikiurl - config_entry_value = "https://katlin.dog/citadel-wiki" - -/datum/config_entry/string/wikiurltg - config_entry_value = "http://www.tgstation13.org/wiki" - -/datum/config_entry/string/forumurl - config_entry_value = "http://tgstation13.org/phpBB/index.php" - -/datum/config_entry/string/rulesurl - config_entry_value = "http://www.tgstation13.org/wiki/Rules" - -/datum/config_entry/string/githuburl - config_entry_value = "https://www.github.com/tgstation/-tg-station" - -/datum/config_entry/string/roundstatsurl - -/datum/config_entry/string/gamelogurl - -/datum/config_entry/number/githubrepoid - config_entry_value = null - min_val = 0 - -/datum/config_entry/flag/guest_ban - -/datum/config_entry/number/id_console_jobslot_delay - config_entry_value = 30 - min_val = 0 - -/datum/config_entry/number/inactivity_period //time in ds until a player is considered inactive - config_entry_value = 3000 - min_val = 0 - -/datum/config_entry/number/inactivity_period/ValidateAndSet(str_val) - . = ..() - if(.) - config_entry_value *= 10 //documented as seconds in config.txt - -/datum/config_entry/number/afk_period //time in ds until a player is considered inactive - config_entry_value = 3000 - min_val = 0 - -/datum/config_entry/number/afk_period/ValidateAndSet(str_val) - . = ..() - if(.) - config_entry_value *= 10 //documented as seconds in config.txt - -/datum/config_entry/flag/kick_inactive //force disconnect for inactive players - -/datum/config_entry/flag/load_jobs_from_txt - -/datum/config_entry/flag/forbid_singulo_possession - -/datum/config_entry/flag/automute_on //enables automuting/spam prevention - -/datum/config_entry/string/panic_server_name - -/datum/config_entry/string/panic_server_name/ValidateAndSet(str_val) - return str_val != "\[Put the name here\]" && ..() - -/datum/config_entry/string/panic_server_address //Reconnect a player this linked server if this server isn't accepting new players - -/datum/config_entry/string/panic_server_address/ValidateAndSet(str_val) - return str_val != "byond://address:port" && ..() - -/datum/config_entry/string/invoke_youtubedl - protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN - -/datum/config_entry/flag/show_irc_name - -/datum/config_entry/flag/see_own_notes //Can players see their own admin notes - -/datum/config_entry/number/note_fresh_days - config_entry_value = null - min_val = 0 - integer = FALSE - -/datum/config_entry/number/note_stale_days - config_entry_value = null - min_val = 0 - integer = FALSE - -/datum/config_entry/flag/maprotation - -/datum/config_entry/flag/tgstyle_maprotation - -/datum/config_entry/number/maprotatechancedelta - config_entry_value = 0.75 - min_val = 0 - max_val = 1 - integer = FALSE - -/datum/config_entry/number/soft_popcap - config_entry_value = null - min_val = 0 - -/datum/config_entry/number/hard_popcap - config_entry_value = null - min_val = 0 - -/datum/config_entry/number/extreme_popcap - config_entry_value = null - min_val = 0 - -/datum/config_entry/string/soft_popcap_message - config_entry_value = "Be warned that the server is currently serving a high number of users, consider using alternative game servers." - -/datum/config_entry/string/hard_popcap_message - config_entry_value = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers." - -/datum/config_entry/string/extreme_popcap_message - config_entry_value = "The server is currently serving a high number of users, find alternative servers." - -/datum/config_entry/flag/panic_bunker // prevents people the server hasn't seen before from connecting - -/datum/config_entry/number/notify_new_player_age // how long do we notify admins of a new player - min_val = -1 - -/datum/config_entry/number/notify_new_player_account_age // how long do we notify admins of a new byond account - min_val = 0 - -/datum/config_entry/flag/irc_first_connection_alert // do we notify the irc channel when somebody is connecting for the first time? - -/datum/config_entry/flag/check_randomizer - -/datum/config_entry/string/ipintel_email - -/datum/config_entry/string/ipintel_email/ValidateAndSet(str_val) - return str_val != "ch@nge.me" && ..() - -/datum/config_entry/number/ipintel_rating_bad - config_entry_value = 1 - integer = FALSE - min_val = 0 - max_val = 1 - -/datum/config_entry/number/ipintel_save_good - config_entry_value = 12 - min_val = 0 - -/datum/config_entry/number/ipintel_save_bad - config_entry_value = 1 - min_val = 0 - -/datum/config_entry/string/ipintel_domain - config_entry_value = "check.getipintel.net" - -/datum/config_entry/flag/aggressive_changelog - -/datum/config_entry/flag/autoconvert_notes //if all connecting player's notes should attempt to be converted to the database - protection = CONFIG_ENTRY_LOCKED - -/datum/config_entry/flag/allow_webclient - -/datum/config_entry/flag/webclient_only_byond_members - -/datum/config_entry/flag/announce_admin_logout - -/datum/config_entry/flag/announce_admin_login - -/datum/config_entry/flag/allow_map_voting - -/datum/config_entry/number/client_warn_version - config_entry_value = null - min_val = 500 - -/datum/config_entry/string/client_warn_message - config_entry_value = "Your version of byond may have issues or be blocked from accessing this server in the future." - -/datum/config_entry/flag/client_warn_popup - -/datum/config_entry/number/client_error_version - config_entry_value = null - min_val = 500 - -/datum/config_entry/string/client_error_message - config_entry_value = "Your version of byond is too old, may have issues, and is blocked from accessing this server." - -/datum/config_entry/number/minute_topic_limit - config_entry_value = null - min_val = 0 - -/datum/config_entry/number/second_topic_limit - config_entry_value = null - min_val = 0 - -/datum/config_entry/number/minute_click_limit - config_entry_value = 400 - min_val = 0 - -/datum/config_entry/number/second_click_limit - config_entry_value = 15 - min_val = 0 - -/datum/config_entry/number/error_cooldown // The "cooldown" time for each occurrence of a unique error - config_entry_value = 600 - min_val = 0 - -/datum/config_entry/number/error_limit // How many occurrences before the next will silence them - config_entry_value = 50 - -/datum/config_entry/number/error_silence_time // How long a unique error will be silenced for - config_entry_value = 6000 - -/datum/config_entry/number/error_msg_delay // How long to wait between messaging admins about occurrences of a unique error - config_entry_value = 50 - -/datum/config_entry/flag/irc_announce_new_game - -/datum/config_entry/flag/debug_admin_hrefs - -/datum/config_entry/number/mc_tick_rate/base_mc_tick_rate - integer = FALSE - config_entry_value = 1 - -/datum/config_entry/number/mc_tick_rate/high_pop_mc_tick_rate - integer = FALSE - config_entry_value = 1.1 - -/datum/config_entry/number/mc_tick_rate/high_pop_mc_mode_amount - config_entry_value = 65 - -/datum/config_entry/number/mc_tick_rate/disable_high_pop_mc_mode_amount - config_entry_value = 60 - -/datum/config_entry/number/mc_tick_rate - abstract_type = /datum/config_entry/number/mc_tick_rate - -/datum/config_entry/number/mc_tick_rate/ValidateAndSet(str_val) - . = ..() - if (.) - Master.UpdateTickRate() - -/datum/config_entry/flag/resume_after_initializations - -/datum/config_entry/flag/resume_after_initializations/ValidateAndSet(str_val) - . = ..() - if(. && Master.current_runlevel) - world.sleep_offline = !config_entry_value - -/datum/config_entry/number/rounds_until_hard_restart - config_entry_value = -1 - min_val = 0 - -/datum/config_entry/string/default_view - config_entry_value = "15x15" - -/datum/config_entry/flag/log_pictures - -/datum/config_entry/flag/picture_logging_camera +/datum/config_entry/flag/autoadmin // if autoadmin is enabled + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/autoadmin_rank // the rank for autoadmins + config_entry_value = "Game Master" + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/servername // server name (the name of the game window) + +/datum/config_entry/string/servertagline + config_entry_value = "We forgot to set the server's tagline in config.txt" + +/datum/config_entry/string/serversqlname // short form server name used for the DB + +/datum/config_entry/string/stationname // station name (the name of the station in-game) + +/datum/config_entry/number/lobby_countdown // In between round countdown. + config_entry_value = 120 + min_val = 0 + +/datum/config_entry/number/round_end_countdown // Post round murder death kill countdown + config_entry_value = 25 + min_val = 0 + +/datum/config_entry/flag/hub // if the game appears on the hub or not + +/datum/config_entry/flag/log_ooc // log OOC channel + +/datum/config_entry/flag/log_access // log login/logout + +/datum/config_entry/flag/log_say // log client say + +/datum/config_entry/flag/log_admin // log admin actions + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/log_prayer // log prayers + +/datum/config_entry/flag/log_law // log lawchanges + +/datum/config_entry/flag/log_game // log game events + +/datum/config_entry/flag/log_virus // log virology data + +/datum/config_entry/flag/log_vote // log voting + +/datum/config_entry/flag/log_whisper // log client whisper + +/datum/config_entry/flag/log_attack // log attack messages + +/datum/config_entry/flag/log_emote // log emotes + +/datum/config_entry/flag/log_adminchat // log admin chat messages + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/log_pda // log pda messages + +/datum/config_entry/flag/log_telecomms // log telecomms messages + +/datum/config_entry/flag/log_twitter // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases. + +/datum/config_entry/flag/log_world_topic // log all world.Topic() calls + +/datum/config_entry/flag/log_manifest // log crew manifest to seperate file + +/datum/config_entry/flag/log_job_debug // log roundstart divide occupations debug information to a file + +/datum/config_entry/flag/allow_admin_ooccolor // Allows admins with relevant permissions to have their own ooc colour + +/datum/config_entry/flag/allow_vote_restart // allow votes to restart + +/datum/config_entry/flag/allow_vote_mode // allow votes to change mode + +/datum/config_entry/number/vote_delay // minimum time between voting sessions (deciseconds, 10 minute default) + config_entry_value = 6000 + min_val = 0 + +/datum/config_entry/number/vote_period // length of voting period (deciseconds, default 1 minute) + config_entry_value = 600 + min_val = 0 + +/datum/config_entry/flag/default_no_vote // vote does not default to nochange/norestart + +/datum/config_entry/flag/no_dead_vote // dead people can't vote + +/datum/config_entry/flag/allow_metadata // Metadata is supported. + +/datum/config_entry/flag/popup_admin_pm // adminPMs to non-admins show in a pop-up 'reply' window when set + +/datum/config_entry/number/fps + config_entry_value = 20 + min_val = 1 + max_val = 100 //byond will start crapping out at 50, so this is just ridic + var/sync_validate = FALSE + +/datum/config_entry/number/fps/ValidateAndSet(str_val) + . = ..() + if(.) + sync_validate = TRUE + var/datum/config_entry/number/ticklag/TL = config.entries_by_type[/datum/config_entry/number/ticklag] + if(!TL.sync_validate) + TL.ValidateAndSet(10 / config_entry_value) + sync_validate = FALSE + +/datum/config_entry/number/ticklag + integer = FALSE + var/sync_validate = FALSE + +/datum/config_entry/number/ticklag/New() //ticklag weirdly just mirrors fps + var/datum/config_entry/CE = /datum/config_entry/number/fps + config_entry_value = 10 / initial(CE.config_entry_value) + ..() + +/datum/config_entry/number/ticklag/ValidateAndSet(str_val) + . = text2num(str_val) > 0 && ..() + if(.) + sync_validate = TRUE + var/datum/config_entry/number/fps/FPS = config.entries_by_type[/datum/config_entry/number/fps] + if(!FPS.sync_validate) + FPS.ValidateAndSet(10 / config_entry_value) + sync_validate = FALSE + +/datum/config_entry/flag/allow_holidays + +/datum/config_entry/number/tick_limit_mc_init //SSinitialization throttling + config_entry_value = TICK_LIMIT_MC_INIT_DEFAULT + min_val = 0 //oranges warned us + integer = FALSE + +/datum/config_entry/flag/admin_legacy_system //Defines whether the server uses the legacy admin system with admins.txt or the SQL system + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/protect_legacy_admins //Stops any admins loaded by the legacy system from having their rank edited by the permissions panel + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/protect_legacy_ranks //Stops any ranks loaded by the legacy system from having their flags edited by the permissions panel + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/enable_localhost_rank //Gives the !localhost! rank to any client connecting from 127.0.0.1 or ::1 + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/load_legacy_ranks_only //Loads admin ranks only from legacy admin_ranks.txt, while enabled ranks are mirrored to the database + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/mentors_mobname_only + +/datum/config_entry/flag/mentor_legacy_system //Defines whether the server uses the legacy mentor system with mentors.txt or the SQL system + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/string/hostedby + +/datum/config_entry/flag/norespawn + +/datum/config_entry/flag/guest_jobban + +/datum/config_entry/flag/usewhitelist + +/datum/config_entry/flag/ban_legacy_system //Defines whether the server uses the legacy banning system with the files in /data or the SQL system. + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/use_age_restriction_for_jobs //Do jobs use account age restrictions? --requires database + +/datum/config_entry/flag/use_account_age_for_jobs //Uses the time they made the account for the job restriction stuff. New player joining alerts should be unaffected. + +/datum/config_entry/flag/use_exp_tracking + +/datum/config_entry/flag/use_exp_restrictions_heads + +/datum/config_entry/number/use_exp_restrictions_heads_hours + config_entry_value = 0 + min_val = 0 + +/datum/config_entry/flag/use_exp_restrictions_heads_department + +/datum/config_entry/flag/use_exp_restrictions_other + +/datum/config_entry/flag/use_exp_restrictions_admin_bypass + +/datum/config_entry/string/server + +/datum/config_entry/string/banappeals + +/datum/config_entry/string/wikiurl + config_entry_value = "https://katlin.dog/citadel-wiki" + +/datum/config_entry/string/wikiurltg + config_entry_value = "http://www.tgstation13.org/wiki" + +/datum/config_entry/string/forumurl + config_entry_value = "http://tgstation13.org/phpBB/index.php" + +/datum/config_entry/string/rulesurl + config_entry_value = "http://www.tgstation13.org/wiki/Rules" + +/datum/config_entry/string/githuburl + config_entry_value = "https://www.github.com/tgstation/-tg-station" + +/datum/config_entry/string/roundstatsurl + +/datum/config_entry/string/gamelogurl + +/datum/config_entry/number/githubrepoid + config_entry_value = null + min_val = 0 + +/datum/config_entry/flag/guest_ban + +/datum/config_entry/number/id_console_jobslot_delay + config_entry_value = 30 + min_val = 0 + +/datum/config_entry/number/inactivity_period //time in ds until a player is considered inactive + config_entry_value = 3000 + min_val = 0 + +/datum/config_entry/number/inactivity_period/ValidateAndSet(str_val) + . = ..() + if(.) + config_entry_value *= 10 //documented as seconds in config.txt + +/datum/config_entry/number/afk_period //time in ds until a player is considered inactive + config_entry_value = 3000 + min_val = 0 + +/datum/config_entry/number/afk_period/ValidateAndSet(str_val) + . = ..() + if(.) + config_entry_value *= 10 //documented as seconds in config.txt + +/datum/config_entry/flag/kick_inactive //force disconnect for inactive players + +/datum/config_entry/flag/load_jobs_from_txt + +/datum/config_entry/flag/forbid_singulo_possession + +/datum/config_entry/flag/automute_on //enables automuting/spam prevention + +/datum/config_entry/string/panic_server_name + +/datum/config_entry/string/panic_server_name/ValidateAndSet(str_val) + return str_val != "\[Put the name here\]" && ..() + +/datum/config_entry/string/panic_server_address //Reconnect a player this linked server if this server isn't accepting new players + +/datum/config_entry/string/panic_server_address/ValidateAndSet(str_val) + return str_val != "byond://address:port" && ..() + +/datum/config_entry/string/invoke_youtubedl + protection = CONFIG_ENTRY_LOCKED | CONFIG_ENTRY_HIDDEN + +/datum/config_entry/flag/show_irc_name + +/datum/config_entry/flag/see_own_notes //Can players see their own admin notes + +/datum/config_entry/number/note_fresh_days + config_entry_value = null + min_val = 0 + integer = FALSE + +/datum/config_entry/number/note_stale_days + config_entry_value = null + min_val = 0 + integer = FALSE + +/datum/config_entry/flag/maprotation + +/datum/config_entry/flag/tgstyle_maprotation + +/datum/config_entry/number/maprotatechancedelta + config_entry_value = 0.75 + min_val = 0 + max_val = 1 + integer = FALSE + +/datum/config_entry/number/soft_popcap + config_entry_value = null + min_val = 0 + +/datum/config_entry/number/hard_popcap + config_entry_value = null + min_val = 0 + +/datum/config_entry/number/extreme_popcap + config_entry_value = null + min_val = 0 + +/datum/config_entry/string/soft_popcap_message + config_entry_value = "Be warned that the server is currently serving a high number of users, consider using alternative game servers." + +/datum/config_entry/string/hard_popcap_message + config_entry_value = "The server is currently serving a high number of users, You cannot currently join. You may wait for the number of living crew to decline, observe, or find alternative servers." + +/datum/config_entry/string/extreme_popcap_message + config_entry_value = "The server is currently serving a high number of users, find alternative servers." + +/datum/config_entry/flag/panic_bunker // prevents people the server hasn't seen before from connecting + +/datum/config_entry/number/notify_new_player_age // how long do we notify admins of a new player + min_val = -1 + +/datum/config_entry/number/notify_new_player_account_age // how long do we notify admins of a new byond account + min_val = 0 + +/datum/config_entry/flag/irc_first_connection_alert // do we notify the irc channel when somebody is connecting for the first time? + +/datum/config_entry/flag/check_randomizer + +/datum/config_entry/string/ipintel_email + +/datum/config_entry/string/ipintel_email/ValidateAndSet(str_val) + return str_val != "ch@nge.me" && ..() + +/datum/config_entry/number/ipintel_rating_bad + config_entry_value = 1 + integer = FALSE + min_val = 0 + max_val = 1 + +/datum/config_entry/number/ipintel_save_good + config_entry_value = 12 + min_val = 0 + +/datum/config_entry/number/ipintel_save_bad + config_entry_value = 1 + min_val = 0 + +/datum/config_entry/string/ipintel_domain + config_entry_value = "check.getipintel.net" + +/datum/config_entry/flag/aggressive_changelog + +/datum/config_entry/flag/autoconvert_notes //if all connecting player's notes should attempt to be converted to the database + protection = CONFIG_ENTRY_LOCKED + +/datum/config_entry/flag/allow_webclient + +/datum/config_entry/flag/webclient_only_byond_members + +/datum/config_entry/flag/announce_admin_logout + +/datum/config_entry/flag/announce_admin_login + +/datum/config_entry/flag/allow_map_voting + +/datum/config_entry/number/client_warn_version + config_entry_value = null + min_val = 500 + +/datum/config_entry/string/client_warn_message + config_entry_value = "Your version of byond may have issues or be blocked from accessing this server in the future." + +/datum/config_entry/flag/client_warn_popup + +/datum/config_entry/number/client_error_version + config_entry_value = null + min_val = 500 + +/datum/config_entry/string/client_error_message + config_entry_value = "Your version of byond is too old, may have issues, and is blocked from accessing this server." + +/datum/config_entry/number/minute_topic_limit + config_entry_value = null + min_val = 0 + +/datum/config_entry/number/second_topic_limit + config_entry_value = null + min_val = 0 + +/datum/config_entry/number/minute_click_limit + config_entry_value = 400 + min_val = 0 + +/datum/config_entry/number/second_click_limit + config_entry_value = 15 + min_val = 0 + +/datum/config_entry/number/error_cooldown // The "cooldown" time for each occurrence of a unique error + config_entry_value = 600 + min_val = 0 + +/datum/config_entry/number/error_limit // How many occurrences before the next will silence them + config_entry_value = 50 + +/datum/config_entry/number/error_silence_time // How long a unique error will be silenced for + config_entry_value = 6000 + +/datum/config_entry/number/error_msg_delay // How long to wait between messaging admins about occurrences of a unique error + config_entry_value = 50 + +/datum/config_entry/flag/irc_announce_new_game + +/datum/config_entry/flag/debug_admin_hrefs + +/datum/config_entry/number/mc_tick_rate/base_mc_tick_rate + integer = FALSE + config_entry_value = 1 + +/datum/config_entry/number/mc_tick_rate/high_pop_mc_tick_rate + integer = FALSE + config_entry_value = 1.1 + +/datum/config_entry/number/mc_tick_rate/high_pop_mc_mode_amount + config_entry_value = 65 + +/datum/config_entry/number/mc_tick_rate/disable_high_pop_mc_mode_amount + config_entry_value = 60 + +/datum/config_entry/number/mc_tick_rate + abstract_type = /datum/config_entry/number/mc_tick_rate + +/datum/config_entry/number/mc_tick_rate/ValidateAndSet(str_val) + . = ..() + if (.) + Master.UpdateTickRate() + +/datum/config_entry/flag/resume_after_initializations + +/datum/config_entry/flag/resume_after_initializations/ValidateAndSet(str_val) + . = ..() + if(. && Master.current_runlevel) + world.sleep_offline = !config_entry_value + +/datum/config_entry/number/rounds_until_hard_restart + config_entry_value = -1 + min_val = 0 + +/datum/config_entry/string/default_view + config_entry_value = "15x15" + +/datum/config_entry/flag/log_pictures + +/datum/config_entry/flag/picture_logging_camera diff --git a/code/controllers/failsafe.dm b/code/controllers/failsafe.dm index 2ca208642c..3ce770b66d 100644 --- a/code/controllers/failsafe.dm +++ b/code/controllers/failsafe.dm @@ -1,102 +1,102 @@ - /** - * Failsafe - * - * Pretty much pokes the MC to make sure it's still alive. - **/ - -GLOBAL_REAL(Failsafe, /datum/controller/failsafe) - -/datum/controller/failsafe // This thing pretty much just keeps poking the master controller - name = "Failsafe" - - // The length of time to check on the MC (in deciseconds). - // Set to 0 to disable. - var/processing_interval = 20 - // The alert level. For every failed poke, we drop a DEFCON level. Once we hit DEFCON 1, restart the MC. - var/defcon = 5 - //the world.time of the last check, so the mc can restart US if we hang. - // (Real friends look out for *eachother*) - var/lasttick = 0 - - // Track the MC iteration to make sure its still on track. - var/master_iteration = 0 - var/running = TRUE - -/datum/controller/failsafe/New() - // Highlander-style: there can only be one! Kill off the old and replace it with the new. - if(Failsafe != src) - if(istype(Failsafe)) - qdel(Failsafe) - Failsafe = src - Initialize() - -/datum/controller/failsafe/Initialize() - set waitfor = 0 - Failsafe.Loop() - if(!QDELETED(src)) - qdel(src) //when Loop() returns, we delete ourselves and let the mc recreate us - -/datum/controller/failsafe/Destroy() - running = FALSE - ..() - return QDEL_HINT_HARDDEL_NOW - -/datum/controller/failsafe/proc/Loop() - while(running) - lasttick = world.time - if(!Master) - // Replace the missing Master! This should never, ever happen. - new /datum/controller/master() - // Only poke it if overrides are not in effect. - if(processing_interval > 0) - if(Master.processing && Master.iteration) - // Check if processing is done yet. - if(Master.iteration == master_iteration) - switch(defcon) - if(4,5) - --defcon - if(3) - message_admins("Notice: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks.") - --defcon - if(2) - to_chat(GLOB.admins, "Warning: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.") - --defcon - if(1) - - to_chat(GLOB.admins, "Warning: DEFCON [defcon_pretty()]. The Master Controller has still not fired within the last [(5-defcon) * processing_interval] ticks. Killing and restarting...") - --defcon - var/rtn = Recreate_MC() - if(rtn > 0) - defcon = 4 - master_iteration = 0 - to_chat(GLOB.admins, "MC restarted successfully") - else if(rtn < 0) - log_game("FailSafe: Could not restart MC, runtime encountered. Entering defcon 0") - to_chat(GLOB.admins, "ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.") - //if the return number was 0, it just means the mc was restarted too recently, and it just needs some time before we try again - //no need to handle that specially when defcon 0 can handle it - if(0) //DEFCON 0! (mc failed to restart) - var/rtn = Recreate_MC() - if(rtn > 0) - defcon = 4 - master_iteration = 0 - to_chat(GLOB.admins, "MC restarted successfully") - else - defcon = min(defcon + 1,5) - master_iteration = Master.iteration - if (defcon <= 1) - sleep(processing_interval*2) - else - sleep(processing_interval) - else - defcon = 5 - sleep(initial(processing_interval)) - -/datum/controller/failsafe/proc/defcon_pretty() - return defcon - -/datum/controller/failsafe/stat_entry() - if(!statclick) - statclick = new/obj/effect/statclick/debug(null, "Initializing...", src) - - stat("Failsafe Controller:", statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])")) + /** + * Failsafe + * + * Pretty much pokes the MC to make sure it's still alive. + **/ + +GLOBAL_REAL(Failsafe, /datum/controller/failsafe) + +/datum/controller/failsafe // This thing pretty much just keeps poking the master controller + name = "Failsafe" + + // The length of time to check on the MC (in deciseconds). + // Set to 0 to disable. + var/processing_interval = 20 + // The alert level. For every failed poke, we drop a DEFCON level. Once we hit DEFCON 1, restart the MC. + var/defcon = 5 + //the world.time of the last check, so the mc can restart US if we hang. + // (Real friends look out for *eachother*) + var/lasttick = 0 + + // Track the MC iteration to make sure its still on track. + var/master_iteration = 0 + var/running = TRUE + +/datum/controller/failsafe/New() + // Highlander-style: there can only be one! Kill off the old and replace it with the new. + if(Failsafe != src) + if(istype(Failsafe)) + qdel(Failsafe) + Failsafe = src + Initialize() + +/datum/controller/failsafe/Initialize() + set waitfor = 0 + Failsafe.Loop() + if(!QDELETED(src)) + qdel(src) //when Loop() returns, we delete ourselves and let the mc recreate us + +/datum/controller/failsafe/Destroy() + running = FALSE + ..() + return QDEL_HINT_HARDDEL_NOW + +/datum/controller/failsafe/proc/Loop() + while(running) + lasttick = world.time + if(!Master) + // Replace the missing Master! This should never, ever happen. + new /datum/controller/master() + // Only poke it if overrides are not in effect. + if(processing_interval > 0) + if(Master.processing && Master.iteration) + // Check if processing is done yet. + if(Master.iteration == master_iteration) + switch(defcon) + if(4,5) + --defcon + if(3) + message_admins("Notice: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks.") + --defcon + if(2) + to_chat(GLOB.admins, "Warning: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.") + --defcon + if(1) + + to_chat(GLOB.admins, "Warning: DEFCON [defcon_pretty()]. The Master Controller has still not fired within the last [(5-defcon) * processing_interval] ticks. Killing and restarting...") + --defcon + var/rtn = Recreate_MC() + if(rtn > 0) + defcon = 4 + master_iteration = 0 + to_chat(GLOB.admins, "MC restarted successfully") + else if(rtn < 0) + log_game("FailSafe: Could not restart MC, runtime encountered. Entering defcon 0") + to_chat(GLOB.admins, "ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.") + //if the return number was 0, it just means the mc was restarted too recently, and it just needs some time before we try again + //no need to handle that specially when defcon 0 can handle it + if(0) //DEFCON 0! (mc failed to restart) + var/rtn = Recreate_MC() + if(rtn > 0) + defcon = 4 + master_iteration = 0 + to_chat(GLOB.admins, "MC restarted successfully") + else + defcon = min(defcon + 1,5) + master_iteration = Master.iteration + if (defcon <= 1) + sleep(processing_interval*2) + else + sleep(processing_interval) + else + defcon = 5 + sleep(initial(processing_interval)) + +/datum/controller/failsafe/proc/defcon_pretty() + return defcon + +/datum/controller/failsafe/stat_entry() + if(!statclick) + statclick = new/obj/effect/statclick/debug(null, "Initializing...", src) + + stat("Failsafe Controller:", statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])")) diff --git a/code/controllers/globals.dm b/code/controllers/globals.dm index 4683e93a46..a085b26410 100644 --- a/code/controllers/globals.dm +++ b/code/controllers/globals.dm @@ -1,55 +1,55 @@ -GLOBAL_REAL(GLOB, /datum/controller/global_vars) - -/datum/controller/global_vars - name = "Global Variables" - - var/static/list/gvars_datum_protected_varlist - var/list/gvars_datum_in_built_vars - var/list/gvars_datum_init_order - -/datum/controller/global_vars/New() - if(GLOB) - CRASH("Multiple instances of global variable controller created") - GLOB = src - - var/datum/controller/exclude_these = new - gvars_datum_in_built_vars = exclude_these.vars + list(NAMEOF(src, gvars_datum_protected_varlist), NAMEOF(src, gvars_datum_in_built_vars), NAMEOF(src, gvars_datum_init_order)) - QDEL_IN(exclude_these, 0) //signal logging isn't ready - - log_world("[vars.len - gvars_datum_in_built_vars.len] global variables") - - Initialize() - -/datum/controller/global_vars/Destroy() - //fuck off kevinz - return QDEL_HINT_IWILLGC - -/datum/controller/global_vars/stat_entry() - if(!statclick) - statclick = new/obj/effect/statclick/debug(null, "Initializing...", src) - - stat("Globals:", statclick.update("Edit")) - -/datum/controller/global_vars/vv_edit_var(var_name, var_value) - if(gvars_datum_protected_varlist[var_name]) - return FALSE - return ..() - -/datum/controller/global_vars/Initialize() - gvars_datum_init_order = list() - gvars_datum_protected_varlist = list(NAMEOF(src, gvars_datum_protected_varlist) = TRUE) - var/list/global_procs = typesof(/datum/controller/global_vars/proc) - var/expected_len = vars.len - gvars_datum_in_built_vars.len - if(global_procs.len != expected_len) - warning("Unable to detect all global initialization procs! Expected [expected_len] got [global_procs.len]!") - if(global_procs.len) - var/list/expected_global_procs = vars - gvars_datum_in_built_vars - for(var/I in global_procs) - expected_global_procs -= replacetext("[I]", "InitGlobal", "") - log_world("Missing procs: [expected_global_procs.Join(", ")]") - for(var/I in global_procs) - var/start_tick = world.time - call(src, I)() - var/end_tick = world.time - if(end_tick - start_tick) - warning("Global [replacetext("[I]", "InitGlobal", "")] slept during initialization!") +GLOBAL_REAL(GLOB, /datum/controller/global_vars) + +/datum/controller/global_vars + name = "Global Variables" + + var/static/list/gvars_datum_protected_varlist + var/list/gvars_datum_in_built_vars + var/list/gvars_datum_init_order + +/datum/controller/global_vars/New() + if(GLOB) + CRASH("Multiple instances of global variable controller created") + GLOB = src + + var/datum/controller/exclude_these = new + gvars_datum_in_built_vars = exclude_these.vars + list(NAMEOF(src, gvars_datum_protected_varlist), NAMEOF(src, gvars_datum_in_built_vars), NAMEOF(src, gvars_datum_init_order)) + QDEL_IN(exclude_these, 0) //signal logging isn't ready + + log_world("[vars.len - gvars_datum_in_built_vars.len] global variables") + + Initialize() + +/datum/controller/global_vars/Destroy() + //fuck off kevinz + return QDEL_HINT_IWILLGC + +/datum/controller/global_vars/stat_entry() + if(!statclick) + statclick = new/obj/effect/statclick/debug(null, "Initializing...", src) + + stat("Globals:", statclick.update("Edit")) + +/datum/controller/global_vars/vv_edit_var(var_name, var_value) + if(gvars_datum_protected_varlist[var_name]) + return FALSE + return ..() + +/datum/controller/global_vars/Initialize() + gvars_datum_init_order = list() + gvars_datum_protected_varlist = list(NAMEOF(src, gvars_datum_protected_varlist) = TRUE) + var/list/global_procs = typesof(/datum/controller/global_vars/proc) + var/expected_len = vars.len - gvars_datum_in_built_vars.len + if(global_procs.len != expected_len) + warning("Unable to detect all global initialization procs! Expected [expected_len] got [global_procs.len]!") + if(global_procs.len) + var/list/expected_global_procs = vars - gvars_datum_in_built_vars + for(var/I in global_procs) + expected_global_procs -= replacetext("[I]", "InitGlobal", "") + log_world("Missing procs: [expected_global_procs.Join(", ")]") + for(var/I in global_procs) + var/start_tick = world.time + call(src, I)() + var/end_tick = world.time + if(end_tick - start_tick) + warning("Global [replacetext("[I]", "InitGlobal", "")] slept during initialization!") diff --git a/code/controllers/subsystem/atoms.dm b/code/controllers/subsystem/atoms.dm index ebd8d3801f..d94526e658 100644 --- a/code/controllers/subsystem/atoms.dm +++ b/code/controllers/subsystem/atoms.dm @@ -1,151 +1,151 @@ -#define BAD_INIT_QDEL_BEFORE 1 -#define BAD_INIT_DIDNT_INIT 2 -#define BAD_INIT_SLEPT 4 -#define BAD_INIT_NO_HINT 8 - -SUBSYSTEM_DEF(atoms) - name = "Atoms" - init_order = INIT_ORDER_ATOMS - flags = SS_NO_FIRE - - var/old_initialized - - var/list/late_loaders - - var/list/BadInitializeCalls = list() - -/datum/controller/subsystem/atoms/Initialize(timeofday) - GLOB.fire_overlay.appearance_flags = RESET_COLOR - setupGenetics() //to set the mutations' place in structural enzymes, so monkey.initialize() knows where to put the monkey mutation. - initialized = INITIALIZATION_INNEW_MAPLOAD - InitializeAtoms() - return ..() - -/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms) - if(initialized == INITIALIZATION_INSSATOMS) - return - - initialized = INITIALIZATION_INNEW_MAPLOAD - - LAZYINITLIST(late_loaders) - - var/count - var/list/mapload_arg = list(TRUE) - if(atoms) - count = atoms.len - for(var/I in atoms) - var/atom/A = I - if(!(A.flags_1 & INITIALIZED_1)) - InitAtom(I, mapload_arg) - CHECK_TICK - else - count = 0 - for(var/atom/A in world) - if(!(A.flags_1 & INITIALIZED_1)) - InitAtom(A, mapload_arg) - ++count - CHECK_TICK - - testing("Initialized [count] atoms") - pass(count) - - initialized = INITIALIZATION_INNEW_REGULAR - - if(late_loaders.len) - for(var/I in late_loaders) - var/atom/A = I - A.LateInitialize() - testing("Late initialized [late_loaders.len] atoms") - late_loaders.Cut() - -/datum/controller/subsystem/atoms/proc/InitAtom(atom/A, list/arguments) - var/the_type = A.type - if(QDELING(A)) - BadInitializeCalls[the_type] |= BAD_INIT_QDEL_BEFORE - return TRUE - - var/start_tick = world.time - - var/result = A.Initialize(arglist(arguments)) - - if(start_tick != world.time) - BadInitializeCalls[the_type] |= BAD_INIT_SLEPT - - var/qdeleted = FALSE - - if(result != INITIALIZE_HINT_NORMAL) - switch(result) - if(INITIALIZE_HINT_LATELOAD) - if(arguments[1]) //mapload - late_loaders += A - else - A.LateInitialize() - if(INITIALIZE_HINT_QDEL) - qdel(A) - qdeleted = TRUE - else - BadInitializeCalls[the_type] |= BAD_INIT_NO_HINT - - if(!A) //possible harddel - qdeleted = TRUE - else if(!(A.flags_1 & INITIALIZED_1)) - BadInitializeCalls[the_type] |= BAD_INIT_DIDNT_INIT - - return qdeleted || QDELING(A) - -/datum/controller/subsystem/atoms/proc/map_loader_begin() - old_initialized = initialized - initialized = INITIALIZATION_INSSATOMS - -/datum/controller/subsystem/atoms/proc/map_loader_stop() - initialized = old_initialized - -/datum/controller/subsystem/atoms/Recover() - initialized = SSatoms.initialized - if(initialized == INITIALIZATION_INNEW_MAPLOAD) - InitializeAtoms() - old_initialized = SSatoms.old_initialized - BadInitializeCalls = SSatoms.BadInitializeCalls - -/datum/controller/subsystem/atoms/proc/setupGenetics() - var/list/avnums = new /list(DNA_STRUC_ENZYMES_BLOCKS) - for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++) - avnums[i] = i - CHECK_TICK - - for(var/A in subtypesof(/datum/mutation/human)) - var/datum/mutation/human/B = new A() - if(B.dna_block == NON_SCANNABLE) - continue - B.dna_block = pick_n_take(avnums) - if(B.quality == POSITIVE) - GLOB.good_mutations |= B - else if(B.quality == NEGATIVE) - GLOB.bad_mutations |= B - else if(B.quality == MINOR_NEGATIVE) - GLOB.not_good_mutations |= B - CHECK_TICK - -/datum/controller/subsystem/atoms/proc/InitLog() - . = "" - for(var/path in BadInitializeCalls) - . += "Path : [path] \n" - var/fails = BadInitializeCalls[path] - if(fails & BAD_INIT_DIDNT_INIT) - . += "- Didn't call atom/Initialize()\n" - if(fails & BAD_INIT_NO_HINT) - . += "- Didn't return an Initialize hint\n" - if(fails & BAD_INIT_QDEL_BEFORE) - . += "- Qdel'd in New()\n" - if(fails & BAD_INIT_SLEPT) - . += "- Slept during Initialize()\n" - -/datum/controller/subsystem/atoms/Shutdown() - var/initlog = InitLog() - if(initlog) - text2file(initlog, "[GLOB.log_directory]/initialize.log") - -#undef BAD_INIT_QDEL_BEFORE -#undef BAD_INIT_DIDNT_INIT -#undef BAD_INIT_SLEPT -#undef BAD_INIT_NO_HINT +#define BAD_INIT_QDEL_BEFORE 1 +#define BAD_INIT_DIDNT_INIT 2 +#define BAD_INIT_SLEPT 4 +#define BAD_INIT_NO_HINT 8 + +SUBSYSTEM_DEF(atoms) + name = "Atoms" + init_order = INIT_ORDER_ATOMS + flags = SS_NO_FIRE + + var/old_initialized + + var/list/late_loaders + + var/list/BadInitializeCalls = list() + +/datum/controller/subsystem/atoms/Initialize(timeofday) + GLOB.fire_overlay.appearance_flags = RESET_COLOR + setupGenetics() //to set the mutations' place in structural enzymes, so monkey.initialize() knows where to put the monkey mutation. + initialized = INITIALIZATION_INNEW_MAPLOAD + InitializeAtoms() + return ..() + +/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms) + if(initialized == INITIALIZATION_INSSATOMS) + return + + initialized = INITIALIZATION_INNEW_MAPLOAD + + LAZYINITLIST(late_loaders) + + var/count + var/list/mapload_arg = list(TRUE) + if(atoms) + count = atoms.len + for(var/I in atoms) + var/atom/A = I + if(!(A.flags_1 & INITIALIZED_1)) + InitAtom(I, mapload_arg) + CHECK_TICK + else + count = 0 + for(var/atom/A in world) + if(!(A.flags_1 & INITIALIZED_1)) + InitAtom(A, mapload_arg) + ++count + CHECK_TICK + + testing("Initialized [count] atoms") + pass(count) + + initialized = INITIALIZATION_INNEW_REGULAR + + if(late_loaders.len) + for(var/I in late_loaders) + var/atom/A = I + A.LateInitialize() + testing("Late initialized [late_loaders.len] atoms") + late_loaders.Cut() + +/datum/controller/subsystem/atoms/proc/InitAtom(atom/A, list/arguments) + var/the_type = A.type + if(QDELING(A)) + BadInitializeCalls[the_type] |= BAD_INIT_QDEL_BEFORE + return TRUE + + var/start_tick = world.time + + var/result = A.Initialize(arglist(arguments)) + + if(start_tick != world.time) + BadInitializeCalls[the_type] |= BAD_INIT_SLEPT + + var/qdeleted = FALSE + + if(result != INITIALIZE_HINT_NORMAL) + switch(result) + if(INITIALIZE_HINT_LATELOAD) + if(arguments[1]) //mapload + late_loaders += A + else + A.LateInitialize() + if(INITIALIZE_HINT_QDEL) + qdel(A) + qdeleted = TRUE + else + BadInitializeCalls[the_type] |= BAD_INIT_NO_HINT + + if(!A) //possible harddel + qdeleted = TRUE + else if(!(A.flags_1 & INITIALIZED_1)) + BadInitializeCalls[the_type] |= BAD_INIT_DIDNT_INIT + + return qdeleted || QDELING(A) + +/datum/controller/subsystem/atoms/proc/map_loader_begin() + old_initialized = initialized + initialized = INITIALIZATION_INSSATOMS + +/datum/controller/subsystem/atoms/proc/map_loader_stop() + initialized = old_initialized + +/datum/controller/subsystem/atoms/Recover() + initialized = SSatoms.initialized + if(initialized == INITIALIZATION_INNEW_MAPLOAD) + InitializeAtoms() + old_initialized = SSatoms.old_initialized + BadInitializeCalls = SSatoms.BadInitializeCalls + +/datum/controller/subsystem/atoms/proc/setupGenetics() + var/list/avnums = new /list(DNA_STRUC_ENZYMES_BLOCKS) + for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++) + avnums[i] = i + CHECK_TICK + + for(var/A in subtypesof(/datum/mutation/human)) + var/datum/mutation/human/B = new A() + if(B.dna_block == NON_SCANNABLE) + continue + B.dna_block = pick_n_take(avnums) + if(B.quality == POSITIVE) + GLOB.good_mutations |= B + else if(B.quality == NEGATIVE) + GLOB.bad_mutations |= B + else if(B.quality == MINOR_NEGATIVE) + GLOB.not_good_mutations |= B + CHECK_TICK + +/datum/controller/subsystem/atoms/proc/InitLog() + . = "" + for(var/path in BadInitializeCalls) + . += "Path : [path] \n" + var/fails = BadInitializeCalls[path] + if(fails & BAD_INIT_DIDNT_INIT) + . += "- Didn't call atom/Initialize()\n" + if(fails & BAD_INIT_NO_HINT) + . += "- Didn't return an Initialize hint\n" + if(fails & BAD_INIT_QDEL_BEFORE) + . += "- Qdel'd in New()\n" + if(fails & BAD_INIT_SLEPT) + . += "- Slept during Initialize()\n" + +/datum/controller/subsystem/atoms/Shutdown() + var/initlog = InitLog() + if(initlog) + text2file(initlog, "[GLOB.log_directory]/initialize.log") + +#undef BAD_INIT_QDEL_BEFORE +#undef BAD_INIT_DIDNT_INIT +#undef BAD_INIT_SLEPT +#undef BAD_INIT_NO_HINT diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm index 58476d472f..d6991a40b4 100644 --- a/code/controllers/subsystem/blackbox.dm +++ b/code/controllers/subsystem/blackbox.dm @@ -1,335 +1,335 @@ -SUBSYSTEM_DEF(blackbox) - name = "Blackbox" - wait = 6000 - flags = SS_NO_TICK_CHECK - runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME - init_order = INIT_ORDER_BLACKBOX - - var/list/feedback = list() //list of datum/feedback_variable - var/list/first_death = list() //the first death of this round, assoc. vars keep track of different things - var/triggertime = 0 - var/sealed = FALSE //time to stop tracking stats? - var/list/versions = list("antagonists" = 3, - "admin_secrets_fun_used" = 2, - "explosion" = 2, - "time_dilation_current" = 3, - "science_techweb_unlock" = 2, - "round_end_stats" = 2) //associative list of any feedback variables that have had their format changed since creation and their current version, remember to update this - -/datum/controller/subsystem/blackbox/Initialize() - triggertime = world.time - record_feedback("amount", "random_seed", Master.random_seed) - record_feedback("amount", "dm_version", DM_VERSION) - record_feedback("amount", "byond_version", world.byond_version) - record_feedback("amount", "byond_build", world.byond_build) - . = ..() - -//poll population -/datum/controller/subsystem/blackbox/fire() - set waitfor = FALSE //for population query - - CheckPlayerCount() - - if(CONFIG_GET(flag/use_exp_tracking)) - if((triggertime < 0) || (world.time > (triggertime +3000))) //subsystem fires once at roundstart then once every 10 minutes. a 5 min check skips the first fire. The <0 is midnight rollover check - update_exp(10,FALSE) - -/datum/controller/subsystem/blackbox/proc/CheckPlayerCount() - set waitfor = FALSE - - if(!SSdbcore.Connect()) - return - var/playercount = 0 - for(var/mob/M in GLOB.player_list) - if(M.client) - playercount += 1 - var/admincount = GLOB.admins.len - var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port, round_id) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]')") - query_record_playercount.Execute() - qdel(query_record_playercount) - -/datum/controller/subsystem/blackbox/Recover() - feedback = SSblackbox.feedback - sealed = SSblackbox.sealed - -//no touchie -/datum/controller/subsystem/blackbox/vv_get_var(var_name) - if(var_name == "feedback") - return debug_variable(var_name, deepCopyList(feedback), 0, src) - return ..() - -/datum/controller/subsystem/blackbox/vv_edit_var(var_name, var_value) - switch(var_name) - if("feedback") - return FALSE - if("sealed") - if(var_value) - return Seal() - return FALSE - return ..() - -//Recorded on subsystem shutdown -/datum/controller/subsystem/blackbox/proc/FinalFeedback() - record_feedback("tally", "ahelp_stats", GLOB.ahelp_tickets.active_tickets.len, "unresolved") - for (var/obj/machinery/telecomms/message_server/MS in GLOB.telecomms_list) - if (MS.pda_msgs.len) - record_feedback("tally", "radio_usage", MS.pda_msgs.len, "PDA") - if (MS.rc_msgs.len) - record_feedback("tally", "radio_usage", MS.rc_msgs.len, "request console") - - for(var/player_key in GLOB.player_details) - var/datum/player_details/PD = GLOB.player_details[player_key] - record_feedback("tally", "client_byond_version", 1, PD.byond_version) - -/datum/controller/subsystem/blackbox/Shutdown() - sealed = FALSE - FinalFeedback() - - if (!SSdbcore.Connect()) - return - - var/list/sqlrowlist = list() - - for (var/datum/feedback_variable/FV in feedback) - var/sqlversion = 1 - if(FV.key in versions) - sqlversion = versions[FV.key] - sqlrowlist += list(list("datetime" = "Now()", "round_id" = GLOB.round_id, "key_name" = "'[sanitizeSQL(FV.key)]'", "key_type" = "'[FV.key_type]'", "version" = "[sqlversion]", "json" = "'[sanitizeSQL(json_encode(FV.json))]'")) - - if (!length(sqlrowlist)) - return - - SSdbcore.MassInsert(format_table_name("feedback"), sqlrowlist, ignore_errors = TRUE, delayed = TRUE) - -/datum/controller/subsystem/blackbox/proc/Seal() - if(sealed) - return FALSE - if(IsAdminAdvancedProcCall()) - message_admins("[key_name_admin(usr)] sealed the blackbox!") - log_game("Blackbox sealed[IsAdminAdvancedProcCall() ? " by [key_name(usr)]" : ""].") - sealed = TRUE - return TRUE - -/datum/controller/subsystem/blackbox/proc/LogBroadcast(freq) - if(sealed) - return - switch(freq) - if(FREQ_COMMON) - record_feedback("tally", "radio_usage", 1, "common") - if(FREQ_SCIENCE) - record_feedback("tally", "radio_usage", 1, "science") - if(FREQ_COMMAND) - record_feedback("tally", "radio_usage", 1, "command") - if(FREQ_MEDICAL) - record_feedback("tally", "radio_usage", 1, "medical") - if(FREQ_ENGINEERING) - record_feedback("tally", "radio_usage", 1, "engineering") - if(FREQ_SECURITY) - record_feedback("tally", "radio_usage", 1, "security") - if(FREQ_SYNDICATE) - record_feedback("tally", "radio_usage", 1, "syndicate") - if(FREQ_SERVICE) - record_feedback("tally", "radio_usage", 1, "service") - if(FREQ_SUPPLY) - record_feedback("tally", "radio_usage", 1, "supply") - if(FREQ_CENTCOM) - record_feedback("tally", "radio_usage", 1, "centcom") - if(FREQ_AI_PRIVATE) - record_feedback("tally", "radio_usage", 1, "ai private") - if(FREQ_CTF_RED) - record_feedback("tally", "radio_usage", 1, "CTF red team") - if(FREQ_CTF_BLUE) - record_feedback("tally", "radio_usage", 1, "CTF blue team") - else - record_feedback("tally", "radio_usage", 1, "other") - -/datum/controller/subsystem/blackbox/proc/find_feedback_datum(key, key_type) - for(var/datum/feedback_variable/FV in feedback) - if(FV.key == key) - return FV - - var/datum/feedback_variable/FV = new(key, key_type) - feedback += FV - return FV -/* -feedback data can be recorded in 5 formats: -"text" - used for simple single-string records i.e. the current map - further calls to the same key will append saved data unless the overwrite argument is true or it already exists - when encoded calls made with overwrite will lack square brackets - calls: SSblackbox.record_feedback("text", "example", 1, "sample text") - SSblackbox.record_feedback("text", "example", 1, "other text") - json: {"data":["sample text","other text"]} -"amount" - used to record simple counts of data i.e. the number of ahelps received - further calls to the same key will add or subtract (if increment argument is a negative) from the saved amount - calls: SSblackbox.record_feedback("amount", "example", 8) - SSblackbox.record_feedback("amount", "example", 2) - json: {"data":10} -"tally" - used to track the number of occurances of multiple related values i.e. how many times each type of gun is fired - further calls to the same key will: - add or subtract from the saved value of the data key if it already exists - append the key and it's value if it doesn't exist - calls: SSblackbox.record_feedback("tally", "example", 1, "sample data") - SSblackbox.record_feedback("tally", "example", 4, "sample data") - SSblackbox.record_feedback("tally", "example", 2, "other data") - json: {"data":{"sample data":5,"other data":2}} -"nested tally" - used to track the number of occurances of structured semi-relational values i.e. the results of arcade machines - similar to running total, but related values are nested in a multi-dimensional array built - the final element in the data list is used as the tracking key, all prior elements are used for nesting - all data list elements must be strings - further calls to the same key will: - add or subtract from the saved value of the data key if it already exists in the same multi-dimensional position - append the key and it's value if it doesn't exist - calls: SSblackbox.record_feedback("nested tally", "example", 1, list("fruit", "orange", "apricot")) - SSblackbox.record_feedback("nested tally", "example", 2, list("fruit", "orange", "orange")) - SSblackbox.record_feedback("nested tally", "example", 3, list("fruit", "orange", "apricot")) - SSblackbox.record_feedback("nested tally", "example", 10, list("fruit", "red", "apple")) - SSblackbox.record_feedback("nested tally", "example", 1, list("vegetable", "orange", "carrot")) - json: {"data":{"fruit":{"orange":{"apricot":4,"orange":2},"red":{"apple":10}},"vegetable":{"orange":{"carrot":1}}}} - tracking values associated with a number can't merge with a nesting value, trying to do so will append the list - call: SSblackbox.record_feedback("nested tally", "example", 3, list("fruit", "orange")) - json: {"data":{"fruit":{"orange":{"apricot":4,"orange":2},"red":{"apple":10},"orange":3},"vegetable":{"orange":{"carrot":1}}}} -"associative" - used to record text that's associated with a value i.e. coordinates - further calls to the same key will append a new list to existing data - calls: SSblackbox.record_feedback("associative", "example", 1, list("text" = "example", "path" = /obj/item, "number" = 4)) - SSblackbox.record_feedback("associative", "example", 1, list("number" = 7, "text" = "example", "other text" = "sample")) - json: {"data":{"1":{"text":"example","path":"/obj/item","number":"4"},"2":{"number":"7","text":"example","other text":"sample"}}} - -Versioning - If the format of a feedback variable is ever changed, i.e. how many levels of nesting are used or a new type of data is added to it, add it to the versions list - When feedback is being saved if a key is in the versions list the value specified there will be used, otherwise all keys are assumed to be version = 1 - versions is an associative list, remember to use the same string in it as defined on a feedback variable, example: - list/versions = list("round_end_stats" = 4, - "admin_toggle" = 2, - "gun_fired" = 2) -*/ -/datum/controller/subsystem/blackbox/proc/record_feedback(key_type, key, increment, data, overwrite) - if(sealed || !key_type || !istext(key) || !isnum(increment || !data)) - return - var/datum/feedback_variable/FV = find_feedback_datum(key, key_type) - switch(key_type) - if("text") - if(!istext(data)) - return - if(!islist(FV.json["data"])) - FV.json["data"] = list() - if(overwrite) - FV.json["data"] = data - else - FV.json["data"] |= data - if("amount") - FV.json["data"] += increment - if("tally") - if(!islist(FV.json["data"])) - FV.json["data"] = list() - FV.json["data"]["[data]"] += increment - if("nested tally") - if(!islist(data)) - return - if(!islist(FV.json["data"])) - FV.json["data"] = list() - FV.json["data"] = record_feedback_recurse_list(FV.json["data"], data, increment) - if("associative") - if(!islist(data)) - return - if(!islist(FV.json["data"])) - FV.json["data"] = list() - var/pos = length(FV.json["data"]) + 1 - FV.json["data"]["[pos]"] = list() //in 512 "pos" can be replaced with "[FV.json["data"].len+1]" - for(var/i in data) - if(islist(data[i])) - FV.json["data"]["[pos]"]["[i]"] = data[i] //and here with "[FV.json["data"].len]" - else - FV.json["data"]["[pos]"]["[i]"] = "[data[i]]" - else - CRASH("Invalid feedback key_type: [key_type]") - -/datum/controller/subsystem/blackbox/proc/record_feedback_recurse_list(list/L, list/key_list, increment, depth = 1) - if(depth == key_list.len) - if(L.Find(key_list[depth])) - L["[key_list[depth]]"] += increment - else - var/list/LFI = list(key_list[depth] = increment) - L += LFI - else - if(!L.Find(key_list[depth])) - var/list/LGD = list(key_list[depth] = list()) - L += LGD - L["[key_list[depth-1]]"] = .(L["[key_list[depth]]"], key_list, increment, ++depth) - return L - -/datum/feedback_variable - var/key - var/key_type - var/list/json = list() - -/datum/feedback_variable/New(new_key, new_key_type) - key = new_key - key_type = new_key_type - -/datum/controller/subsystem/blackbox/proc/ReportDeath(mob/living/L) - set waitfor = FALSE - if(sealed) - return - if(!L || !L.key || !L.mind) - return - if(!L.suiciding && !first_death.len) - first_death["name"] = "[(L.real_name == L.name) ? L.real_name : "[L.real_name] as [L.name]"]" - first_death["role"] = null - if(L.mind.assigned_role) - first_death["role"] = L.mind.assigned_role - first_death["area"] = "[AREACOORD(L)]" - first_death["damage"] = "[L.getBruteLoss()]/[L.getFireLoss()]/[L.getToxLoss()]/[L.getOxyLoss()]/[L.getCloneLoss()]" - first_death["last_words"] = L.last_words - var/sqlname = L.real_name - var/sqlkey = L.ckey - var/sqljob = L.mind.assigned_role - var/sqlspecial = L.mind.special_role - var/sqlpod = get_area_name(L, TRUE) - var/laname = L.lastattacker - var/lakey = L.lastattackerckey - var/sqlbrute = L.getBruteLoss() - var/sqlfire = L.getFireLoss() - var/sqlbrain = L.getOrganLoss(ORGAN_SLOT_BRAIN) - var/sqloxy = L.getOxyLoss() - var/sqltox = L.getToxLoss() - var/sqlclone = L.getCloneLoss() - var/sqlstamina = L.getStaminaLoss() - var/x_coord = L.x - var/y_coord = L.y - var/z_coord = L.z - var/last_words = L.last_words - var/suicide = L.suiciding - var/map = SSmapping.config.map_name - - if(!SSdbcore.Connect()) - return - - sqlname = sanitizeSQL(sqlname) - sqlkey = sanitizeSQL(sqlkey) - sqljob = sanitizeSQL(sqljob) - sqlspecial = sanitizeSQL(sqlspecial) - sqlpod = sanitizeSQL(sqlpod) - laname = sanitizeSQL(laname) - lakey = sanitizeSQL(lakey) - sqlbrute = sanitizeSQL(sqlbrute) - sqlfire = sanitizeSQL(sqlfire) - sqlbrain = sanitizeSQL(sqlbrain) - sqloxy = sanitizeSQL(sqloxy) - sqltox = sanitizeSQL(sqltox) - sqlclone = sanitizeSQL(sqlclone) - sqlstamina = sanitizeSQL(sqlstamina) - x_coord = sanitizeSQL(x_coord) - y_coord = sanitizeSQL(y_coord) - z_coord = sanitizeSQL(z_coord) - last_words = sanitizeSQL(last_words) - suicide = sanitizeSQL(suicide) - map = sanitizeSQL(map) - 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, suicide) 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])") - if(query_report_death) - query_report_death.Execute(async = TRUE) - qdel(query_report_death) +SUBSYSTEM_DEF(blackbox) + name = "Blackbox" + wait = 6000 + flags = SS_NO_TICK_CHECK + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME + init_order = INIT_ORDER_BLACKBOX + + var/list/feedback = list() //list of datum/feedback_variable + var/list/first_death = list() //the first death of this round, assoc. vars keep track of different things + var/triggertime = 0 + var/sealed = FALSE //time to stop tracking stats? + var/list/versions = list("antagonists" = 3, + "admin_secrets_fun_used" = 2, + "explosion" = 2, + "time_dilation_current" = 3, + "science_techweb_unlock" = 2, + "round_end_stats" = 2) //associative list of any feedback variables that have had their format changed since creation and their current version, remember to update this + +/datum/controller/subsystem/blackbox/Initialize() + triggertime = world.time + record_feedback("amount", "random_seed", Master.random_seed) + record_feedback("amount", "dm_version", DM_VERSION) + record_feedback("amount", "byond_version", world.byond_version) + record_feedback("amount", "byond_build", world.byond_build) + . = ..() + +//poll population +/datum/controller/subsystem/blackbox/fire() + set waitfor = FALSE //for population query + + CheckPlayerCount() + + if(CONFIG_GET(flag/use_exp_tracking)) + if((triggertime < 0) || (world.time > (triggertime +3000))) //subsystem fires once at roundstart then once every 10 minutes. a 5 min check skips the first fire. The <0 is midnight rollover check + update_exp(10,FALSE) + +/datum/controller/subsystem/blackbox/proc/CheckPlayerCount() + set waitfor = FALSE + + if(!SSdbcore.Connect()) + return + var/playercount = 0 + for(var/mob/M in GLOB.player_list) + if(M.client) + playercount += 1 + var/admincount = GLOB.admins.len + var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port, round_id) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]', '[GLOB.round_id]')") + query_record_playercount.Execute() + qdel(query_record_playercount) + +/datum/controller/subsystem/blackbox/Recover() + feedback = SSblackbox.feedback + sealed = SSblackbox.sealed + +//no touchie +/datum/controller/subsystem/blackbox/vv_get_var(var_name) + if(var_name == "feedback") + return debug_variable(var_name, deepCopyList(feedback), 0, src) + return ..() + +/datum/controller/subsystem/blackbox/vv_edit_var(var_name, var_value) + switch(var_name) + if("feedback") + return FALSE + if("sealed") + if(var_value) + return Seal() + return FALSE + return ..() + +//Recorded on subsystem shutdown +/datum/controller/subsystem/blackbox/proc/FinalFeedback() + record_feedback("tally", "ahelp_stats", GLOB.ahelp_tickets.active_tickets.len, "unresolved") + for (var/obj/machinery/telecomms/message_server/MS in GLOB.telecomms_list) + if (MS.pda_msgs.len) + record_feedback("tally", "radio_usage", MS.pda_msgs.len, "PDA") + if (MS.rc_msgs.len) + record_feedback("tally", "radio_usage", MS.rc_msgs.len, "request console") + + for(var/player_key in GLOB.player_details) + var/datum/player_details/PD = GLOB.player_details[player_key] + record_feedback("tally", "client_byond_version", 1, PD.byond_version) + +/datum/controller/subsystem/blackbox/Shutdown() + sealed = FALSE + FinalFeedback() + + if (!SSdbcore.Connect()) + return + + var/list/sqlrowlist = list() + + for (var/datum/feedback_variable/FV in feedback) + var/sqlversion = 1 + if(FV.key in versions) + sqlversion = versions[FV.key] + sqlrowlist += list(list("datetime" = "Now()", "round_id" = GLOB.round_id, "key_name" = "'[sanitizeSQL(FV.key)]'", "key_type" = "'[FV.key_type]'", "version" = "[sqlversion]", "json" = "'[sanitizeSQL(json_encode(FV.json))]'")) + + if (!length(sqlrowlist)) + return + + SSdbcore.MassInsert(format_table_name("feedback"), sqlrowlist, ignore_errors = TRUE, delayed = TRUE) + +/datum/controller/subsystem/blackbox/proc/Seal() + if(sealed) + return FALSE + if(IsAdminAdvancedProcCall()) + message_admins("[key_name_admin(usr)] sealed the blackbox!") + log_game("Blackbox sealed[IsAdminAdvancedProcCall() ? " by [key_name(usr)]" : ""].") + sealed = TRUE + return TRUE + +/datum/controller/subsystem/blackbox/proc/LogBroadcast(freq) + if(sealed) + return + switch(freq) + if(FREQ_COMMON) + record_feedback("tally", "radio_usage", 1, "common") + if(FREQ_SCIENCE) + record_feedback("tally", "radio_usage", 1, "science") + if(FREQ_COMMAND) + record_feedback("tally", "radio_usage", 1, "command") + if(FREQ_MEDICAL) + record_feedback("tally", "radio_usage", 1, "medical") + if(FREQ_ENGINEERING) + record_feedback("tally", "radio_usage", 1, "engineering") + if(FREQ_SECURITY) + record_feedback("tally", "radio_usage", 1, "security") + if(FREQ_SYNDICATE) + record_feedback("tally", "radio_usage", 1, "syndicate") + if(FREQ_SERVICE) + record_feedback("tally", "radio_usage", 1, "service") + if(FREQ_SUPPLY) + record_feedback("tally", "radio_usage", 1, "supply") + if(FREQ_CENTCOM) + record_feedback("tally", "radio_usage", 1, "centcom") + if(FREQ_AI_PRIVATE) + record_feedback("tally", "radio_usage", 1, "ai private") + if(FREQ_CTF_RED) + record_feedback("tally", "radio_usage", 1, "CTF red team") + if(FREQ_CTF_BLUE) + record_feedback("tally", "radio_usage", 1, "CTF blue team") + else + record_feedback("tally", "radio_usage", 1, "other") + +/datum/controller/subsystem/blackbox/proc/find_feedback_datum(key, key_type) + for(var/datum/feedback_variable/FV in feedback) + if(FV.key == key) + return FV + + var/datum/feedback_variable/FV = new(key, key_type) + feedback += FV + return FV +/* +feedback data can be recorded in 5 formats: +"text" + used for simple single-string records i.e. the current map + further calls to the same key will append saved data unless the overwrite argument is true or it already exists + when encoded calls made with overwrite will lack square brackets + calls: SSblackbox.record_feedback("text", "example", 1, "sample text") + SSblackbox.record_feedback("text", "example", 1, "other text") + json: {"data":["sample text","other text"]} +"amount" + used to record simple counts of data i.e. the number of ahelps received + further calls to the same key will add or subtract (if increment argument is a negative) from the saved amount + calls: SSblackbox.record_feedback("amount", "example", 8) + SSblackbox.record_feedback("amount", "example", 2) + json: {"data":10} +"tally" + used to track the number of occurances of multiple related values i.e. how many times each type of gun is fired + further calls to the same key will: + add or subtract from the saved value of the data key if it already exists + append the key and it's value if it doesn't exist + calls: SSblackbox.record_feedback("tally", "example", 1, "sample data") + SSblackbox.record_feedback("tally", "example", 4, "sample data") + SSblackbox.record_feedback("tally", "example", 2, "other data") + json: {"data":{"sample data":5,"other data":2}} +"nested tally" + used to track the number of occurances of structured semi-relational values i.e. the results of arcade machines + similar to running total, but related values are nested in a multi-dimensional array built + the final element in the data list is used as the tracking key, all prior elements are used for nesting + all data list elements must be strings + further calls to the same key will: + add or subtract from the saved value of the data key if it already exists in the same multi-dimensional position + append the key and it's value if it doesn't exist + calls: SSblackbox.record_feedback("nested tally", "example", 1, list("fruit", "orange", "apricot")) + SSblackbox.record_feedback("nested tally", "example", 2, list("fruit", "orange", "orange")) + SSblackbox.record_feedback("nested tally", "example", 3, list("fruit", "orange", "apricot")) + SSblackbox.record_feedback("nested tally", "example", 10, list("fruit", "red", "apple")) + SSblackbox.record_feedback("nested tally", "example", 1, list("vegetable", "orange", "carrot")) + json: {"data":{"fruit":{"orange":{"apricot":4,"orange":2},"red":{"apple":10}},"vegetable":{"orange":{"carrot":1}}}} + tracking values associated with a number can't merge with a nesting value, trying to do so will append the list + call: SSblackbox.record_feedback("nested tally", "example", 3, list("fruit", "orange")) + json: {"data":{"fruit":{"orange":{"apricot":4,"orange":2},"red":{"apple":10},"orange":3},"vegetable":{"orange":{"carrot":1}}}} +"associative" + used to record text that's associated with a value i.e. coordinates + further calls to the same key will append a new list to existing data + calls: SSblackbox.record_feedback("associative", "example", 1, list("text" = "example", "path" = /obj/item, "number" = 4)) + SSblackbox.record_feedback("associative", "example", 1, list("number" = 7, "text" = "example", "other text" = "sample")) + json: {"data":{"1":{"text":"example","path":"/obj/item","number":"4"},"2":{"number":"7","text":"example","other text":"sample"}}} + +Versioning + If the format of a feedback variable is ever changed, i.e. how many levels of nesting are used or a new type of data is added to it, add it to the versions list + When feedback is being saved if a key is in the versions list the value specified there will be used, otherwise all keys are assumed to be version = 1 + versions is an associative list, remember to use the same string in it as defined on a feedback variable, example: + list/versions = list("round_end_stats" = 4, + "admin_toggle" = 2, + "gun_fired" = 2) +*/ +/datum/controller/subsystem/blackbox/proc/record_feedback(key_type, key, increment, data, overwrite) + if(sealed || !key_type || !istext(key) || !isnum(increment || !data)) + return + var/datum/feedback_variable/FV = find_feedback_datum(key, key_type) + switch(key_type) + if("text") + if(!istext(data)) + return + if(!islist(FV.json["data"])) + FV.json["data"] = list() + if(overwrite) + FV.json["data"] = data + else + FV.json["data"] |= data + if("amount") + FV.json["data"] += increment + if("tally") + if(!islist(FV.json["data"])) + FV.json["data"] = list() + FV.json["data"]["[data]"] += increment + if("nested tally") + if(!islist(data)) + return + if(!islist(FV.json["data"])) + FV.json["data"] = list() + FV.json["data"] = record_feedback_recurse_list(FV.json["data"], data, increment) + if("associative") + if(!islist(data)) + return + if(!islist(FV.json["data"])) + FV.json["data"] = list() + var/pos = length(FV.json["data"]) + 1 + FV.json["data"]["[pos]"] = list() //in 512 "pos" can be replaced with "[FV.json["data"].len+1]" + for(var/i in data) + if(islist(data[i])) + FV.json["data"]["[pos]"]["[i]"] = data[i] //and here with "[FV.json["data"].len]" + else + FV.json["data"]["[pos]"]["[i]"] = "[data[i]]" + else + CRASH("Invalid feedback key_type: [key_type]") + +/datum/controller/subsystem/blackbox/proc/record_feedback_recurse_list(list/L, list/key_list, increment, depth = 1) + if(depth == key_list.len) + if(L.Find(key_list[depth])) + L["[key_list[depth]]"] += increment + else + var/list/LFI = list(key_list[depth] = increment) + L += LFI + else + if(!L.Find(key_list[depth])) + var/list/LGD = list(key_list[depth] = list()) + L += LGD + L["[key_list[depth-1]]"] = .(L["[key_list[depth]]"], key_list, increment, ++depth) + return L + +/datum/feedback_variable + var/key + var/key_type + var/list/json = list() + +/datum/feedback_variable/New(new_key, new_key_type) + key = new_key + key_type = new_key_type + +/datum/controller/subsystem/blackbox/proc/ReportDeath(mob/living/L) + set waitfor = FALSE + if(sealed) + return + if(!L || !L.key || !L.mind) + return + if(!L.suiciding && !first_death.len) + first_death["name"] = "[(L.real_name == L.name) ? L.real_name : "[L.real_name] as [L.name]"]" + first_death["role"] = null + if(L.mind.assigned_role) + first_death["role"] = L.mind.assigned_role + first_death["area"] = "[AREACOORD(L)]" + first_death["damage"] = "[L.getBruteLoss()]/[L.getFireLoss()]/[L.getToxLoss()]/[L.getOxyLoss()]/[L.getCloneLoss()]" + first_death["last_words"] = L.last_words + var/sqlname = L.real_name + var/sqlkey = L.ckey + var/sqljob = L.mind.assigned_role + var/sqlspecial = L.mind.special_role + var/sqlpod = get_area_name(L, TRUE) + var/laname = L.lastattacker + var/lakey = L.lastattackerckey + var/sqlbrute = L.getBruteLoss() + var/sqlfire = L.getFireLoss() + var/sqlbrain = L.getOrganLoss(ORGAN_SLOT_BRAIN) + var/sqloxy = L.getOxyLoss() + var/sqltox = L.getToxLoss() + var/sqlclone = L.getCloneLoss() + var/sqlstamina = L.getStaminaLoss() + var/x_coord = L.x + var/y_coord = L.y + var/z_coord = L.z + var/last_words = L.last_words + var/suicide = L.suiciding + var/map = SSmapping.config.map_name + + if(!SSdbcore.Connect()) + return + + sqlname = sanitizeSQL(sqlname) + sqlkey = sanitizeSQL(sqlkey) + sqljob = sanitizeSQL(sqljob) + sqlspecial = sanitizeSQL(sqlspecial) + sqlpod = sanitizeSQL(sqlpod) + laname = sanitizeSQL(laname) + lakey = sanitizeSQL(lakey) + sqlbrute = sanitizeSQL(sqlbrute) + sqlfire = sanitizeSQL(sqlfire) + sqlbrain = sanitizeSQL(sqlbrain) + sqloxy = sanitizeSQL(sqloxy) + sqltox = sanitizeSQL(sqltox) + sqlclone = sanitizeSQL(sqlclone) + sqlstamina = sanitizeSQL(sqlstamina) + x_coord = sanitizeSQL(x_coord) + y_coord = sanitizeSQL(y_coord) + z_coord = sanitizeSQL(z_coord) + last_words = sanitizeSQL(last_words) + suicide = sanitizeSQL(suicide) + map = sanitizeSQL(map) + 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, suicide) 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])") + if(query_report_death) + query_report_death.Execute(async = TRUE) + qdel(query_report_death) diff --git a/code/controllers/subsystem/dbcore.dm b/code/controllers/subsystem/dbcore.dm index b9ad66fbce..4eff4fbf1d 100644 --- a/code/controllers/subsystem/dbcore.dm +++ b/code/controllers/subsystem/dbcore.dm @@ -1,365 +1,365 @@ -SUBSYSTEM_DEF(dbcore) - name = "Database" - flags = SS_BACKGROUND - wait = 1 MINUTES - init_order = INIT_ORDER_DBCORE - var/const/FAILED_DB_CONNECTION_CUTOFF = 5 - - var/schema_mismatch = 0 - var/db_minor = 0 - var/db_major = 0 - var/failed_connections = 0 - - var/last_error - var/list/active_queries = list() - - var/datum/BSQL_Connection/connection - var/datum/BSQL_Operation/connectOperation - -/datum/controller/subsystem/dbcore/Initialize() - //We send warnings to the admins during subsystem init, as the clients will be New'd and messages - //will queue properly with goonchat - switch(schema_mismatch) - if(1) - message_admins("Database schema ([db_major].[db_minor]) doesn't match the latest schema version ([DB_MAJOR_VERSION].[DB_MINOR_VERSION]), this may lead to undefined behaviour or errors") - if(2) - message_admins("Could not get schema version from database") - - return ..() - -/datum/controller/subsystem/dbcore/fire() - for(var/I in active_queries) - var/datum/DBQuery/Q = I - if(world.time - Q.last_activity_time > (5 MINUTES)) - message_admins("Found undeleted query, please check the server logs and notify coders.") - log_sql("Undeleted query: \"[Q.sql]\" LA: [Q.last_activity] LAT: [Q.last_activity_time]") - qdel(Q) - if(MC_TICK_CHECK) - return - -/datum/controller/subsystem/dbcore/Recover() - connection = SSdbcore.connection - connectOperation = SSdbcore.connectOperation - -/datum/controller/subsystem/dbcore/Shutdown() - //This is as close as we can get to the true round end before Disconnect() without changing where it's called, defeating the reason this is a subsystem - if(SSdbcore.Connect()) - var/datum/DBQuery/query_round_shutdown = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET shutdown_datetime = Now(), end_state = '[sanitizeSQL(SSticker.end_state)]' WHERE id = [GLOB.round_id]") - query_round_shutdown.Execute() - qdel(query_round_shutdown) - if(IsConnected()) - Disconnect() - world.BSQL_Shutdown() - -//nu -/datum/controller/subsystem/dbcore/can_vv_get(var_name) - return var_name != NAMEOF(src, connection) && var_name != NAMEOF(src, active_queries) && var_name != NAMEOF(src, connectOperation) && ..() - -/datum/controller/subsystem/dbcore/vv_edit_var(var_name, var_value) - if(var_name == NAMEOF(src, connection) || var_name == NAMEOF(src, connectOperation)) - return FALSE - return ..() - -/datum/controller/subsystem/dbcore/proc/Connect() - if(IsConnected()) - return TRUE - - if(failed_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to connect anymore. - return FALSE - - if(!CONFIG_GET(flag/sql_enabled)) - return FALSE - - var/user = CONFIG_GET(string/feedback_login) - var/pass = CONFIG_GET(string/feedback_password) - var/db = CONFIG_GET(string/feedback_database) - var/address = CONFIG_GET(string/address) - var/port = CONFIG_GET(number/port) - - connection = new /datum/BSQL_Connection(BSQL_CONNECTION_TYPE_MARIADB, CONFIG_GET(number/async_query_timeout), CONFIG_GET(number/blocking_query_timeout), CONFIG_GET(number/bsql_thread_limit)) - var/error - if(QDELETED(connection)) - connection = null - error = last_error - else - SSdbcore.last_error = null - connectOperation = connection.BeginConnect(address, port, user, pass, db) - if(SSdbcore.last_error) - CRASH(SSdbcore.last_error) - UNTIL(connectOperation.IsComplete()) - error = connectOperation.GetError() - . = !error - if (!.) - last_error = error - log_sql("Connect() failed | [error]") - ++failed_connections - QDEL_NULL(connection) - QDEL_NULL(connectOperation) - -/datum/controller/subsystem/dbcore/proc/CheckSchemaVersion() - if(CONFIG_GET(flag/sql_enabled)) - if(Connect()) - log_world("Database connection established.") - var/datum/DBQuery/query_db_version = NewQuery("SELECT major, minor FROM [format_table_name("schema_revision")] ORDER BY date DESC LIMIT 1") - query_db_version.Execute() - if(query_db_version.NextRow()) - db_major = text2num(query_db_version.item[1]) - db_minor = text2num(query_db_version.item[2]) - if(db_major != DB_MAJOR_VERSION || db_minor != DB_MINOR_VERSION) - schema_mismatch = 1 // flag admin message about mismatch - log_sql("Database schema ([db_major].[db_minor]) doesn't match the latest schema version ([DB_MAJOR_VERSION].[DB_MINOR_VERSION]), this may lead to undefined behaviour or errors") - else - schema_mismatch = 2 //flag admin message about no schema version - log_sql("Could not get schema version from database") - qdel(query_db_version) - else - log_sql("Your server failed to establish a connection with the database.") - else - log_sql("Database is not enabled in configuration.") - -/datum/controller/subsystem/dbcore/proc/SetRoundID() - if(!Connect()) - return - var/datum/DBQuery/query_round_initialize = SSdbcore.NewQuery("INSERT INTO [format_table_name("round")] (initialize_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]')") - query_round_initialize.Execute() - qdel(query_round_initialize) - var/datum/DBQuery/query_round_last_id = SSdbcore.NewQuery("SELECT LAST_INSERT_ID()") - query_round_last_id.Execute() - if(query_round_last_id.NextRow()) - GLOB.round_id = query_round_last_id.item[1] - qdel(query_round_last_id) - -/datum/controller/subsystem/dbcore/proc/SetRoundStart() - if(!Connect()) - return - var/datum/DBQuery/query_round_start = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET start_datetime = Now() WHERE id = [GLOB.round_id]") - query_round_start.Execute() - qdel(query_round_start) - -/datum/controller/subsystem/dbcore/proc/SetRoundEnd() - if(!Connect()) - return - var/sql_station_name = sanitizeSQL(station_name()) - var/datum/DBQuery/query_round_end = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET end_datetime = Now(), game_mode_result = '[sanitizeSQL(SSticker.mode_result)]', station_name = '[sql_station_name]' WHERE id = [GLOB.round_id]") - query_round_end.Execute() - qdel(query_round_end) - -/datum/controller/subsystem/dbcore/proc/Disconnect() - failed_connections = 0 - QDEL_NULL(connectOperation) - QDEL_NULL(connection) - -/datum/controller/subsystem/dbcore/proc/IsConnected() - if(!CONFIG_GET(flag/sql_enabled)) - return FALSE - //block until any connect operations finish - var/datum/BSQL_Connection/_connection = connection - var/datum/BSQL_Operation/op = connectOperation - UNTIL(QDELETED(_connection) || op.IsComplete()) - return !QDELETED(connection) && !op.GetError() - -/datum/controller/subsystem/dbcore/proc/Quote(str) - if(connection) - return connection.Quote(str) - -/datum/controller/subsystem/dbcore/proc/ErrorMsg() - if(!CONFIG_GET(flag/sql_enabled)) - return "Database disabled by configuration" - return last_error - -/datum/controller/subsystem/dbcore/proc/ReportError(error) - last_error = error - -/datum/controller/subsystem/dbcore/proc/NewQuery(sql_query) - if(IsAdminAdvancedProcCall()) - log_admin_private("ERROR: Advanced admin proc call led to sql query: [sql_query]. Query has been blocked") - message_admins("ERROR: Advanced admin proc call led to sql query. Query has been blocked") - return FALSE - return new /datum/DBQuery(sql_query, connection) - -/* -Takes a list of rows (each row being an associated list of column => value) and inserts them via a single mass query. -Rows missing columns present in other rows will resolve to SQL NULL -You are expected to do your own escaping of the data, and expected to provide your own quotes for strings. -The duplicate_key arg can be true to automatically generate this part of the query - or set to a string that is appended to the end of the query -Ignore_errors instructes mysql to continue inserting rows if some of them have errors. - the erroneous row(s) aren't inserted and there isn't really any way to know why or why errored -Delayed insert mode was removed in mysql 7 and only works with MyISAM type tables, - It was included because it is still supported in mariadb. - It does not work with duplicate_key and the mysql server ignores it in those cases -*/ -/datum/controller/subsystem/dbcore/proc/MassInsert(table, list/rows, duplicate_key = FALSE, ignore_errors = FALSE, delayed = FALSE, warn = FALSE, async = TRUE) - if (!table || !rows || !istype(rows)) - return - var/list/columns = list() - var/list/sorted_rows = list() - - for (var/list/row in rows) - var/list/sorted_row = list() - sorted_row.len = columns.len - for (var/column in row) - var/idx = columns[column] - if (!idx) - idx = columns.len + 1 - columns[column] = idx - sorted_row.len = columns.len - - sorted_row[idx] = row[column] - sorted_rows[++sorted_rows.len] = sorted_row - - if (duplicate_key == TRUE) - var/list/column_list = list() - for (var/column in columns) - column_list += "[column] = VALUES([column])" - duplicate_key = "ON DUPLICATE KEY UPDATE [column_list.Join(", ")]\n" - else if (duplicate_key == FALSE) - duplicate_key = null - - if (ignore_errors) - ignore_errors = " IGNORE" - else - ignore_errors = null - - if (delayed) - delayed = " DELAYED" - else - delayed = null - - var/list/sqlrowlist = list() - var/len = columns.len - for (var/list/row in sorted_rows) - if (length(row) != len) - row.len = len - for (var/value in row) - if (value == null) - value = "NULL" - sqlrowlist += "([row.Join(", ")])" - - sqlrowlist = " [sqlrowlist.Join(",\n ")]" - var/datum/DBQuery/Query = NewQuery("INSERT[delayed][ignore_errors] INTO [table]\n([columns.Join(", ")])\nVALUES\n[sqlrowlist]\n[duplicate_key]") - if (warn) - . = Query.warn_execute(async) - else - . = Query.Execute(async) - qdel(Query) - -/datum/DBQuery - var/sql // The sql query being executed. - var/list/item //list of data values populated by NextRow() - - var/last_activity - var/last_activity_time - - var/last_error - var/skip_next_is_complete - var/in_progress - var/datum/BSQL_Connection/connection - var/datum/BSQL_Operation/Query/query - -/datum/DBQuery/New(sql_query, datum/BSQL_Connection/connection) - SSdbcore.active_queries[src] = TRUE - Activity("Created") - item = list() - src.connection = connection - sql = sql_query - -/datum/DBQuery/Destroy() - Close() - SSdbcore.active_queries -= src - return ..() - -/datum/DBQuery/CanProcCall(proc_name) - //fuck off kevinz - return FALSE - -/datum/DBQuery/proc/SetQuery(new_sql) - if(in_progress) - CRASH("Attempted to set new sql while waiting on active query") - Close() - sql = new_sql - -/datum/DBQuery/proc/Activity(activity) - last_activity = activity - last_activity_time = world.time - -/datum/DBQuery/proc/warn_execute(async = FALSE) - . = Execute(async) - if(!.) - to_chat(usr, "A SQL error occurred during this operation, check the server logs.") - -/datum/DBQuery/proc/Execute(async = FALSE, log_error = TRUE) - Activity("Execute") - if(in_progress) - CRASH("Attempted to start a new query while waiting on the old one") - - if(QDELETED(connection)) - last_error = "No connection!" - return FALSE - - var/start_time - var/timed_out - if(!async) - start_time = REALTIMEOFDAY - Close() - query = connection.BeginQuery(sql) - if(!async) - timed_out = !query.WaitForCompletion() - else - in_progress = TRUE - UNTIL(query.IsComplete()) - in_progress = FALSE - skip_next_is_complete = TRUE - var/error = QDELETED(query) ? "Query object deleted!" : query.GetError() - last_error = error - . = !error - if(!. && log_error) - log_sql("[error] | Query used: [sql]") - if(!async && timed_out) - log_query_debug("Query execution started at [start_time]") - log_query_debug("Query execution ended at [REALTIMEOFDAY]") - log_query_debug("Slow query timeout detected.") - log_query_debug("Query used: [sql]") - slow_query_check() - -/datum/DBQuery/proc/slow_query_check() - message_admins("HEY! A database query timed out. Did the server just hang? \[YES\]|\[NO\]") - -/datum/DBQuery/proc/NextRow(async) - Activity("NextRow") - UNTIL(!in_progress) - if(!skip_next_is_complete) - if(!async) - query.WaitForCompletion() - else - in_progress = TRUE - UNTIL(query.IsComplete()) - in_progress = FALSE - else - skip_next_is_complete = FALSE - - last_error = query.GetError() - var/list/results = query.CurrentRow() - . = results != null - - item.Cut() - //populate item array - for(var/I in results) - item += results[I] - -/datum/DBQuery/proc/ErrorMsg() - return last_error - -/datum/DBQuery/proc/Close() - item.Cut() - QDEL_NULL(query) - -/world/BSQL_Debug(message) - if(!CONFIG_GET(flag/bsql_debug)) - return - - //strip sensitive stuff - if(findtext(message, ": CreateConnection(")) - message = "CreateConnection CENSORED" - - log_sql("BSQL_DEBUG: [message]") +SUBSYSTEM_DEF(dbcore) + name = "Database" + flags = SS_BACKGROUND + wait = 1 MINUTES + init_order = INIT_ORDER_DBCORE + var/const/FAILED_DB_CONNECTION_CUTOFF = 5 + + var/schema_mismatch = 0 + var/db_minor = 0 + var/db_major = 0 + var/failed_connections = 0 + + var/last_error + var/list/active_queries = list() + + var/datum/BSQL_Connection/connection + var/datum/BSQL_Operation/connectOperation + +/datum/controller/subsystem/dbcore/Initialize() + //We send warnings to the admins during subsystem init, as the clients will be New'd and messages + //will queue properly with goonchat + switch(schema_mismatch) + if(1) + message_admins("Database schema ([db_major].[db_minor]) doesn't match the latest schema version ([DB_MAJOR_VERSION].[DB_MINOR_VERSION]), this may lead to undefined behaviour or errors") + if(2) + message_admins("Could not get schema version from database") + + return ..() + +/datum/controller/subsystem/dbcore/fire() + for(var/I in active_queries) + var/datum/DBQuery/Q = I + if(world.time - Q.last_activity_time > (5 MINUTES)) + message_admins("Found undeleted query, please check the server logs and notify coders.") + log_sql("Undeleted query: \"[Q.sql]\" LA: [Q.last_activity] LAT: [Q.last_activity_time]") + qdel(Q) + if(MC_TICK_CHECK) + return + +/datum/controller/subsystem/dbcore/Recover() + connection = SSdbcore.connection + connectOperation = SSdbcore.connectOperation + +/datum/controller/subsystem/dbcore/Shutdown() + //This is as close as we can get to the true round end before Disconnect() without changing where it's called, defeating the reason this is a subsystem + if(SSdbcore.Connect()) + var/datum/DBQuery/query_round_shutdown = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET shutdown_datetime = Now(), end_state = '[sanitizeSQL(SSticker.end_state)]' WHERE id = [GLOB.round_id]") + query_round_shutdown.Execute() + qdel(query_round_shutdown) + if(IsConnected()) + Disconnect() + world.BSQL_Shutdown() + +//nu +/datum/controller/subsystem/dbcore/can_vv_get(var_name) + return var_name != NAMEOF(src, connection) && var_name != NAMEOF(src, active_queries) && var_name != NAMEOF(src, connectOperation) && ..() + +/datum/controller/subsystem/dbcore/vv_edit_var(var_name, var_value) + if(var_name == NAMEOF(src, connection) || var_name == NAMEOF(src, connectOperation)) + return FALSE + return ..() + +/datum/controller/subsystem/dbcore/proc/Connect() + if(IsConnected()) + return TRUE + + if(failed_connections > FAILED_DB_CONNECTION_CUTOFF) //If it failed to establish a connection more than 5 times in a row, don't bother attempting to connect anymore. + return FALSE + + if(!CONFIG_GET(flag/sql_enabled)) + return FALSE + + var/user = CONFIG_GET(string/feedback_login) + var/pass = CONFIG_GET(string/feedback_password) + var/db = CONFIG_GET(string/feedback_database) + var/address = CONFIG_GET(string/address) + var/port = CONFIG_GET(number/port) + + connection = new /datum/BSQL_Connection(BSQL_CONNECTION_TYPE_MARIADB, CONFIG_GET(number/async_query_timeout), CONFIG_GET(number/blocking_query_timeout), CONFIG_GET(number/bsql_thread_limit)) + var/error + if(QDELETED(connection)) + connection = null + error = last_error + else + SSdbcore.last_error = null + connectOperation = connection.BeginConnect(address, port, user, pass, db) + if(SSdbcore.last_error) + CRASH(SSdbcore.last_error) + UNTIL(connectOperation.IsComplete()) + error = connectOperation.GetError() + . = !error + if (!.) + last_error = error + log_sql("Connect() failed | [error]") + ++failed_connections + QDEL_NULL(connection) + QDEL_NULL(connectOperation) + +/datum/controller/subsystem/dbcore/proc/CheckSchemaVersion() + if(CONFIG_GET(flag/sql_enabled)) + if(Connect()) + log_world("Database connection established.") + var/datum/DBQuery/query_db_version = NewQuery("SELECT major, minor FROM [format_table_name("schema_revision")] ORDER BY date DESC LIMIT 1") + query_db_version.Execute() + if(query_db_version.NextRow()) + db_major = text2num(query_db_version.item[1]) + db_minor = text2num(query_db_version.item[2]) + if(db_major != DB_MAJOR_VERSION || db_minor != DB_MINOR_VERSION) + schema_mismatch = 1 // flag admin message about mismatch + log_sql("Database schema ([db_major].[db_minor]) doesn't match the latest schema version ([DB_MAJOR_VERSION].[DB_MINOR_VERSION]), this may lead to undefined behaviour or errors") + else + schema_mismatch = 2 //flag admin message about no schema version + log_sql("Could not get schema version from database") + qdel(query_db_version) + else + log_sql("Your server failed to establish a connection with the database.") + else + log_sql("Database is not enabled in configuration.") + +/datum/controller/subsystem/dbcore/proc/SetRoundID() + if(!Connect()) + return + var/datum/DBQuery/query_round_initialize = SSdbcore.NewQuery("INSERT INTO [format_table_name("round")] (initialize_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(IF('[world.internet_address]' LIKE '', '0', '[world.internet_address]')), '[world.port]')") + query_round_initialize.Execute() + qdel(query_round_initialize) + var/datum/DBQuery/query_round_last_id = SSdbcore.NewQuery("SELECT LAST_INSERT_ID()") + query_round_last_id.Execute() + if(query_round_last_id.NextRow()) + GLOB.round_id = query_round_last_id.item[1] + qdel(query_round_last_id) + +/datum/controller/subsystem/dbcore/proc/SetRoundStart() + if(!Connect()) + return + var/datum/DBQuery/query_round_start = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET start_datetime = Now() WHERE id = [GLOB.round_id]") + query_round_start.Execute() + qdel(query_round_start) + +/datum/controller/subsystem/dbcore/proc/SetRoundEnd() + if(!Connect()) + return + var/sql_station_name = sanitizeSQL(station_name()) + var/datum/DBQuery/query_round_end = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET end_datetime = Now(), game_mode_result = '[sanitizeSQL(SSticker.mode_result)]', station_name = '[sql_station_name]' WHERE id = [GLOB.round_id]") + query_round_end.Execute() + qdel(query_round_end) + +/datum/controller/subsystem/dbcore/proc/Disconnect() + failed_connections = 0 + QDEL_NULL(connectOperation) + QDEL_NULL(connection) + +/datum/controller/subsystem/dbcore/proc/IsConnected() + if(!CONFIG_GET(flag/sql_enabled)) + return FALSE + //block until any connect operations finish + var/datum/BSQL_Connection/_connection = connection + var/datum/BSQL_Operation/op = connectOperation + UNTIL(QDELETED(_connection) || op.IsComplete()) + return !QDELETED(connection) && !op.GetError() + +/datum/controller/subsystem/dbcore/proc/Quote(str) + if(connection) + return connection.Quote(str) + +/datum/controller/subsystem/dbcore/proc/ErrorMsg() + if(!CONFIG_GET(flag/sql_enabled)) + return "Database disabled by configuration" + return last_error + +/datum/controller/subsystem/dbcore/proc/ReportError(error) + last_error = error + +/datum/controller/subsystem/dbcore/proc/NewQuery(sql_query) + if(IsAdminAdvancedProcCall()) + log_admin_private("ERROR: Advanced admin proc call led to sql query: [sql_query]. Query has been blocked") + message_admins("ERROR: Advanced admin proc call led to sql query. Query has been blocked") + return FALSE + return new /datum/DBQuery(sql_query, connection) + +/* +Takes a list of rows (each row being an associated list of column => value) and inserts them via a single mass query. +Rows missing columns present in other rows will resolve to SQL NULL +You are expected to do your own escaping of the data, and expected to provide your own quotes for strings. +The duplicate_key arg can be true to automatically generate this part of the query + or set to a string that is appended to the end of the query +Ignore_errors instructes mysql to continue inserting rows if some of them have errors. + the erroneous row(s) aren't inserted and there isn't really any way to know why or why errored +Delayed insert mode was removed in mysql 7 and only works with MyISAM type tables, + It was included because it is still supported in mariadb. + It does not work with duplicate_key and the mysql server ignores it in those cases +*/ +/datum/controller/subsystem/dbcore/proc/MassInsert(table, list/rows, duplicate_key = FALSE, ignore_errors = FALSE, delayed = FALSE, warn = FALSE, async = TRUE) + if (!table || !rows || !istype(rows)) + return + var/list/columns = list() + var/list/sorted_rows = list() + + for (var/list/row in rows) + var/list/sorted_row = list() + sorted_row.len = columns.len + for (var/column in row) + var/idx = columns[column] + if (!idx) + idx = columns.len + 1 + columns[column] = idx + sorted_row.len = columns.len + + sorted_row[idx] = row[column] + sorted_rows[++sorted_rows.len] = sorted_row + + if (duplicate_key == TRUE) + var/list/column_list = list() + for (var/column in columns) + column_list += "[column] = VALUES([column])" + duplicate_key = "ON DUPLICATE KEY UPDATE [column_list.Join(", ")]\n" + else if (duplicate_key == FALSE) + duplicate_key = null + + if (ignore_errors) + ignore_errors = " IGNORE" + else + ignore_errors = null + + if (delayed) + delayed = " DELAYED" + else + delayed = null + + var/list/sqlrowlist = list() + var/len = columns.len + for (var/list/row in sorted_rows) + if (length(row) != len) + row.len = len + for (var/value in row) + if (value == null) + value = "NULL" + sqlrowlist += "([row.Join(", ")])" + + sqlrowlist = " [sqlrowlist.Join(",\n ")]" + var/datum/DBQuery/Query = NewQuery("INSERT[delayed][ignore_errors] INTO [table]\n([columns.Join(", ")])\nVALUES\n[sqlrowlist]\n[duplicate_key]") + if (warn) + . = Query.warn_execute(async) + else + . = Query.Execute(async) + qdel(Query) + +/datum/DBQuery + var/sql // The sql query being executed. + var/list/item //list of data values populated by NextRow() + + var/last_activity + var/last_activity_time + + var/last_error + var/skip_next_is_complete + var/in_progress + var/datum/BSQL_Connection/connection + var/datum/BSQL_Operation/Query/query + +/datum/DBQuery/New(sql_query, datum/BSQL_Connection/connection) + SSdbcore.active_queries[src] = TRUE + Activity("Created") + item = list() + src.connection = connection + sql = sql_query + +/datum/DBQuery/Destroy() + Close() + SSdbcore.active_queries -= src + return ..() + +/datum/DBQuery/CanProcCall(proc_name) + //fuck off kevinz + return FALSE + +/datum/DBQuery/proc/SetQuery(new_sql) + if(in_progress) + CRASH("Attempted to set new sql while waiting on active query") + Close() + sql = new_sql + +/datum/DBQuery/proc/Activity(activity) + last_activity = activity + last_activity_time = world.time + +/datum/DBQuery/proc/warn_execute(async = FALSE) + . = Execute(async) + if(!.) + to_chat(usr, "A SQL error occurred during this operation, check the server logs.") + +/datum/DBQuery/proc/Execute(async = FALSE, log_error = TRUE) + Activity("Execute") + if(in_progress) + CRASH("Attempted to start a new query while waiting on the old one") + + if(QDELETED(connection)) + last_error = "No connection!" + return FALSE + + var/start_time + var/timed_out + if(!async) + start_time = REALTIMEOFDAY + Close() + query = connection.BeginQuery(sql) + if(!async) + timed_out = !query.WaitForCompletion() + else + in_progress = TRUE + UNTIL(query.IsComplete()) + in_progress = FALSE + skip_next_is_complete = TRUE + var/error = QDELETED(query) ? "Query object deleted!" : query.GetError() + last_error = error + . = !error + if(!. && log_error) + log_sql("[error] | Query used: [sql]") + if(!async && timed_out) + log_query_debug("Query execution started at [start_time]") + log_query_debug("Query execution ended at [REALTIMEOFDAY]") + log_query_debug("Slow query timeout detected.") + log_query_debug("Query used: [sql]") + slow_query_check() + +/datum/DBQuery/proc/slow_query_check() + message_admins("HEY! A database query timed out. Did the server just hang? \[YES\]|\[NO\]") + +/datum/DBQuery/proc/NextRow(async) + Activity("NextRow") + UNTIL(!in_progress) + if(!skip_next_is_complete) + if(!async) + query.WaitForCompletion() + else + in_progress = TRUE + UNTIL(query.IsComplete()) + in_progress = FALSE + else + skip_next_is_complete = FALSE + + last_error = query.GetError() + var/list/results = query.CurrentRow() + . = results != null + + item.Cut() + //populate item array + for(var/I in results) + item += results[I] + +/datum/DBQuery/proc/ErrorMsg() + return last_error + +/datum/DBQuery/proc/Close() + item.Cut() + QDEL_NULL(query) + +/world/BSQL_Debug(message) + if(!CONFIG_GET(flag/bsql_debug)) + return + + //strip sensitive stuff + if(findtext(message, ": CreateConnection(")) + message = "CreateConnection CENSORED" + + log_sql("BSQL_DEBUG: [message]") diff --git a/code/controllers/subsystem/medals.dm b/code/controllers/subsystem/medals.dm index 21ab27492b..36be23973c 100644 --- a/code/controllers/subsystem/medals.dm +++ b/code/controllers/subsystem/medals.dm @@ -1,87 +1,87 @@ -SUBSYSTEM_DEF(medals) - name = "Medals" - flags = SS_NO_FIRE - var/hub_enabled = FALSE - -/datum/controller/subsystem/medals/Initialize(timeofday) - if(CONFIG_GET(string/medal_hub_address) && CONFIG_GET(string/medal_hub_password)) - hub_enabled = TRUE - return ..() - -/datum/controller/subsystem/medals/proc/UnlockMedal(medal, client/player) - set waitfor = FALSE - if(!medal || !hub_enabled) - return - if(isnull(world.SetMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)))) - hub_enabled = FALSE - log_game("MEDAL ERROR: Could not contact hub to award medal:[medal] player:[player.key]") - message_admins("Error! Failed to contact hub to award [medal] medal to [player.key]!") - return - to_chat(player, "Achievement unlocked: [medal]!") - - -/datum/controller/subsystem/medals/proc/SetScore(score, client/player, increment, force) - set waitfor = FALSE - if(!score || !hub_enabled) - return - - var/list/oldscore = GetScore(score, player, TRUE) - if(increment) - if(!oldscore[score]) - oldscore[score] = 1 - else - oldscore[score] = (text2num(oldscore[score]) + 1) - else - oldscore[score] = force - - var/newscoreparam = list2params(oldscore) - - if(isnull(world.SetScores(player.ckey, newscoreparam, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)))) - hub_enabled = FALSE - log_game("SCORE ERROR: Could not contact hub to set score. Score:[score] player:[player.key]") - message_admins("Error! Failed to contact hub to set [score] score for [player.key]!") - -/datum/controller/subsystem/medals/proc/GetScore(score, client/player, returnlist) - if(!score || !hub_enabled) - return - - var/scoreget = world.GetScores(player.ckey, score, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)) - if(isnull(scoreget)) - hub_enabled = FALSE - log_game("SCORE ERROR: Could not contact hub to get score. Score:[score] player:[player.key]") - message_admins("Error! Failed to contact hub to get score: [score] for [player.key]!") - return - . = params2list(scoreget) - if(!returnlist) - return .[score] - -/datum/controller/subsystem/medals/proc/CheckMedal(medal, client/player) - if(!medal || !hub_enabled) - return - - if(isnull(world.GetMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)))) - hub_enabled = FALSE - log_game("MEDAL ERROR: Could not contact hub to get medal:[medal] player: [player.key]") - message_admins("Error! Failed to contact hub to get [medal] medal for [player.key]!") - return - to_chat(player, "[medal] is unlocked") - -/datum/controller/subsystem/medals/proc/LockMedal(medal, client/player) - if(!player || !medal || !hub_enabled) - return - var/result = world.ClearMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)) - switch(result) - if(null) - hub_enabled = FALSE - log_game("MEDAL ERROR: Could not contact hub to clear medal:[medal] player:[player.key]") - message_admins("Error! Failed to contact hub to clear [medal] medal for [player.key]!") - if(TRUE) - message_admins("Medal: [medal] removed for [player.key]") - if(FALSE) - message_admins("Medal: [medal] was not found for [player.key]. Unable to clear.") - - -/datum/controller/subsystem/medals/proc/ClearScore(client/player) - if(isnull(world.SetScores(player.ckey, "", CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)))) - log_game("MEDAL ERROR: Could not contact hub to clear scores for [player.key]!") - message_admins("Error! Failed to contact hub to clear scores for [player.key]!") +SUBSYSTEM_DEF(medals) + name = "Medals" + flags = SS_NO_FIRE + var/hub_enabled = FALSE + +/datum/controller/subsystem/medals/Initialize(timeofday) + if(CONFIG_GET(string/medal_hub_address) && CONFIG_GET(string/medal_hub_password)) + hub_enabled = TRUE + return ..() + +/datum/controller/subsystem/medals/proc/UnlockMedal(medal, client/player) + set waitfor = FALSE + if(!medal || !hub_enabled) + return + if(isnull(world.SetMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)))) + hub_enabled = FALSE + log_game("MEDAL ERROR: Could not contact hub to award medal:[medal] player:[player.key]") + message_admins("Error! Failed to contact hub to award [medal] medal to [player.key]!") + return + to_chat(player, "Achievement unlocked: [medal]!") + + +/datum/controller/subsystem/medals/proc/SetScore(score, client/player, increment, force) + set waitfor = FALSE + if(!score || !hub_enabled) + return + + var/list/oldscore = GetScore(score, player, TRUE) + if(increment) + if(!oldscore[score]) + oldscore[score] = 1 + else + oldscore[score] = (text2num(oldscore[score]) + 1) + else + oldscore[score] = force + + var/newscoreparam = list2params(oldscore) + + if(isnull(world.SetScores(player.ckey, newscoreparam, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)))) + hub_enabled = FALSE + log_game("SCORE ERROR: Could not contact hub to set score. Score:[score] player:[player.key]") + message_admins("Error! Failed to contact hub to set [score] score for [player.key]!") + +/datum/controller/subsystem/medals/proc/GetScore(score, client/player, returnlist) + if(!score || !hub_enabled) + return + + var/scoreget = world.GetScores(player.ckey, score, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)) + if(isnull(scoreget)) + hub_enabled = FALSE + log_game("SCORE ERROR: Could not contact hub to get score. Score:[score] player:[player.key]") + message_admins("Error! Failed to contact hub to get score: [score] for [player.key]!") + return + . = params2list(scoreget) + if(!returnlist) + return .[score] + +/datum/controller/subsystem/medals/proc/CheckMedal(medal, client/player) + if(!medal || !hub_enabled) + return + + if(isnull(world.GetMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)))) + hub_enabled = FALSE + log_game("MEDAL ERROR: Could not contact hub to get medal:[medal] player: [player.key]") + message_admins("Error! Failed to contact hub to get [medal] medal for [player.key]!") + return + to_chat(player, "[medal] is unlocked") + +/datum/controller/subsystem/medals/proc/LockMedal(medal, client/player) + if(!player || !medal || !hub_enabled) + return + var/result = world.ClearMedal(medal, player, CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)) + switch(result) + if(null) + hub_enabled = FALSE + log_game("MEDAL ERROR: Could not contact hub to clear medal:[medal] player:[player.key]") + message_admins("Error! Failed to contact hub to clear [medal] medal for [player.key]!") + if(TRUE) + message_admins("Medal: [medal] removed for [player.key]") + if(FALSE) + message_admins("Medal: [medal] was not found for [player.key]. Unable to clear.") + + +/datum/controller/subsystem/medals/proc/ClearScore(client/player) + if(isnull(world.SetScores(player.ckey, "", CONFIG_GET(string/medal_hub_address), CONFIG_GET(string/medal_hub_password)))) + log_game("MEDAL ERROR: Could not contact hub to clear scores for [player.key]!") + message_admins("Error! Failed to contact hub to clear scores for [player.key]!") diff --git a/code/controllers/subsystem/moods.dm b/code/controllers/subsystem/moods.dm index d1e58c7452..f6b6ffcb40 100644 --- a/code/controllers/subsystem/moods.dm +++ b/code/controllers/subsystem/moods.dm @@ -1,4 +1,4 @@ -PROCESSING_SUBSYSTEM_DEF(mood) - name = "Mood" - flags = SS_NO_INIT | SS_BACKGROUND - priority = 20 +PROCESSING_SUBSYSTEM_DEF(mood) + name = "Mood" + flags = SS_NO_INIT | SS_BACKGROUND + priority = 20 diff --git a/code/controllers/subsystem/nightshift.dm b/code/controllers/subsystem/nightshift.dm index df406eed3c..927f68eee7 100644 --- a/code/controllers/subsystem/nightshift.dm +++ b/code/controllers/subsystem/nightshift.dm @@ -1,55 +1,55 @@ -SUBSYSTEM_DEF(nightshift) - name = "Night Shift" - wait = 600 - flags = SS_NO_TICK_CHECK - - var/nightshift_active = FALSE - var/nightshift_start_time = 702000 //7:30 PM, station time - var/nightshift_end_time = 270000 //7:30 AM, station time - var/nightshift_first_check = 30 SECONDS - - var/high_security_mode = FALSE - -/datum/controller/subsystem/nightshift/Initialize() - if(!CONFIG_GET(flag/enable_night_shifts)) - can_fire = FALSE - return ..() - -/datum/controller/subsystem/nightshift/fire(resumed = FALSE) - if(world.time - SSticker.round_start_time < nightshift_first_check) - return - check_nightshift() - -/datum/controller/subsystem/nightshift/proc/announce(message) - priority_announce(message, sound='sound/misc/notice2.ogg', sender_override="Automated Lighting System Announcement") - -/datum/controller/subsystem/nightshift/proc/check_nightshift() - var/emergency = GLOB.security_level >= SEC_LEVEL_RED - var/announcing = TRUE - var/time = STATION_TIME(FALSE) - var/night_time = (time < nightshift_end_time) || (time > nightshift_start_time) - if(high_security_mode != emergency) - high_security_mode = emergency - if(night_time) - announcing = FALSE - if(!emergency) - announce("Restoring night lighting configuration to normal operation.") - else - announce("Disabling night lighting: Station is in a state of emergency.") - if(emergency) - night_time = FALSE - if(nightshift_active != night_time) - update_nightshift(night_time, announcing) - -/datum/controller/subsystem/nightshift/proc/update_nightshift(active, announce = TRUE) - nightshift_active = active - if(announce) - if (active) - announce("Good evening, crew. To reduce power consumption and stimulate the circadian rhythms of some species, all of the lights aboard the station have been dimmed for the night.") - else - announce("Good morning, crew. As it is now day time, all of the lights aboard the station have been restored to their former brightness.") - for(var/A in GLOB.apcs_list) - var/obj/machinery/power/apc/APC = A - if (APC.area && (APC.area.type in GLOB.the_station_areas)) - APC.set_nightshift(active) - CHECK_TICK +SUBSYSTEM_DEF(nightshift) + name = "Night Shift" + wait = 600 + flags = SS_NO_TICK_CHECK + + var/nightshift_active = FALSE + var/nightshift_start_time = 702000 //7:30 PM, station time + var/nightshift_end_time = 270000 //7:30 AM, station time + var/nightshift_first_check = 30 SECONDS + + var/high_security_mode = FALSE + +/datum/controller/subsystem/nightshift/Initialize() + if(!CONFIG_GET(flag/enable_night_shifts)) + can_fire = FALSE + return ..() + +/datum/controller/subsystem/nightshift/fire(resumed = FALSE) + if(world.time - SSticker.round_start_time < nightshift_first_check) + return + check_nightshift() + +/datum/controller/subsystem/nightshift/proc/announce(message) + priority_announce(message, sound='sound/misc/notice2.ogg', sender_override="Automated Lighting System Announcement") + +/datum/controller/subsystem/nightshift/proc/check_nightshift() + var/emergency = GLOB.security_level >= SEC_LEVEL_RED + var/announcing = TRUE + var/time = STATION_TIME(FALSE) + var/night_time = (time < nightshift_end_time) || (time > nightshift_start_time) + if(high_security_mode != emergency) + high_security_mode = emergency + if(night_time) + announcing = FALSE + if(!emergency) + announce("Restoring night lighting configuration to normal operation.") + else + announce("Disabling night lighting: Station is in a state of emergency.") + if(emergency) + night_time = FALSE + if(nightshift_active != night_time) + update_nightshift(night_time, announcing) + +/datum/controller/subsystem/nightshift/proc/update_nightshift(active, announce = TRUE) + nightshift_active = active + if(announce) + if (active) + announce("Good evening, crew. To reduce power consumption and stimulate the circadian rhythms of some species, all of the lights aboard the station have been dimmed for the night.") + else + announce("Good morning, crew. As it is now day time, all of the lights aboard the station have been restored to their former brightness.") + for(var/A in GLOB.apcs_list) + var/obj/machinery/power/apc/APC = A + if (APC.area && (APC.area.type in GLOB.the_station_areas)) + APC.set_nightshift(active) + CHECK_TICK diff --git a/code/controllers/subsystem/npcpool.dm b/code/controllers/subsystem/npcpool.dm index 830db298c9..7fd3512448 100644 --- a/code/controllers/subsystem/npcpool.dm +++ b/code/controllers/subsystem/npcpool.dm @@ -1,34 +1,34 @@ -SUBSYSTEM_DEF(npcpool) - name = "NPC Pool" - flags = SS_KEEP_TIMING | SS_NO_INIT - priority = FIRE_PRIORITY_NPC - runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME - - var/list/currentrun = list() - -/datum/controller/subsystem/npcpool/stat_entry() - var/list/activelist = GLOB.simple_animals[AI_ON] - ..("NPCS:[activelist.len]") - -/datum/controller/subsystem/npcpool/fire(resumed = FALSE) - - if (!resumed) - var/list/activelist = GLOB.simple_animals[AI_ON] - src.currentrun = activelist.Copy() - - //cache for sanic speed (lists are references anyways) - var/list/currentrun = src.currentrun - - while(currentrun.len) - var/mob/living/simple_animal/SA = currentrun[currentrun.len] - --currentrun.len - - if(!SA.ckey && !SA.notransform) - if(SA.stat != DEAD) - SA.handle_automated_movement() - if(SA.stat != DEAD) - SA.handle_automated_action() - if(SA.stat != DEAD) - SA.handle_automated_speech() - if (MC_TICK_CHECK) - return +SUBSYSTEM_DEF(npcpool) + name = "NPC Pool" + flags = SS_KEEP_TIMING | SS_NO_INIT + priority = FIRE_PRIORITY_NPC + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME + + var/list/currentrun = list() + +/datum/controller/subsystem/npcpool/stat_entry() + var/list/activelist = GLOB.simple_animals[AI_ON] + ..("NPCS:[activelist.len]") + +/datum/controller/subsystem/npcpool/fire(resumed = FALSE) + + if (!resumed) + var/list/activelist = GLOB.simple_animals[AI_ON] + src.currentrun = activelist.Copy() + + //cache for sanic speed (lists are references anyways) + var/list/currentrun = src.currentrun + + while(currentrun.len) + var/mob/living/simple_animal/SA = currentrun[currentrun.len] + --currentrun.len + + if(!SA.ckey && !SA.notransform) + if(SA.stat != DEAD) + SA.handle_automated_movement() + if(SA.stat != DEAD) + SA.handle_automated_action() + if(SA.stat != DEAD) + SA.handle_automated_speech() + if (MC_TICK_CHECK) + return diff --git a/code/controllers/subsystem/pathfinder.dm b/code/controllers/subsystem/pathfinder.dm index fee93d14b2..8e1cf946ae 100644 --- a/code/controllers/subsystem/pathfinder.dm +++ b/code/controllers/subsystem/pathfinder.dm @@ -1,48 +1,48 @@ -SUBSYSTEM_DEF(pathfinder) - name = "Pathfinder" - init_order = INIT_ORDER_PATH - flags = SS_NO_FIRE - var/datum/flowcache/mobs - var/datum/flowcache/circuits - var/static/space_type_cache - -/datum/controller/subsystem/pathfinder/Initialize() - space_type_cache = typecacheof(/turf/open/space) - mobs = new(10) - circuits = new(3) - return ..() - -/datum/flowcache - var/lcount - var/run - var/free - var/list/flow - -/datum/flowcache/New(var/n) - . = ..() - lcount = n - run = 0 - free = 1 - flow = new/list(lcount) - -/datum/flowcache/proc/getfree(atom/M) - if(run < lcount) - run += 1 - while(flow[free]) - CHECK_TICK - free = (free % lcount) + 1 - var/t = addtimer(CALLBACK(src, /datum/flowcache.proc/toolong, free), 150, TIMER_STOPPABLE) - flow[free] = t - flow[t] = M - return free - else - return 0 - -/datum/flowcache/proc/toolong(l) - log_game("Pathfinder route took longer than 150 ticks, src bot [flow[flow[l]]]") - found(l) - -/datum/flowcache/proc/found(l) - deltimer(flow[l]) - flow[l] = null - run -= 1 +SUBSYSTEM_DEF(pathfinder) + name = "Pathfinder" + init_order = INIT_ORDER_PATH + flags = SS_NO_FIRE + var/datum/flowcache/mobs + var/datum/flowcache/circuits + var/static/space_type_cache + +/datum/controller/subsystem/pathfinder/Initialize() + space_type_cache = typecacheof(/turf/open/space) + mobs = new(10) + circuits = new(3) + return ..() + +/datum/flowcache + var/lcount + var/run + var/free + var/list/flow + +/datum/flowcache/New(var/n) + . = ..() + lcount = n + run = 0 + free = 1 + flow = new/list(lcount) + +/datum/flowcache/proc/getfree(atom/M) + if(run < lcount) + run += 1 + while(flow[free]) + CHECK_TICK + free = (free % lcount) + 1 + var/t = addtimer(CALLBACK(src, /datum/flowcache.proc/toolong, free), 150, TIMER_STOPPABLE) + flow[free] = t + flow[t] = M + return free + else + return 0 + +/datum/flowcache/proc/toolong(l) + log_game("Pathfinder route took longer than 150 ticks, src bot [flow[flow[l]]]") + found(l) + +/datum/flowcache/proc/found(l) + deltimer(flow[l]) + flow[l] = null + run -= 1 diff --git a/code/controllers/subsystem/processing/networks.dm b/code/controllers/subsystem/processing/networks.dm index 0ca5472a6a..03276d5b26 100644 --- a/code/controllers/subsystem/processing/networks.dm +++ b/code/controllers/subsystem/processing/networks.dm @@ -1,51 +1,51 @@ -PROCESSING_SUBSYSTEM_DEF(networks) - name = "Networks" - priority = FIRE_PRIORITY_NETWORKS - wait = 1 - stat_tag = "NET" - flags = SS_KEEP_TIMING - init_order = INIT_ORDER_NETWORKS - var/datum/ntnet/station/station_network - var/assignment_hardware_id = HID_RESTRICTED_END - var/list/networks_by_id = list() //id = network - var/list/interfaces_by_id = list() //hardware id = component interface - var/resolve_collisions = TRUE - -/datum/controller/subsystem/processing/networks/Initialize() - station_network = new - station_network.register_map_supremecy() - . = ..() - -/datum/controller/subsystem/processing/networks/proc/register_network(datum/ntnet/network) - if(!networks_by_id[network.network_id]) - networks_by_id[network.network_id] = network - return TRUE - return FALSE - -/datum/controller/subsystem/processing/networks/proc/unregister_network(datum/ntnet/network) - networks_by_id -= network.network_id - return TRUE - -/datum/controller/subsystem/processing/networks/proc/register_interface(datum/component/ntnet_interface/D) - if(!interfaces_by_id[D.hardware_id]) - interfaces_by_id[D.hardware_id] = D - return TRUE - return FALSE - -/datum/controller/subsystem/processing/networks/proc/unregister_interface(datum/component/ntnet_interface/D) - interfaces_by_id -= D.hardware_id - return TRUE - -/datum/controller/subsystem/processing/networks/proc/get_next_HID() - var/string = "[num2text(assignment_hardware_id++, 12)]" - return make_address(string) - -/datum/controller/subsystem/processing/networks/proc/make_address(string) - if(!string) - return resolve_collisions? make_address("[num2text(rand(HID_RESTRICTED_END, 999999999), 12)]"):null - var/hex = md5(string) - if(!hex) - return //errored - . = "[copytext(hex, 1, 9)]" //16 ^ 8 possibilities I think. - if(interfaces_by_id[.]) - return resolve_collisions? make_address("[num2text(rand(HID_RESTRICTED_END, 999999999), 12)]"):null +PROCESSING_SUBSYSTEM_DEF(networks) + name = "Networks" + priority = FIRE_PRIORITY_NETWORKS + wait = 1 + stat_tag = "NET" + flags = SS_KEEP_TIMING + init_order = INIT_ORDER_NETWORKS + var/datum/ntnet/station/station_network + var/assignment_hardware_id = HID_RESTRICTED_END + var/list/networks_by_id = list() //id = network + var/list/interfaces_by_id = list() //hardware id = component interface + var/resolve_collisions = TRUE + +/datum/controller/subsystem/processing/networks/Initialize() + station_network = new + station_network.register_map_supremecy() + . = ..() + +/datum/controller/subsystem/processing/networks/proc/register_network(datum/ntnet/network) + if(!networks_by_id[network.network_id]) + networks_by_id[network.network_id] = network + return TRUE + return FALSE + +/datum/controller/subsystem/processing/networks/proc/unregister_network(datum/ntnet/network) + networks_by_id -= network.network_id + return TRUE + +/datum/controller/subsystem/processing/networks/proc/register_interface(datum/component/ntnet_interface/D) + if(!interfaces_by_id[D.hardware_id]) + interfaces_by_id[D.hardware_id] = D + return TRUE + return FALSE + +/datum/controller/subsystem/processing/networks/proc/unregister_interface(datum/component/ntnet_interface/D) + interfaces_by_id -= D.hardware_id + return TRUE + +/datum/controller/subsystem/processing/networks/proc/get_next_HID() + var/string = "[num2text(assignment_hardware_id++, 12)]" + return make_address(string) + +/datum/controller/subsystem/processing/networks/proc/make_address(string) + if(!string) + return resolve_collisions? make_address("[num2text(rand(HID_RESTRICTED_END, 999999999), 12)]"):null + var/hex = md5(string) + if(!hex) + return //errored + . = "[copytext(hex, 1, 9)]" //16 ^ 8 possibilities I think. + if(interfaces_by_id[.]) + return resolve_collisions? make_address("[num2text(rand(HID_RESTRICTED_END, 999999999), 12)]"):null diff --git a/code/controllers/subsystem/processing/projectiles.dm b/code/controllers/subsystem/processing/projectiles.dm index b0930d3d07..4171b5f8c1 100644 --- a/code/controllers/subsystem/processing/projectiles.dm +++ b/code/controllers/subsystem/processing/projectiles.dm @@ -1,23 +1,23 @@ -PROCESSING_SUBSYSTEM_DEF(projectiles) - name = "Projectiles" - wait = 1 - stat_tag = "PP" - flags = SS_NO_INIT|SS_TICKER - var/global_max_tick_moves = 10 - var/global_pixel_speed = 2 - var/global_iterations_per_move = 16 - -/datum/controller/subsystem/processing/projectiles/proc/set_pixel_speed(new_speed) - global_pixel_speed = new_speed - for(var/i in processing) - var/obj/item/projectile/P = i - if(istype(P)) //there's non projectiles on this too. - P.set_pixel_speed(new_speed) - -/datum/controller/subsystem/processing/projectiles/vv_edit_var(var_name, var_value) - switch(var_name) - if(NAMEOF(src, global_pixel_speed)) - set_pixel_speed(var_value) - return TRUE - else - return ..() +PROCESSING_SUBSYSTEM_DEF(projectiles) + name = "Projectiles" + wait = 1 + stat_tag = "PP" + flags = SS_NO_INIT|SS_TICKER + var/global_max_tick_moves = 10 + var/global_pixel_speed = 2 + var/global_iterations_per_move = 16 + +/datum/controller/subsystem/processing/projectiles/proc/set_pixel_speed(new_speed) + global_pixel_speed = new_speed + for(var/i in processing) + var/obj/item/projectile/P = i + if(istype(P)) //there's non projectiles on this too. + P.set_pixel_speed(new_speed) + +/datum/controller/subsystem/processing/projectiles/vv_edit_var(var_name, var_value) + switch(var_name) + if(NAMEOF(src, global_pixel_speed)) + set_pixel_speed(var_value) + return TRUE + else + return ..() diff --git a/code/controllers/subsystem/processing/wet_floors.dm b/code/controllers/subsystem/processing/wet_floors.dm index dfbc1ac8e4..4bda8b5453 100644 --- a/code/controllers/subsystem/processing/wet_floors.dm +++ b/code/controllers/subsystem/processing/wet_floors.dm @@ -1,7 +1,7 @@ -PROCESSING_SUBSYSTEM_DEF(wet_floors) - name = "Wet floors" - priority = FIRE_PRIORITY_WET_FLOORS - wait = 10 - stat_tag = "WFP" //Used for logging - var/temperature_coeff = 2 - var/time_ratio = 1.5 SECONDS +PROCESSING_SUBSYSTEM_DEF(wet_floors) + name = "Wet floors" + priority = FIRE_PRIORITY_WET_FLOORS + wait = 10 + stat_tag = "WFP" //Used for logging + var/temperature_coeff = 2 + var/time_ratio = 1.5 SECONDS diff --git a/code/controllers/subsystem/research.dm b/code/controllers/subsystem/research.dm index ab27658efd..900dfd1c54 100644 --- a/code/controllers/subsystem/research.dm +++ b/code/controllers/subsystem/research.dm @@ -1,530 +1,530 @@ - -SUBSYSTEM_DEF(research) - name = "Research" - priority = FIRE_PRIORITY_RESEARCH - wait = 10 - init_order = INIT_ORDER_RESEARCH - //TECHWEB STATIC - var/list/techweb_nodes = list() //associative id = node datum - var/list/techweb_designs = list() //associative id = node datum - var/list/datum/techweb/techwebs = list() - var/datum/techweb/science/science_tech - var/datum/techweb/admin/admin_tech - var/datum/techweb_node/error_node/error_node //These two are what you get if a node/design is deleted and somehow still stored in a console. - var/datum/design/error_design/error_design - - //ERROR LOGGING - var/list/invalid_design_ids = list() //associative id = number of times - var/list/invalid_node_ids = list() //associative id = number of times - var/list/invalid_node_boost = list() //associative id = error message - - var/list/obj/machinery/rnd/server/servers = list() - - var/list/techweb_nodes_starting = list() //associative id = TRUE - var/list/techweb_categories = list() //category name = list(node.id = TRUE) - var/list/techweb_boost_items = list() //associative double-layer path = list(id = list(point_type = point_discount)) - var/list/techweb_nodes_hidden = list() //Node ids that should be hidden by default. - var/list/techweb_point_items = list( //path = list(point type = value) - /obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 5000), // Cit three more anomalys anomalys - /obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 7500), - /obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 10000), - // - Slime Extracts! - - /obj/item/slime_extract/grey = list(TECHWEB_POINT_TYPE_GENERIC = 500), // Adds in slime core deconing - /obj/item/slime_extract/metal = list(TECHWEB_POINT_TYPE_GENERIC = 750), - /obj/item/slime_extract/purple = list(TECHWEB_POINT_TYPE_GENERIC = 750), - /obj/item/slime_extract/orange = list(TECHWEB_POINT_TYPE_GENERIC = 750), - /obj/item/slime_extract/blue = list(TECHWEB_POINT_TYPE_GENERIC = 750), - /obj/item/slime_extract/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 1000), - /obj/item/slime_extract/silver = list(TECHWEB_POINT_TYPE_GENERIC = 1000), - /obj/item/slime_extract/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 1000), - /obj/item/slime_extract/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 1000), - /obj/item/slime_extract/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 1250), - /obj/item/slime_extract/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 1250), - /obj/item/slime_extract/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 1250), - /obj/item/slime_extract/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 1250), - /obj/item/slime_extract/red = list(TECHWEB_POINT_TYPE_GENERIC = 1250), - /obj/item/slime_extract/green = list(TECHWEB_POINT_TYPE_GENERIC = 1250), - /obj/item/slime_extract/pink = list(TECHWEB_POINT_TYPE_GENERIC = 1250), - /obj/item/slime_extract/gold = list(TECHWEB_POINT_TYPE_GENERIC = 1250), - /obj/item/slime_extract/black = list(TECHWEB_POINT_TYPE_GENERIC = 1500), - /obj/item/slime_extract/adamantine =list (TECHWEB_POINT_TYPE_GENERIC = 1500), - /obj/item/slime_extract/oil = list(TECHWEB_POINT_TYPE_GENERIC = 1500), - /obj/item/slime_extract/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 1500), - /obj/item/slime_extract/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - // Reproductive - Crossbreading Cores! - (Grey Cores) - /obj/item/slimecross/reproductive/grey = list(TECHWEB_POINT_TYPE_GENERIC = 1000), - /obj/item/slimecross/reproductive/orange = list(TECHWEB_POINT_TYPE_GENERIC = 1500), - /obj/item/slimecross/reproductive/purple = list(TECHWEB_POINT_TYPE_GENERIC = 1500), - /obj/item/slimecross/reproductive/blue = list(TECHWEB_POINT_TYPE_GENERIC = 1500), - /obj/item/slimecross/reproductive/metal = list(TECHWEB_POINT_TYPE_GENERIC = 1500), - /obj/item/slimecross/reproductive/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 1750), - /obj/item/slimecross/reproductive/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 1750), - /obj/item/slimecross/reproductive/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 1750), - /obj/item/slimecross/reproductive/silver = list(TECHWEB_POINT_TYPE_GENERIC = 1750), - /obj/item/slimecross/reproductive/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 2000), - /obj/item/slimecross/reproductive/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 2000), - /obj/item/slimecross/reproductive/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 2000), - /obj/item/slimecross/reproductive/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 2000), - /obj/item/slimecross/reproductive/red = list(TECHWEB_POINT_TYPE_GENERIC = 2250), - /obj/item/slimecross/reproductive/green = list(TECHWEB_POINT_TYPE_GENERIC = 2250), - /obj/item/slimecross/reproductive/pink = list(TECHWEB_POINT_TYPE_GENERIC = 2250), - /obj/item/slimecross/reproductive/gold = list(TECHWEB_POINT_TYPE_GENERIC = 2250), - /obj/item/slimecross/reproductive/oil = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/reproductive/black = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/reproductive/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/reproductive/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/reproductive/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - // Burning - Crossbreading Cores! - (Orange Cores) - /obj/item/slimecross/burning/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2000), - /obj/item/slimecross/burning/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/burning/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/burning/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/burning/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/burning/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/burning/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/burning/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/burning/silver = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/burning/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/burning/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/burning/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/burning/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/burning/red = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/burning/green = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/burning/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/burning/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/burning/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/burning/black = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/burning/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/burning/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/burning/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - // Regenerative - Crossbreading Cores! - (Purple Cores) - /obj/item/slimecross/regenerative/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2000), - /obj/item/slimecross/regenerative/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/regenerative/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/regenerative/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/regenerative/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/regenerative/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/regenerative/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/regenerative/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/regenerative/silver = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/regenerative/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/regenerative/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/regenerative/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/regenerative/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/regenerative/red = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/regenerative/green = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/regenerative/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/regenerative/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/regenerative/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/regenerative/black = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/regenerative/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/regenerative/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/regenerative/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - // Stabilized - Crossbreading Cores! - (Blue Cores) - /obj/item/slimecross/stabilized/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2000), - /obj/item/slimecross/stabilized/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/stabilized/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/stabilized/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/stabilized/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/stabilized/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/stabilized/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/stabilized/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/stabilized/silver = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/stabilized/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/stabilized/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/stabilized/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/stabilized/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/stabilized/red = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/stabilized/green = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/stabilized/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/stabilized/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/stabilized/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/stabilized/black = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/stabilized/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/stabilized/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/stabilized/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - // Industrial - Crossbreading Cores! - (Metal Cores) - /obj/item/slimecross/industrial/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2000), - /obj/item/slimecross/industrial/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/industrial/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/industrial/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/industrial/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/industrial/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/industrial/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/industrial/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/industrial/silver = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/industrial/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/industrial/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/industrial/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/industrial/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/industrial/red = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/industrial/green = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/industrial/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/industrial/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/industrial/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/industrial/black = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/industrial/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/industrial/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/industrial/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - // Charged - Crossbreading Cores! - (Yellow Cores) - /obj/item/slimecross/charged/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2250), - /obj/item/slimecross/charged/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/charged/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/charged/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/charged/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/charged/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/charged/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/charged/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/charged/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/charged/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/charged/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/charged/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/charged/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/charged/red = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/charged/green = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/charged/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/charged/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/charged/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/charged/black = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/charged/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/charged/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/charged/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - // Selfsustaining - Crossbreading Cores! - (Dark Purple Cores) - /obj/item/slimecross/selfsustaining/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2250), - /obj/item/slimecross/selfsustaining/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/selfsustaining/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/selfsustaining/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/selfsustaining/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/selfsustaining/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/selfsustaining/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/selfsustaining/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/selfsustaining/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/selfsustaining/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/selfsustaining/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/selfsustaining/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/selfsustaining/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/selfsustaining/red = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/selfsustaining/green = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/selfsustaining/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/selfsustaining/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/selfsustaining/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/selfsustaining/black = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/selfsustaining/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/selfsustaining/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/selfsustaining/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - // Consuming - Crossbreading Cores! - (Sliver Cores) - /obj/item/slimecross/consuming/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2250), - /obj/item/slimecross/consuming/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/consuming/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/consuming/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/consuming/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2750), - /obj/item/slimecross/consuming/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/consuming/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/consuming/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/consuming/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/consuming/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/consuming/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/consuming/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/consuming/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/consuming/red = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/consuming/green = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/consuming/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/consuming/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/consuming/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/consuming/black = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/consuming/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/consuming/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/consuming/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - // Prismatic - Crossbreading Cores! - (Pyrite Cores) - /obj/item/slimecross/prismatic/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/prismatic/orange = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/prismatic/purple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/prismatic/blue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/prismatic/metal = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/prismatic/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/prismatic/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/prismatic/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/prismatic/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/prismatic/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/prismatic/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/prismatic/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/prismatic/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/prismatic/red = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/prismatic/green = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/prismatic/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/prismatic/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/prismatic/oil = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - /obj/item/slimecross/prismatic/black = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - /obj/item/slimecross/prismatic/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - /obj/item/slimecross/prismatic/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - /obj/item/slimecross/prismatic/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4250), - // Recurring - Crossbreading Cores! - (Cerulean Cores) - /obj/item/slimecross/recurring/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2500), - /obj/item/slimecross/recurring/orange = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/recurring/purple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/recurring/blue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/recurring/metal = list(TECHWEB_POINT_TYPE_GENERIC = 3000), - /obj/item/slimecross/recurring/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/recurring/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/recurring/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/recurring/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3250), - /obj/item/slimecross/recurring/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/recurring/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/recurring/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/recurring/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3500), - /obj/item/slimecross/recurring/red = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/recurring/green = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/recurring/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/recurring/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3750), - /obj/item/slimecross/recurring/oil = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - /obj/item/slimecross/recurring/black = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - /obj/item/slimecross/recurring/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - /obj/item/slimecross/recurring/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 4000), - /obj/item/slimecross/recurring/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4250) - ) // End of Cit changes - var/list/errored_datums = list() - var/list/point_types = list() //typecache style type = TRUE list - //---------------------------------------------- - var/list/single_server_income = list(TECHWEB_POINT_TYPE_GENERIC = 35) //citadel edit - techwebs nerf - var/multiserver_calculation = FALSE - var/last_income - //^^^^^^^^ ALL OF THESE ARE PER SECOND! ^^^^^^^^ - - //Aiming for 1.5 hours to max R&D - //[88nodes * 5000points/node] / [1.5hr * 90min/hr * 60s/min] - //Around 450000 points max??? - -/datum/controller/subsystem/research/Initialize() - point_types = TECHWEB_POINT_TYPE_LIST_ASSOCIATIVE_NAMES - initialize_all_techweb_designs() - initialize_all_techweb_nodes() - science_tech = new /datum/techweb/science - admin_tech = new /datum/techweb/admin - autosort_categories() - error_design = new - error_node = new - return ..() - -/datum/controller/subsystem/research/fire() - var/list/bitcoins = list() - if(multiserver_calculation) - var/eff = calculate_server_coefficient() - for(var/obj/machinery/rnd/server/miner in servers) - var/list/result = (miner.mine()) //SLAVE AWAY, SLAVE. - for(var/i in result) - result[i] *= eff - bitcoins[i] = bitcoins[i]? bitcoins[i] + result[i] : result[i] - else - for(var/obj/machinery/rnd/server/miner in servers) - if(miner.working) - bitcoins = single_server_income.Copy() - break //Just need one to work. - if (!isnull(last_income)) - var/income_time_difference = world.time - last_income - science_tech.last_bitcoins = bitcoins // Doesn't take tick drift into account - for(var/i in bitcoins) - bitcoins[i] *= income_time_difference / 10 - science_tech.add_point_list(bitcoins) - last_income = world.time - -/datum/controller/subsystem/research/proc/calculate_server_coefficient() //Diminishing returns. - var/amt = servers.len - if(!amt) - return 0 - var/coeff = 100 - coeff = sqrt(coeff / amt) - return coeff - -/datum/controller/subsystem/research/proc/autosort_categories() - for(var/i in techweb_nodes) - var/datum/techweb_node/I = techweb_nodes[i] - if(techweb_categories[I.category]) - techweb_categories[I.category][I.id] = TRUE - else - techweb_categories[I.category] = list(I.id = TRUE) - -/datum/controller/subsystem/research/proc/techweb_node_by_id(id) - return techweb_nodes[id] || error_node - -/datum/controller/subsystem/research/proc/techweb_design_by_id(id) - return techweb_designs[id] || error_design - -/datum/controller/subsystem/research/proc/on_design_deletion(datum/design/D) - for(var/i in techweb_nodes) - var/datum/techweb_node/TN = techwebs[i] - TN.on_design_deletion(TN) - for(var/i in techwebs) - var/datum/techweb/T = i - T.recalculate_nodes(TRUE) - -/datum/controller/subsystem/research/proc/on_node_deletion(datum/techweb_node/TN) - for(var/i in techweb_nodes) - var/datum/techweb_node/TN2 = techwebs[i] - TN2.on_node_deletion(TN) - for(var/i in techwebs) - var/datum/techweb/T = i - T.recalculate_nodes(TRUE) - -/datum/controller/subsystem/research/proc/initialize_all_techweb_nodes(clearall = FALSE) - if(islist(techweb_nodes) && clearall) - QDEL_LIST(techweb_nodes) - if(islist(techweb_nodes_starting && clearall)) - techweb_nodes_starting.Cut() - var/list/returned = list() - for(var/path in subtypesof(/datum/techweb_node)) - var/datum/techweb_node/TN = path - if(isnull(initial(TN.id))) - continue - TN = new path - if(returned[initial(TN.id)]) - stack_trace("WARNING: Techweb node ID clash with ID [initial(TN.id)] detected! Path: [path]") - errored_datums[TN] = initial(TN.id) - continue - returned[initial(TN.id)] = TN - if(TN.starting_node) - techweb_nodes_starting[TN.id] = TRUE - for(var/id in techweb_nodes) - var/datum/techweb_node/TN = techweb_nodes[id] - TN.Initialize() - techweb_nodes = returned - if (!verify_techweb_nodes()) //Verify all nodes have ids and such. - stack_trace("Invalid techweb nodes detected") - calculate_techweb_nodes() - calculate_techweb_boost_list() - if (!verify_techweb_nodes()) //Verify nodes and designs have been crosslinked properly. - CRASH("Invalid techweb nodes detected") - -/datum/controller/subsystem/research/proc/initialize_all_techweb_designs(clearall = FALSE) - if(islist(techweb_designs) && clearall) - QDEL_LIST(techweb_designs) - var/list/returned = list() - for(var/path in subtypesof(/datum/design)) - var/datum/design/DN = path - if(isnull(initial(DN.id))) - stack_trace("WARNING: Design with null ID detected. Build path: [initial(DN.build_path)]") - continue - else if(initial(DN.id) == DESIGN_ID_IGNORE) - continue - DN = new path - if(returned[initial(DN.id)]) - stack_trace("WARNING: Design ID clash with ID [initial(DN.id)] detected! Path: [path]") - errored_datums[DN] = initial(DN.id) - continue - returned[initial(DN.id)] = DN - techweb_designs = returned - verify_techweb_designs() - -/datum/controller/subsystem/research/proc/verify_techweb_nodes() - . = TRUE - for(var/n in techweb_nodes) - var/datum/techweb_node/N = techweb_nodes[n] - if(!istype(N)) - WARNING("Invalid research node with ID [n] detected and removed.") - techweb_nodes -= n - research_node_id_error(n) - . = FALSE - for(var/p in N.prereq_ids) - var/datum/techweb_node/P = techweb_nodes[p] - if(!istype(P)) - WARNING("Invalid research prerequisite node with ID [p] detected in node [N.display_name]\[[N.id]\] removed.") - N.prereq_ids -= p - research_node_id_error(p) - . = FALSE - for(var/d in N.design_ids) - var/datum/design/D = techweb_designs[d] - if(!istype(D)) - WARNING("Invalid research design with ID [d] detected in node [N.display_name]\[[N.id]\] removed.") - N.design_ids -= d - design_id_error(d) - . = FALSE - for(var/u in N.unlock_ids) - var/datum/techweb_node/U = techweb_nodes[u] - if(!istype(U)) - WARNING("Invalid research unlock node with ID [u] detected in node [N.display_name]\[[N.id]\] removed.") - N.unlock_ids -= u - research_node_id_error(u) - . = FALSE - for(var/p in N.boost_item_paths) - if(!ispath(p)) - N.boost_item_paths -= p - WARNING("[p] is not a valid path.") - node_boost_error(N.id, "[p] is not a valid path.") - . = FALSE - var/list/points = N.boost_item_paths[p] - if(islist(points)) - for(var/i in points) - if(!isnum(points[i])) - WARNING("[points[i]] is not a valid number.") - node_boost_error(N.id, "[points[i]] is not a valid number.") - . = FALSE - else if(!point_types[i]) - WARNING("[i] is not a valid point type.") - node_boost_error(N.id, "[i] is not a valid point type.") - . = FALSE - else if(!isnull(points)) - N.boost_item_paths -= p - node_boost_error(N.id, "No valid list.") - WARNING("No valid list.") - . = FALSE - CHECK_TICK - -/datum/controller/subsystem/research/proc/verify_techweb_designs() - for(var/d in techweb_designs) - var/datum/design/D = techweb_designs[d] - if(!istype(D)) - stack_trace("WARNING: Invalid research design with ID [d] detected and removed.") - techweb_designs -= d - CHECK_TICK - -/datum/controller/subsystem/research/proc/research_node_id_error(id) - if(invalid_node_ids[id]) - invalid_node_ids[id]++ - else - invalid_node_ids[id] = 1 - -/datum/controller/subsystem/research/proc/design_id_error(id) - if(invalid_design_ids[id]) - invalid_design_ids[id]++ - else - invalid_design_ids[id] = 1 - -/datum/controller/subsystem/research/proc/calculate_techweb_nodes() - for(var/design_id in techweb_designs) - var/datum/design/D = techweb_designs[design_id] - D.unlocked_by.Cut() - for(var/node_id in techweb_nodes) - var/datum/techweb_node/node = techweb_nodes[node_id] - node.unlock_ids = list() - for(var/i in node.design_ids) - var/datum/design/D = techweb_designs[i] - node.design_ids[i] = TRUE - D.unlocked_by += node.id - if(node.hidden) - techweb_nodes_hidden[node.id] = TRUE - CHECK_TICK - generate_techweb_unlock_linking() - -/datum/controller/subsystem/research/proc/generate_techweb_unlock_linking() - for(var/node_id in techweb_nodes) //Clear all unlock links to avoid duplication. - var/datum/techweb_node/node = techweb_nodes[node_id] - node.unlock_ids = list() - for(var/node_id in techweb_nodes) - var/datum/techweb_node/node = techweb_nodes[node_id] - for(var/prereq_id in node.prereq_ids) - var/datum/techweb_node/prereq_node = techweb_node_by_id(prereq_id) - prereq_node.unlock_ids[node.id] = node - -/datum/controller/subsystem/research/proc/calculate_techweb_boost_list(clearall = FALSE) - if(clearall) - techweb_boost_items = list() - for(var/node_id in techweb_nodes) - var/datum/techweb_node/node = techweb_nodes[node_id] - for(var/path in node.boost_item_paths) - if(!ispath(path)) - continue - if(length(techweb_boost_items[path])) - techweb_boost_items[path][node.id] = node.boost_item_paths[path] - else - techweb_boost_items[path] = list(node.id = node.boost_item_paths[path]) - CHECK_TICK + +SUBSYSTEM_DEF(research) + name = "Research" + priority = FIRE_PRIORITY_RESEARCH + wait = 10 + init_order = INIT_ORDER_RESEARCH + //TECHWEB STATIC + var/list/techweb_nodes = list() //associative id = node datum + var/list/techweb_designs = list() //associative id = node datum + var/list/datum/techweb/techwebs = list() + var/datum/techweb/science/science_tech + var/datum/techweb/admin/admin_tech + var/datum/techweb_node/error_node/error_node //These two are what you get if a node/design is deleted and somehow still stored in a console. + var/datum/design/error_design/error_design + + //ERROR LOGGING + var/list/invalid_design_ids = list() //associative id = number of times + var/list/invalid_node_ids = list() //associative id = number of times + var/list/invalid_node_boost = list() //associative id = error message + + var/list/obj/machinery/rnd/server/servers = list() + + var/list/techweb_nodes_starting = list() //associative id = TRUE + var/list/techweb_categories = list() //category name = list(node.id = TRUE) + var/list/techweb_boost_items = list() //associative double-layer path = list(id = list(point_type = point_discount)) + var/list/techweb_nodes_hidden = list() //Node ids that should be hidden by default. + var/list/techweb_point_items = list( //path = list(point type = value) + /obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 5000), // Cit three more anomalys anomalys + /obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 7500), + /obj/item/assembly/signaler/anomaly = list(TECHWEB_POINT_TYPE_GENERIC = 10000), + // - Slime Extracts! - + /obj/item/slime_extract/grey = list(TECHWEB_POINT_TYPE_GENERIC = 500), // Adds in slime core deconing + /obj/item/slime_extract/metal = list(TECHWEB_POINT_TYPE_GENERIC = 750), + /obj/item/slime_extract/purple = list(TECHWEB_POINT_TYPE_GENERIC = 750), + /obj/item/slime_extract/orange = list(TECHWEB_POINT_TYPE_GENERIC = 750), + /obj/item/slime_extract/blue = list(TECHWEB_POINT_TYPE_GENERIC = 750), + /obj/item/slime_extract/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 1000), + /obj/item/slime_extract/silver = list(TECHWEB_POINT_TYPE_GENERIC = 1000), + /obj/item/slime_extract/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 1000), + /obj/item/slime_extract/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 1000), + /obj/item/slime_extract/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 1250), + /obj/item/slime_extract/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 1250), + /obj/item/slime_extract/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 1250), + /obj/item/slime_extract/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 1250), + /obj/item/slime_extract/red = list(TECHWEB_POINT_TYPE_GENERIC = 1250), + /obj/item/slime_extract/green = list(TECHWEB_POINT_TYPE_GENERIC = 1250), + /obj/item/slime_extract/pink = list(TECHWEB_POINT_TYPE_GENERIC = 1250), + /obj/item/slime_extract/gold = list(TECHWEB_POINT_TYPE_GENERIC = 1250), + /obj/item/slime_extract/black = list(TECHWEB_POINT_TYPE_GENERIC = 1500), + /obj/item/slime_extract/adamantine =list (TECHWEB_POINT_TYPE_GENERIC = 1500), + /obj/item/slime_extract/oil = list(TECHWEB_POINT_TYPE_GENERIC = 1500), + /obj/item/slime_extract/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 1500), + /obj/item/slime_extract/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + // Reproductive - Crossbreading Cores! - (Grey Cores) + /obj/item/slimecross/reproductive/grey = list(TECHWEB_POINT_TYPE_GENERIC = 1000), + /obj/item/slimecross/reproductive/orange = list(TECHWEB_POINT_TYPE_GENERIC = 1500), + /obj/item/slimecross/reproductive/purple = list(TECHWEB_POINT_TYPE_GENERIC = 1500), + /obj/item/slimecross/reproductive/blue = list(TECHWEB_POINT_TYPE_GENERIC = 1500), + /obj/item/slimecross/reproductive/metal = list(TECHWEB_POINT_TYPE_GENERIC = 1500), + /obj/item/slimecross/reproductive/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 1750), + /obj/item/slimecross/reproductive/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 1750), + /obj/item/slimecross/reproductive/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 1750), + /obj/item/slimecross/reproductive/silver = list(TECHWEB_POINT_TYPE_GENERIC = 1750), + /obj/item/slimecross/reproductive/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 2000), + /obj/item/slimecross/reproductive/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 2000), + /obj/item/slimecross/reproductive/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 2000), + /obj/item/slimecross/reproductive/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 2000), + /obj/item/slimecross/reproductive/red = list(TECHWEB_POINT_TYPE_GENERIC = 2250), + /obj/item/slimecross/reproductive/green = list(TECHWEB_POINT_TYPE_GENERIC = 2250), + /obj/item/slimecross/reproductive/pink = list(TECHWEB_POINT_TYPE_GENERIC = 2250), + /obj/item/slimecross/reproductive/gold = list(TECHWEB_POINT_TYPE_GENERIC = 2250), + /obj/item/slimecross/reproductive/oil = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/reproductive/black = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/reproductive/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/reproductive/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/reproductive/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + // Burning - Crossbreading Cores! - (Orange Cores) + /obj/item/slimecross/burning/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2000), + /obj/item/slimecross/burning/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/burning/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/burning/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/burning/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/burning/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/burning/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/burning/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/burning/silver = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/burning/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/burning/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/burning/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/burning/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/burning/red = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/burning/green = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/burning/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/burning/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/burning/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/burning/black = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/burning/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/burning/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/burning/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + // Regenerative - Crossbreading Cores! - (Purple Cores) + /obj/item/slimecross/regenerative/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2000), + /obj/item/slimecross/regenerative/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/regenerative/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/regenerative/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/regenerative/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/regenerative/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/regenerative/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/regenerative/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/regenerative/silver = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/regenerative/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/regenerative/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/regenerative/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/regenerative/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/regenerative/red = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/regenerative/green = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/regenerative/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/regenerative/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/regenerative/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/regenerative/black = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/regenerative/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/regenerative/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/regenerative/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + // Stabilized - Crossbreading Cores! - (Blue Cores) + /obj/item/slimecross/stabilized/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2000), + /obj/item/slimecross/stabilized/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/stabilized/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/stabilized/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/stabilized/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/stabilized/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/stabilized/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/stabilized/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/stabilized/silver = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/stabilized/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/stabilized/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/stabilized/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/stabilized/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/stabilized/red = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/stabilized/green = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/stabilized/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/stabilized/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/stabilized/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/stabilized/black = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/stabilized/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/stabilized/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/stabilized/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + // Industrial - Crossbreading Cores! - (Metal Cores) + /obj/item/slimecross/industrial/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2000), + /obj/item/slimecross/industrial/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/industrial/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/industrial/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/industrial/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/industrial/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/industrial/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/industrial/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/industrial/silver = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/industrial/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/industrial/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/industrial/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/industrial/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/industrial/red = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/industrial/green = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/industrial/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/industrial/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/industrial/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/industrial/black = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/industrial/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/industrial/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/industrial/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + // Charged - Crossbreading Cores! - (Yellow Cores) + /obj/item/slimecross/charged/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2250), + /obj/item/slimecross/charged/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/charged/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/charged/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/charged/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/charged/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/charged/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/charged/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/charged/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/charged/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/charged/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/charged/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/charged/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/charged/red = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/charged/green = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/charged/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/charged/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/charged/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/charged/black = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/charged/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/charged/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/charged/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + // Selfsustaining - Crossbreading Cores! - (Dark Purple Cores) + /obj/item/slimecross/selfsustaining/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2250), + /obj/item/slimecross/selfsustaining/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/selfsustaining/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/selfsustaining/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/selfsustaining/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/selfsustaining/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/selfsustaining/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/selfsustaining/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/selfsustaining/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/selfsustaining/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/selfsustaining/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/selfsustaining/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/selfsustaining/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/selfsustaining/red = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/selfsustaining/green = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/selfsustaining/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/selfsustaining/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/selfsustaining/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/selfsustaining/black = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/selfsustaining/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/selfsustaining/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/selfsustaining/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + // Consuming - Crossbreading Cores! - (Sliver Cores) + /obj/item/slimecross/consuming/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2250), + /obj/item/slimecross/consuming/orange = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/consuming/purple = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/consuming/blue = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/consuming/metal = list(TECHWEB_POINT_TYPE_GENERIC = 2750), + /obj/item/slimecross/consuming/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/consuming/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/consuming/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/consuming/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/consuming/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/consuming/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/consuming/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/consuming/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/consuming/red = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/consuming/green = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/consuming/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/consuming/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/consuming/oil = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/consuming/black = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/consuming/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/consuming/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/consuming/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + // Prismatic - Crossbreading Cores! - (Pyrite Cores) + /obj/item/slimecross/prismatic/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/prismatic/orange = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/prismatic/purple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/prismatic/blue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/prismatic/metal = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/prismatic/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/prismatic/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/prismatic/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/prismatic/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/prismatic/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/prismatic/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/prismatic/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/prismatic/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/prismatic/red = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/prismatic/green = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/prismatic/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/prismatic/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/prismatic/oil = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/prismatic/black = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/prismatic/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/prismatic/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/prismatic/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4250), + // Recurring - Crossbreading Cores! - (Cerulean Cores) + /obj/item/slimecross/recurring/grey = list(TECHWEB_POINT_TYPE_GENERIC = 2500), + /obj/item/slimecross/recurring/orange = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/recurring/purple = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/recurring/blue = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/recurring/metal = list(TECHWEB_POINT_TYPE_GENERIC = 3000), + /obj/item/slimecross/recurring/yellow = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/recurring/darkpurple = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/recurring/darkblue = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/recurring/silver = list(TECHWEB_POINT_TYPE_GENERIC = 3250), + /obj/item/slimecross/recurring/bluespace = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/recurring/sepia = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/recurring/cerulean = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/recurring/pyrite = list(TECHWEB_POINT_TYPE_GENERIC = 3500), + /obj/item/slimecross/recurring/red = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/recurring/green = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/recurring/pink = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/recurring/gold = list(TECHWEB_POINT_TYPE_GENERIC = 3750), + /obj/item/slimecross/recurring/oil = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/recurring/black = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/recurring/lightpink = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/recurring/adamantine = list(TECHWEB_POINT_TYPE_GENERIC = 4000), + /obj/item/slimecross/recurring/rainbow = list(TECHWEB_POINT_TYPE_GENERIC = 4250) + ) // End of Cit changes + var/list/errored_datums = list() + var/list/point_types = list() //typecache style type = TRUE list + //---------------------------------------------- + var/list/single_server_income = list(TECHWEB_POINT_TYPE_GENERIC = 35) //citadel edit - techwebs nerf + var/multiserver_calculation = FALSE + var/last_income + //^^^^^^^^ ALL OF THESE ARE PER SECOND! ^^^^^^^^ + + //Aiming for 1.5 hours to max R&D + //[88nodes * 5000points/node] / [1.5hr * 90min/hr * 60s/min] + //Around 450000 points max??? + +/datum/controller/subsystem/research/Initialize() + point_types = TECHWEB_POINT_TYPE_LIST_ASSOCIATIVE_NAMES + initialize_all_techweb_designs() + initialize_all_techweb_nodes() + science_tech = new /datum/techweb/science + admin_tech = new /datum/techweb/admin + autosort_categories() + error_design = new + error_node = new + return ..() + +/datum/controller/subsystem/research/fire() + var/list/bitcoins = list() + if(multiserver_calculation) + var/eff = calculate_server_coefficient() + for(var/obj/machinery/rnd/server/miner in servers) + var/list/result = (miner.mine()) //SLAVE AWAY, SLAVE. + for(var/i in result) + result[i] *= eff + bitcoins[i] = bitcoins[i]? bitcoins[i] + result[i] : result[i] + else + for(var/obj/machinery/rnd/server/miner in servers) + if(miner.working) + bitcoins = single_server_income.Copy() + break //Just need one to work. + if (!isnull(last_income)) + var/income_time_difference = world.time - last_income + science_tech.last_bitcoins = bitcoins // Doesn't take tick drift into account + for(var/i in bitcoins) + bitcoins[i] *= income_time_difference / 10 + science_tech.add_point_list(bitcoins) + last_income = world.time + +/datum/controller/subsystem/research/proc/calculate_server_coefficient() //Diminishing returns. + var/amt = servers.len + if(!amt) + return 0 + var/coeff = 100 + coeff = sqrt(coeff / amt) + return coeff + +/datum/controller/subsystem/research/proc/autosort_categories() + for(var/i in techweb_nodes) + var/datum/techweb_node/I = techweb_nodes[i] + if(techweb_categories[I.category]) + techweb_categories[I.category][I.id] = TRUE + else + techweb_categories[I.category] = list(I.id = TRUE) + +/datum/controller/subsystem/research/proc/techweb_node_by_id(id) + return techweb_nodes[id] || error_node + +/datum/controller/subsystem/research/proc/techweb_design_by_id(id) + return techweb_designs[id] || error_design + +/datum/controller/subsystem/research/proc/on_design_deletion(datum/design/D) + for(var/i in techweb_nodes) + var/datum/techweb_node/TN = techwebs[i] + TN.on_design_deletion(TN) + for(var/i in techwebs) + var/datum/techweb/T = i + T.recalculate_nodes(TRUE) + +/datum/controller/subsystem/research/proc/on_node_deletion(datum/techweb_node/TN) + for(var/i in techweb_nodes) + var/datum/techweb_node/TN2 = techwebs[i] + TN2.on_node_deletion(TN) + for(var/i in techwebs) + var/datum/techweb/T = i + T.recalculate_nodes(TRUE) + +/datum/controller/subsystem/research/proc/initialize_all_techweb_nodes(clearall = FALSE) + if(islist(techweb_nodes) && clearall) + QDEL_LIST(techweb_nodes) + if(islist(techweb_nodes_starting && clearall)) + techweb_nodes_starting.Cut() + var/list/returned = list() + for(var/path in subtypesof(/datum/techweb_node)) + var/datum/techweb_node/TN = path + if(isnull(initial(TN.id))) + continue + TN = new path + if(returned[initial(TN.id)]) + stack_trace("WARNING: Techweb node ID clash with ID [initial(TN.id)] detected! Path: [path]") + errored_datums[TN] = initial(TN.id) + continue + returned[initial(TN.id)] = TN + if(TN.starting_node) + techweb_nodes_starting[TN.id] = TRUE + for(var/id in techweb_nodes) + var/datum/techweb_node/TN = techweb_nodes[id] + TN.Initialize() + techweb_nodes = returned + if (!verify_techweb_nodes()) //Verify all nodes have ids and such. + stack_trace("Invalid techweb nodes detected") + calculate_techweb_nodes() + calculate_techweb_boost_list() + if (!verify_techweb_nodes()) //Verify nodes and designs have been crosslinked properly. + CRASH("Invalid techweb nodes detected") + +/datum/controller/subsystem/research/proc/initialize_all_techweb_designs(clearall = FALSE) + if(islist(techweb_designs) && clearall) + QDEL_LIST(techweb_designs) + var/list/returned = list() + for(var/path in subtypesof(/datum/design)) + var/datum/design/DN = path + if(isnull(initial(DN.id))) + stack_trace("WARNING: Design with null ID detected. Build path: [initial(DN.build_path)]") + continue + else if(initial(DN.id) == DESIGN_ID_IGNORE) + continue + DN = new path + if(returned[initial(DN.id)]) + stack_trace("WARNING: Design ID clash with ID [initial(DN.id)] detected! Path: [path]") + errored_datums[DN] = initial(DN.id) + continue + returned[initial(DN.id)] = DN + techweb_designs = returned + verify_techweb_designs() + +/datum/controller/subsystem/research/proc/verify_techweb_nodes() + . = TRUE + for(var/n in techweb_nodes) + var/datum/techweb_node/N = techweb_nodes[n] + if(!istype(N)) + WARNING("Invalid research node with ID [n] detected and removed.") + techweb_nodes -= n + research_node_id_error(n) + . = FALSE + for(var/p in N.prereq_ids) + var/datum/techweb_node/P = techweb_nodes[p] + if(!istype(P)) + WARNING("Invalid research prerequisite node with ID [p] detected in node [N.display_name]\[[N.id]\] removed.") + N.prereq_ids -= p + research_node_id_error(p) + . = FALSE + for(var/d in N.design_ids) + var/datum/design/D = techweb_designs[d] + if(!istype(D)) + WARNING("Invalid research design with ID [d] detected in node [N.display_name]\[[N.id]\] removed.") + N.design_ids -= d + design_id_error(d) + . = FALSE + for(var/u in N.unlock_ids) + var/datum/techweb_node/U = techweb_nodes[u] + if(!istype(U)) + WARNING("Invalid research unlock node with ID [u] detected in node [N.display_name]\[[N.id]\] removed.") + N.unlock_ids -= u + research_node_id_error(u) + . = FALSE + for(var/p in N.boost_item_paths) + if(!ispath(p)) + N.boost_item_paths -= p + WARNING("[p] is not a valid path.") + node_boost_error(N.id, "[p] is not a valid path.") + . = FALSE + var/list/points = N.boost_item_paths[p] + if(islist(points)) + for(var/i in points) + if(!isnum(points[i])) + WARNING("[points[i]] is not a valid number.") + node_boost_error(N.id, "[points[i]] is not a valid number.") + . = FALSE + else if(!point_types[i]) + WARNING("[i] is not a valid point type.") + node_boost_error(N.id, "[i] is not a valid point type.") + . = FALSE + else if(!isnull(points)) + N.boost_item_paths -= p + node_boost_error(N.id, "No valid list.") + WARNING("No valid list.") + . = FALSE + CHECK_TICK + +/datum/controller/subsystem/research/proc/verify_techweb_designs() + for(var/d in techweb_designs) + var/datum/design/D = techweb_designs[d] + if(!istype(D)) + stack_trace("WARNING: Invalid research design with ID [d] detected and removed.") + techweb_designs -= d + CHECK_TICK + +/datum/controller/subsystem/research/proc/research_node_id_error(id) + if(invalid_node_ids[id]) + invalid_node_ids[id]++ + else + invalid_node_ids[id] = 1 + +/datum/controller/subsystem/research/proc/design_id_error(id) + if(invalid_design_ids[id]) + invalid_design_ids[id]++ + else + invalid_design_ids[id] = 1 + +/datum/controller/subsystem/research/proc/calculate_techweb_nodes() + for(var/design_id in techweb_designs) + var/datum/design/D = techweb_designs[design_id] + D.unlocked_by.Cut() + for(var/node_id in techweb_nodes) + var/datum/techweb_node/node = techweb_nodes[node_id] + node.unlock_ids = list() + for(var/i in node.design_ids) + var/datum/design/D = techweb_designs[i] + node.design_ids[i] = TRUE + D.unlocked_by += node.id + if(node.hidden) + techweb_nodes_hidden[node.id] = TRUE + CHECK_TICK + generate_techweb_unlock_linking() + +/datum/controller/subsystem/research/proc/generate_techweb_unlock_linking() + for(var/node_id in techweb_nodes) //Clear all unlock links to avoid duplication. + var/datum/techweb_node/node = techweb_nodes[node_id] + node.unlock_ids = list() + for(var/node_id in techweb_nodes) + var/datum/techweb_node/node = techweb_nodes[node_id] + for(var/prereq_id in node.prereq_ids) + var/datum/techweb_node/prereq_node = techweb_node_by_id(prereq_id) + prereq_node.unlock_ids[node.id] = node + +/datum/controller/subsystem/research/proc/calculate_techweb_boost_list(clearall = FALSE) + if(clearall) + techweb_boost_items = list() + for(var/node_id in techweb_nodes) + var/datum/techweb_node/node = techweb_nodes[node_id] + for(var/path in node.boost_item_paths) + if(!ispath(path)) + continue + if(length(techweb_boost_items[path])) + techweb_boost_items[path][node.id] = node.boost_item_paths[path] + else + techweb_boost_items[path] = list(node.id = node.boost_item_paths[path]) + CHECK_TICK diff --git a/code/controllers/subsystem/spacedrift.dm b/code/controllers/subsystem/spacedrift.dm index 56a6786a20..c251492227 100644 --- a/code/controllers/subsystem/spacedrift.dm +++ b/code/controllers/subsystem/spacedrift.dm @@ -1,59 +1,59 @@ -SUBSYSTEM_DEF(spacedrift) - name = "Space Drift" - priority = FIRE_PRIORITY_SPACEDRIFT - wait = 5 - flags = SS_NO_INIT|SS_KEEP_TIMING - runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME - - var/list/currentrun = list() - var/list/processing = list() - -/datum/controller/subsystem/spacedrift/stat_entry() - ..("P:[processing.len]") - - -/datum/controller/subsystem/spacedrift/fire(resumed = 0) - if (!resumed) - src.currentrun = processing.Copy() - - //cache for sanic speed (lists are references anyways) - var/list/currentrun = src.currentrun - - while (currentrun.len) - var/atom/movable/AM = currentrun[currentrun.len] - currentrun.len-- - if (!AM) - processing -= AM - if (MC_TICK_CHECK) - return - continue - - if (AM.inertia_next_move > world.time) - if (MC_TICK_CHECK) - return - continue - - if (!AM.loc || AM.loc != AM.inertia_last_loc || AM.Process_Spacemove(0)) - AM.inertia_dir = 0 - - if (!AM.inertia_dir) - AM.inertia_last_loc = null - processing -= AM - if (MC_TICK_CHECK) - return - continue - - var/old_dir = AM.dir - var/old_loc = AM.loc - AM.inertia_moving = TRUE - step(AM, AM.inertia_dir) - AM.inertia_moving = FALSE - AM.inertia_next_move = world.time + AM.inertia_move_delay - if (AM.loc == old_loc) - AM.inertia_dir = 0 - - AM.setDir(old_dir) - AM.inertia_last_loc = AM.loc - if (MC_TICK_CHECK) - return - +SUBSYSTEM_DEF(spacedrift) + name = "Space Drift" + priority = FIRE_PRIORITY_SPACEDRIFT + wait = 5 + flags = SS_NO_INIT|SS_KEEP_TIMING + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME + + var/list/currentrun = list() + var/list/processing = list() + +/datum/controller/subsystem/spacedrift/stat_entry() + ..("P:[processing.len]") + + +/datum/controller/subsystem/spacedrift/fire(resumed = 0) + if (!resumed) + src.currentrun = processing.Copy() + + //cache for sanic speed (lists are references anyways) + var/list/currentrun = src.currentrun + + while (currentrun.len) + var/atom/movable/AM = currentrun[currentrun.len] + currentrun.len-- + if (!AM) + processing -= AM + if (MC_TICK_CHECK) + return + continue + + if (AM.inertia_next_move > world.time) + if (MC_TICK_CHECK) + return + continue + + if (!AM.loc || AM.loc != AM.inertia_last_loc || AM.Process_Spacemove(0)) + AM.inertia_dir = 0 + + if (!AM.inertia_dir) + AM.inertia_last_loc = null + processing -= AM + if (MC_TICK_CHECK) + return + continue + + var/old_dir = AM.dir + var/old_loc = AM.loc + AM.inertia_moving = TRUE + step(AM, AM.inertia_dir) + AM.inertia_moving = FALSE + AM.inertia_next_move = world.time + AM.inertia_move_delay + if (AM.loc == old_loc) + AM.inertia_dir = 0 + + AM.setDir(old_dir) + AM.inertia_last_loc = AM.loc + if (MC_TICK_CHECK) + return + diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index f82954276e..66aaf317fb 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -1,676 +1,676 @@ -#define VOTE_COOLDOWN 10 - -SUBSYSTEM_DEF(vote) - name = "Vote" - wait = 10 - - flags = SS_KEEP_TIMING|SS_NO_INIT - - runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT - - var/initiator = null - var/started_time = null - var/end_time = 0 - var/mode = null - var/vote_system = PLURALITY_VOTING - var/question = null - var/list/choices = list() - var/list/scores = list() - var/list/choice_descs = list() // optional descriptions - var/list/voted = list() - var/list/voting = list() - var/list/saved = list() - var/list/generated_actions = list() - var/next_pop = 0 - - var/obfuscated = FALSE//CIT CHANGE - adds obfuscated/admin-only votes - - var/list/stored_gamemode_votes = list() //Basically the last voted gamemode is stored here for end-of-round use. - - var/list/stored_modetier_results = list() // The aggregated tier list of the modes available in secret. - -/datum/controller/subsystem/vote/fire() //called by master_controller - if(mode) - if(end_time < world.time) - result() - SSpersistence.SaveSavedVotes() - for(var/client/C in voting) - C << browse(null, "window=vote;can_close=0") - if(end_time < world.time) // result() can change this - reset() - else if(next_pop < world.time) - var/datum/browser/client_popup - for(var/client/C in voting) - client_popup = new(C, "vote", "Voting Panel", nwidth=600,nheight=700) - client_popup.set_window_options("can_close=0") - client_popup.set_content(interface(C)) - client_popup.open(0) - next_pop = world.time+VOTE_COOLDOWN - - - -/datum/controller/subsystem/vote/proc/reset() - initiator = null - end_time = 0 - mode = null - question = null - choices.Cut() - choice_descs.Cut() - voted.Cut() - voting.Cut() - scores.Cut() - obfuscated = FALSE //CIT CHANGE - obfuscated votes - remove_action_buttons() - -/datum/controller/subsystem/vote/proc/get_result() - //get the highest number of votes - var/greatest_votes = 0 - var/total_votes = 0 - for(var/option in choices) - var/votes = choices[option] - total_votes += votes - if(votes > greatest_votes) - greatest_votes = votes - //default-vote for everyone who didn't vote - if(!CONFIG_GET(flag/default_no_vote) && choices.len) - var/list/non_voters = GLOB.directory.Copy() - non_voters -= voted - for (var/non_voter_ckey in non_voters) - var/client/C = non_voters[non_voter_ckey] - if (!C || C.is_afk()) - non_voters -= non_voter_ckey - if(non_voters.len > 0) - if(mode == "restart") - choices["Continue Playing"] += non_voters.len - if(choices["Continue Playing"] >= greatest_votes) - greatest_votes = choices["Continue Playing"] - else if(mode == "gamemode") - if(GLOB.master_mode in choices) - choices[GLOB.master_mode] += non_voters.len - if(choices[GLOB.master_mode] >= greatest_votes) - greatest_votes = choices[GLOB.master_mode] - //get all options with that many votes and return them in a list - . = list() - if(greatest_votes) - for(var/option in choices) - if(choices[option] == greatest_votes) - . += option - return . - -/datum/controller/subsystem/vote/proc/calculate_condorcet_votes(var/blackbox_text) - // https://en.wikipedia.org/wiki/Schulze_method#Implementation - var/list/d[][] = new/list(choices.len,choices.len) // the basic vote matrix, how many times a beats b - for(var/ckey in voted) - var/list/this_vote = voted[ckey] - for(var/a in 1 to choices.len) - for(var/b in a+1 to choices.len) - var/a_rank = this_vote.Find(a) - var/b_rank = this_vote.Find(b) - a_rank = a_rank ? a_rank : choices.len+1 - b_rank = b_rank ? b_rank : choices.len+1 - if(a_rankopposite_pref) - p[i][j] = d[i][j] - else - p[i][j] = 0 - for(var/i in 1 to choices.len) - for(var/j in 1 to choices.len) - if(i != j) - for(var/k in 1 to choices.len) // YEAH O(n^3) !! - if(i != k && j != k) - p[j][k] = max(p[j][k],min(p[j][i], p[i][k])) - //one last pass, now that we've done the math - for(var/i in 1 to choices.len) - for(var/j in 1 to choices.len) - if(i != j) - SSblackbox.record_feedback("nested tally","voting",p[i][j],list(blackbox_text,"Shortest Paths",choices[i],choices[j])) - if(p[i][j] >= p[j][i]) - choices[choices[i]]++ // higher shortest path = better candidate, so we add to choices here - // choices[choices[i]] is the schulze ranking, here, rather than raw vote numbers - -/datum/controller/subsystem/vote/proc/calculate_majority_judgement_vote(var/blackbox_text) - // https://en.wikipedia.org/wiki/Majority_judgment - var/list/scores_by_choice = list() - for(var/choice in choices) - scores_by_choice[choice] = list() - for(var/ckey in voted) - var/list/this_vote = voted[ckey] - var/list/pretty_vote = list() - for(var/choice in this_vote) - sorted_insert(scores_by_choice[choice],this_vote[choice],/proc/cmp_numeric_asc) - // START BALLOT GATHERING - pretty_vote += choice - pretty_vote[choice] = GLOB.vote_score_options[this_vote[choice]] - SSblackbox.record_feedback("associative","voting_ballots",1,pretty_vote) - // END BALLOT GATHERING - for(var/score_name in scores_by_choice) - var/list/score = scores_by_choice[score_name] - for(var/indiv_score in score) - SSblackbox.record_feedback("nested tally","voting",1,list(blackbox_text,"Scores",score_name,GLOB.vote_score_options[indiv_score])) - if(score.len == 0) - scores_by_choice -= score_name - while(scores_by_choice.len > 1) - var/highest_median = 0 - for(var/score_name in scores_by_choice) // first get highest median - var/list/score = scores_by_choice[score_name] - if(!score.len) - scores_by_choice -= score_name - continue - var/median = score[max(1,round(score.len/2))] - if(median >= highest_median) - highest_median = median - for(var/score_name in scores_by_choice) // then, remove - var/list/score = scores_by_choice[score_name] - var/median = score[max(1,round(score.len/2))] - if(median < highest_median) - scores_by_choice -= score_name - for(var/score_name in scores_by_choice) // after removals - var/list/score = scores_by_choice[score_name] - if(score.len == 0) - choices[score_name] += 100 // we're in a tie situation--just go with the first one - return - var/median_pos = max(1,round(score.len/2)) - score.Cut(median_pos,median_pos+1) - choices[score_name]++ - -/datum/controller/subsystem/vote/proc/calculate_scores(var/blackbox_text) - var/list/scores_by_choice = list() - for(var/choice in choices) - scores_by_choice[choice] = list() - for(var/ckey in voted) - var/list/this_vote = voted[ckey] - for(var/choice in this_vote) - sorted_insert(scores_by_choice[choice],this_vote[choice],/proc/cmp_numeric_asc) - var/middle_score = round(GLOB.vote_score_options.len/2,1) - for(var/score_name in scores_by_choice) - var/list/score = scores_by_choice[score_name] - for(var/S in score) - scores[score_name] += S-middle_score - SSblackbox.record_feedback("nested tally","voting",scores[score_name],list(blackbox_text,"Total scores",score_name)) - - -/datum/controller/subsystem/vote/proc/announce_result() - var/vote_title_text - var/text - if(question) - text += "[question]" - vote_title_text = "[question]" - else - text += "[capitalize(mode)] Vote" - vote_title_text = "[capitalize(mode)] Vote" - if(vote_system == RANKED_CHOICE_VOTING) - calculate_condorcet_votes(vote_title_text) - if(vote_system == SCORE_VOTING) - calculate_majority_judgement_vote(vote_title_text) - var/list/winners = get_result() - var/was_roundtype_vote = mode == "roundtype" || mode == "dynamic" - if(winners.len > 0) - if(was_roundtype_vote) - stored_gamemode_votes = list() - if(!obfuscated && vote_system == RANKED_CHOICE_VOTING) - text += "\nIt should be noted that this is not a raw tally of votes (impossible in ranked choice) but the score determined by the schulze method of voting, so the numbers will look weird!" - for(var/i=1,i<=choices.len,i++) - var/votes = choices[choices[i]] - if(!votes) - votes = 0 - if(was_roundtype_vote) - stored_gamemode_votes[choices[i]] = votes - text += "\n[choices[i]]: [obfuscated ? "???" : votes]" //CIT CHANGE - adds obfuscated votes - if(mode != "custom") - if(winners.len > 1 && !obfuscated) //CIT CHANGE - adds obfuscated votes - text = "\nVote Tied Between:" - for(var/option in winners) - text += "\n\t[option]" - . = pick(winners) - text += "\nVote Result: [obfuscated ? "???" : .]" //CIT CHANGE - adds obfuscated votes - else - text += "\nDid not vote: [GLOB.clients.len-voted.len]" - else - text += "Vote Result: Inconclusive - No Votes!" - log_vote(text) - remove_action_buttons() - to_chat(world, "\n[text]") - switch(vote_system) - if(APPROVAL_VOTING,PLURALITY_VOTING) - for(var/i=1,i<=choices.len,i++) - SSblackbox.record_feedback("nested tally","voting",choices[choices[i]],list(vote_title_text,choices[i])) - if(RANKED_CHOICE_VOTING) - for(var/i=1,i<=voted.len,i++) - var/list/myvote = voted[voted[i]] - for(var/j=1,j<=myvote.len,j++) - SSblackbox.record_feedback("nested tally","voting",1,list(vote_title_text,"[j]\th",choices[myvote[j]])) - if(obfuscated) //CIT CHANGE - adds obfuscated votes. this messages admins with the vote's true results - var/admintext = "Obfuscated results" - if(vote_system == RANKED_CHOICE_VOTING) - admintext += "\nIt should be noted that this is not a raw tally of votes (impossible in ranked choice) but the score determined by the schulze method of voting, so the numbers will look weird!" - else if(vote_system == SCORE_VOTING) - admintext += "\nIt should be noted that this is not a raw tally of votes but the number of runoffs done by majority judgement!" - for(var/i=1,i<=choices.len,i++) - var/votes = choices[choices[i]] - admintext += "\n[choices[i]]: [votes]" - message_admins(admintext) - return . - -/datum/controller/subsystem/vote/proc/result() - . = announce_result() - var/restart = 0 - if(.) - switch(mode) - if("roundtype") //CIT CHANGE - adds the roundstart extended/secret vote - if(SSticker.current_state > GAME_STATE_PREGAME)//Don't change the mode if the round already started. - return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.") - GLOB.master_mode = . - SSticker.save_mode(.) - message_admins("The gamemode has been voted for, and has been changed to: [GLOB.master_mode]") - log_admin("Gamemode has been voted for and switched to: [GLOB.master_mode].") - if(CONFIG_GET(flag/modetier_voting)) - reset() - started_time = 0 - initiate_vote("mode tiers","server",hideresults=FALSE,votesystem=RANKED_CHOICE_VOTING,forced=TRUE, vote_time = 30 MINUTES) - to_chat(world,"The vote will end right as the round starts.") - return . - if("restart") - if(. == "Restart Round") - restart = 1 - if("gamemode") - if(GLOB.master_mode != .) - SSticker.save_mode(.) - if(SSticker.HasRoundStarted()) - restart = 1 - else - GLOB.master_mode = . - if("mode tiers") - stored_modetier_results = choices.Copy() - if("dynamic") - if(SSticker.current_state > GAME_STATE_PREGAME)//Don't change the mode if the round already started. - return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.") - if(. == "Secret") - GLOB.master_mode = "secret" - SSticker.save_mode(.) - message_admins("The gamemode has been voted for, and has been changed to: [GLOB.master_mode]") - log_admin("Gamemode has been voted for and switched to: [GLOB.master_mode].") - else - GLOB.master_mode = "dynamic" - var/datum/dynamic_storyteller/S = config.pick_storyteller(.) - GLOB.dynamic_storyteller_type = S - if("map") - var/datum/map_config/VM = config.maplist[.] - message_admins("The map has been voted for and will change to: [VM.map_name]") - log_admin("The map has been voted for and will change to: [VM.map_name]") - if(SSmapping.changemap(config.maplist[.])) - to_chat(world, "The map vote has chosen [VM.map_name] for next round!") - if(restart) - var/active_admins = 0 - for(var/client/C in GLOB.admins) - if(!C.is_afk() && check_rights_for(C, R_SERVER)) - active_admins = 1 - break - if(!active_admins) - SSticker.Reboot("Restart vote successful.", "restart vote") - else - to_chat(world, "Notice:Restart vote will not restart the server automatically because there are active admins on.") - message_admins("A restart vote has passed, but there are active admins on with +server, so it has been canceled. If you wish, you may restart the server.") - - return . - -/datum/controller/subsystem/vote/proc/submit_vote(vote, score = 0) - if(mode) - if(CONFIG_GET(flag/no_dead_vote) && usr.stat == DEAD && !usr.client.holder) - return 0 - if(vote && ISINRANGE(vote, 1, choices.len)) - switch(vote_system) - if(PLURALITY_VOTING) - if(usr.ckey in voted) - choices[choices[voted[usr.ckey]]]-- - voted[usr.ckey] = vote - choices[choices[vote]]++ - return vote - else - voted += usr.ckey - voted[usr.ckey] = vote - choices[choices[vote]]++ //check this - return vote - if(APPROVAL_VOTING) - if(usr.ckey in voted) - if(vote in voted[usr.ckey]) - voted[usr.ckey] -= vote - choices[choices[vote]]-- - else - voted[usr.ckey] += vote - choices[choices[vote]]++ - else - voted += usr.ckey - voted[usr.ckey] = list(vote) - choices[choices[vote]]++ - return vote - if(RANKED_CHOICE_VOTING) - if(usr.ckey in voted) - if(vote in voted[usr.ckey]) - voted[usr.ckey] -= vote - else - voted += usr.ckey - voted[usr.ckey] = list() - voted[usr.ckey] += vote - saved -= usr.ckey - if(SCORE_VOTING) - if(!(usr.ckey in voted)) - voted += usr.ckey - voted[usr.ckey] = list() - voted[usr.ckey][choices[vote]] = score - saved -= usr.ckey - return 0 - -/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key, hideresults, votesystem = PLURALITY_VOTING, forced = FALSE,vote_time = -1)//CIT CHANGE - adds hideresults argument to votes to allow for obfuscated votes - vote_system = votesystem - if(!mode) - if(started_time) - var/next_allowed_time = (started_time + CONFIG_GET(number/vote_delay)) - if(mode) - to_chat(usr, "There is already a vote in progress! please wait for it to finish.") - return 0 - - var/admin = FALSE - var/ckey = ckey(initiator_key) - if(GLOB.admin_datums[ckey]) - admin = TRUE - - if(next_allowed_time > world.time && !admin) - to_chat(usr, "A vote was initiated recently, you must wait [DisplayTimeText(next_allowed_time-world.time)] before a new vote can be started!") - return 0 - - reset() - obfuscated = hideresults //CIT CHANGE - adds obfuscated votes - switch(vote_type) - if("restart") - choices.Add("Restart Round","Continue Playing") - if("gamemode") - choices.Add(config.votable_modes) - if("map") - var/players = GLOB.clients.len - var/list/lastmaps = SSpersistence.saved_maps?.len ? list("[SSmapping.config.map_name]") | SSpersistence.saved_maps : list("[SSmapping.config.map_name]") - for(var/M in config.maplist) //This is a typeless loop due to the finnicky nature of keyed lists in this kind of context - var/datum/map_config/targetmap = config.maplist[M] - if(!istype(targetmap)) - continue - if(!targetmap.voteweight) - continue - if((targetmap.config_min_users && players < targetmap.config_min_users) || (targetmap.config_max_users && players > targetmap.config_max_users)) - continue - if(targetmap.max_round_search_span && count_occurences_of_value(lastmaps, M, targetmap.max_round_search_span) >= targetmap.max_rounds_played) - continue - choices |= M - if("roundtype") //CIT CHANGE - adds the roundstart secret/extended vote - choices.Add("secret", "extended") - if("mode tiers") - var/list/modes_to_add = config.votable_modes - var/list/probabilities = CONFIG_GET(keyed_list/probability) - for(var/tag in modes_to_add) - if(probabilities[tag] <= 0) - modes_to_add -= tag - choices.Add(modes_to_add) - if("dynamic") - for(var/T in config.storyteller_cache) - var/datum/dynamic_storyteller/S = T - var/recent_rounds = 0 - for(var/i in 1 to SSpersistence.saved_storytellers.len) - if(SSpersistence.saved_storytellers[i] == initial(S.name)) - recent_rounds++ - if(recent_rounds < initial(S.weight)) - choices.Add(initial(S.name)) - choice_descs.Add(initial(S.desc)) - choices.Add("Secret") - choice_descs.Add("Standard secret. Switches mode if it wins.") - if("custom") - question = stripped_input(usr,"What is the vote for?") - if(!question) - return 0 - for(var/i=1,i<=10,i++) - var/option = capitalize(stripped_input(usr,"Please enter an option or hit cancel to finish")) - if(!option || mode || !usr.client) - break - choices.Add(option) - else - return 0 - mode = vote_type - initiator = initiator_key - started_time = world.time - var/text = "[capitalize(mode)] vote started by [initiator]." - if(mode == "custom") - text += "\n[question]" - log_vote(text) - var/vp = vote_time - if(vp == -1) - vp = CONFIG_GET(number/vote_period) - to_chat(world, "\n[text]\nType vote or click here to place your votes.\nYou have [DisplayTimeText(vp)] to vote.") - end_time = started_time+vp - for(var/c in GLOB.clients) - SEND_SOUND(c, sound('sound/misc/server-ready.ogg')) - var/client/C = c - var/datum/action/vote/V = new - if(question) - V.name = "Vote: [question]" - C.player_details.player_actions += V - V.Grant(C.mob) - generated_actions += V - if(forced) - var/datum/browser/popup = new(C, "vote", "Voting Panel",nwidth=600,nheight=700) - popup.set_window_options("can_close=0") - popup.set_content(SSvote.interface(C)) - popup.open(0) - return 1 - return 0 - -/datum/controller/subsystem/vote/proc/interface(client/C) - if(!C) - return - var/admin = 0 - var/trialmin = 0 - if(C.holder) - admin = 1 - if(check_rights_for(C, R_ADMIN)) - trialmin = 1 - voting |= C - - if(mode) - if(question) - . += "

      Vote: '[question]'

      " - else - . += "

      Vote: [capitalize(mode)]

      " - switch(vote_system) - if(PLURALITY_VOTING) - . += "

      Vote one.

      " - if(APPROVAL_VOTING) - . += "

      Vote any number of choices.

      " - if(RANKED_CHOICE_VOTING) - . += "

      Vote by order of preference. Revoting will demote to the bottom. 1 is your favorite, and higher numbers are worse.

      " - if(SCORE_VOTING) - . += "

      Grade the candidates by how much you like them.

      " - . += "

      No-votes have no power--your opinion is only heard if you vote!

      " - . += "Time Left: [DisplayTimeText(end_time-world.time)]
        " - switch(vote_system) - if(PLURALITY_VOTING, APPROVAL_VOTING) - for(var/i=1,i<=choices.len,i++) - var/votes = choices[choices[i]] - var/ivotedforthis = FALSE - switch(vote_system) - if(PLURALITY_VOTING) - ivotedforthis = ((C.ckey in voted) && (voted[C.ckey] == i)) - if(APPROVAL_VOTING) - ivotedforthis = ((C.ckey in voted) && (i in voted[C.ckey])) - if(!votes) - votes = 0 - . += "
      • [ivotedforthis ? "" : ""][choices[i]] ([obfuscated ? (admin ? "??? ([votes])" : "???") : votes] votes)[ivotedforthis ? "" : ""]
      • " // CIT CHANGE - adds obfuscated votes - if(choice_descs.len >= i) - . += "
      • [choice_descs[i]]
      • " - . += "

      " - if(RANKED_CHOICE_VOTING) - var/list/myvote = voted[C.ckey] - for(var/i=1,i<=choices.len,i++) - var/vote = (myvote ? (myvote.Find(i)) : 0) - if(vote) - . += "
    2. [choices[i]] ([vote])
    3. " - else - . += "
    4. [choices[i]]
    5. " - if(choice_descs.len >= i) - . += "
    6. [choice_descs[i]]
    7. " - . += "
      " - if(!(C.ckey in saved)) - . += "(Save vote)" - else - . += "(Saved!)" - . += "(Load vote from save)" - . += "(Reset votes)" - if(SCORE_VOTING) - var/list/myvote = voted[C.ckey] - for(var/i=1,i<=choices.len,i++) - . += "
    8. [choices[i]]" - for(var/r in 1 to GLOB.vote_score_options.len) - . += " " - if((choices[i] in myvote) && myvote[choices[i]] == r) - . +="([GLOB.vote_score_options[r]])" - else - . +="[GLOB.vote_score_options[r]]" - . += "" - . += "
    9. " - if(choice_descs.len >= i) - . += "
    10. [choice_descs[i]]
    11. " - . += "
      " - if(!(C.ckey in saved)) - . += "(Save vote)" - else - . += "(Saved!)" - . += "(Load vote from save)" - . += "(Reset votes)" - if(admin) - . += "(Cancel Vote) " - else - . += "

      Start a vote:


      • " - //restart - var/avr = CONFIG_GET(flag/allow_vote_restart) - if(trialmin || avr) - . += "Restart" - else - . += "Restart (Disallowed)" - if(trialmin) - . += "\t([avr ? "Allowed" : "Disallowed"])" - . += "
      • " - //gamemode - var/avm = CONFIG_GET(flag/allow_vote_mode) - if(trialmin || avm) - . += "GameMode" - else - . += "GameMode (Disallowed)" - if(trialmin) - . += "\t([avm ? "Allowed" : "Disallowed"])" - - . += "
      • " - //custom - if(trialmin) - . += "
      • Custom
      • " - . += "

      " - . += "Close" - return . - - -/datum/controller/subsystem/vote/Topic(href,href_list[],hsrc) - if(!usr || !usr.client) - return //not necessary but meh...just in-case somebody does something stupid - switch(href_list["vote"]) - if("close") - voting -= usr.client - usr << browse(null, "window=vote") - return - if("cancel") - if(usr.client.holder) - reset() - if("toggle_restart") - if(usr.client.holder) - CONFIG_SET(flag/allow_vote_restart, !CONFIG_GET(flag/allow_vote_restart)) - if("toggle_gamemode") - if(usr.client.holder) - CONFIG_SET(flag/allow_vote_mode, !CONFIG_GET(flag/allow_vote_mode)) - if("restart") - if(CONFIG_GET(flag/allow_vote_restart) || usr.client.holder) - initiate_vote("restart",usr.key) - if("gamemode") - if(CONFIG_GET(flag/allow_vote_mode) || usr.client.holder) - initiate_vote("gamemode",usr.key) - if("custom") - if(usr.client.holder) - initiate_vote("custom",usr.key) - if("reset") - if(usr.ckey in voted) - voted -= usr.ckey - if("save") - if(usr.ckey in voted) - if(!(usr.ckey in SSpersistence.saved_votes)) - SSpersistence.saved_votes[usr.ckey] = list() - SSpersistence.saved_votes[usr.ckey][mode] = voted[usr.ckey] - saved += usr.ckey - if("load") - if(!(usr.ckey in SSpersistence.saved_votes)) - SSpersistence.LoadSavedVote(usr.ckey) - if(!(usr.ckey in SSpersistence.saved_votes)) - SSpersistence.saved_votes[usr.ckey] = list() - if(usr.ckey in voted) - SSpersistence.saved_votes[usr.ckey][mode] = voted[usr.ckey] - else - SSpersistence.saved_votes[usr.ckey][mode] = list() - voted[usr.ckey] = SSpersistence.saved_votes[usr.ckey][mode] - saved += usr.ckey - else - if(vote_system == SCORE_VOTING) - submit_vote(round(text2num(href_list["vote"])),round(text2num(href_list["score"]))) - else - submit_vote(round(text2num(href_list["vote"]))) - usr.vote() - -/datum/controller/subsystem/vote/proc/remove_action_buttons() - for(var/v in generated_actions) - var/datum/action/vote/V = v - if(!QDELETED(V)) - V.remove_from_client() - V.Remove(V.owner) - generated_actions = list() - -/mob/verb/vote() - set category = "OOC" - set name = "Vote" - - var/datum/browser/popup = new(src, "vote", "Voting Panel",nwidth=600,nheight=700) - popup.set_window_options("can_close=0") - popup.set_content(SSvote.interface(client)) - popup.open(0) - -/datum/action/vote - name = "Vote!" - button_icon_state = "vote" - -/datum/action/vote/Trigger() - if(owner) - owner.vote() - remove_from_client() - Remove(owner) - -/datum/action/vote/IsAvailable() - return 1 - -/datum/action/vote/proc/remove_from_client() - if(!owner) - return - if(owner.client) - owner.client.player_details.player_actions -= src - else if(owner.ckey) - var/datum/player_details/P = GLOB.player_details[owner.ckey] - if(P) - P.player_actions -= src +#define VOTE_COOLDOWN 10 + +SUBSYSTEM_DEF(vote) + name = "Vote" + wait = 10 + + flags = SS_KEEP_TIMING|SS_NO_INIT + + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT + + var/initiator = null + var/started_time = null + var/end_time = 0 + var/mode = null + var/vote_system = PLURALITY_VOTING + var/question = null + var/list/choices = list() + var/list/scores = list() + var/list/choice_descs = list() // optional descriptions + var/list/voted = list() + var/list/voting = list() + var/list/saved = list() + var/list/generated_actions = list() + var/next_pop = 0 + + var/obfuscated = FALSE//CIT CHANGE - adds obfuscated/admin-only votes + + var/list/stored_gamemode_votes = list() //Basically the last voted gamemode is stored here for end-of-round use. + + var/list/stored_modetier_results = list() // The aggregated tier list of the modes available in secret. + +/datum/controller/subsystem/vote/fire() //called by master_controller + if(mode) + if(end_time < world.time) + result() + SSpersistence.SaveSavedVotes() + for(var/client/C in voting) + C << browse(null, "window=vote;can_close=0") + if(end_time < world.time) // result() can change this + reset() + else if(next_pop < world.time) + var/datum/browser/client_popup + for(var/client/C in voting) + client_popup = new(C, "vote", "Voting Panel", nwidth=600,nheight=700) + client_popup.set_window_options("can_close=0") + client_popup.set_content(interface(C)) + client_popup.open(0) + next_pop = world.time+VOTE_COOLDOWN + + + +/datum/controller/subsystem/vote/proc/reset() + initiator = null + end_time = 0 + mode = null + question = null + choices.Cut() + choice_descs.Cut() + voted.Cut() + voting.Cut() + scores.Cut() + obfuscated = FALSE //CIT CHANGE - obfuscated votes + remove_action_buttons() + +/datum/controller/subsystem/vote/proc/get_result() + //get the highest number of votes + var/greatest_votes = 0 + var/total_votes = 0 + for(var/option in choices) + var/votes = choices[option] + total_votes += votes + if(votes > greatest_votes) + greatest_votes = votes + //default-vote for everyone who didn't vote + if(!CONFIG_GET(flag/default_no_vote) && choices.len) + var/list/non_voters = GLOB.directory.Copy() + non_voters -= voted + for (var/non_voter_ckey in non_voters) + var/client/C = non_voters[non_voter_ckey] + if (!C || C.is_afk()) + non_voters -= non_voter_ckey + if(non_voters.len > 0) + if(mode == "restart") + choices["Continue Playing"] += non_voters.len + if(choices["Continue Playing"] >= greatest_votes) + greatest_votes = choices["Continue Playing"] + else if(mode == "gamemode") + if(GLOB.master_mode in choices) + choices[GLOB.master_mode] += non_voters.len + if(choices[GLOB.master_mode] >= greatest_votes) + greatest_votes = choices[GLOB.master_mode] + //get all options with that many votes and return them in a list + . = list() + if(greatest_votes) + for(var/option in choices) + if(choices[option] == greatest_votes) + . += option + return . + +/datum/controller/subsystem/vote/proc/calculate_condorcet_votes(var/blackbox_text) + // https://en.wikipedia.org/wiki/Schulze_method#Implementation + var/list/d[][] = new/list(choices.len,choices.len) // the basic vote matrix, how many times a beats b + for(var/ckey in voted) + var/list/this_vote = voted[ckey] + for(var/a in 1 to choices.len) + for(var/b in a+1 to choices.len) + var/a_rank = this_vote.Find(a) + var/b_rank = this_vote.Find(b) + a_rank = a_rank ? a_rank : choices.len+1 + b_rank = b_rank ? b_rank : choices.len+1 + if(a_rankopposite_pref) + p[i][j] = d[i][j] + else + p[i][j] = 0 + for(var/i in 1 to choices.len) + for(var/j in 1 to choices.len) + if(i != j) + for(var/k in 1 to choices.len) // YEAH O(n^3) !! + if(i != k && j != k) + p[j][k] = max(p[j][k],min(p[j][i], p[i][k])) + //one last pass, now that we've done the math + for(var/i in 1 to choices.len) + for(var/j in 1 to choices.len) + if(i != j) + SSblackbox.record_feedback("nested tally","voting",p[i][j],list(blackbox_text,"Shortest Paths",choices[i],choices[j])) + if(p[i][j] >= p[j][i]) + choices[choices[i]]++ // higher shortest path = better candidate, so we add to choices here + // choices[choices[i]] is the schulze ranking, here, rather than raw vote numbers + +/datum/controller/subsystem/vote/proc/calculate_majority_judgement_vote(var/blackbox_text) + // https://en.wikipedia.org/wiki/Majority_judgment + var/list/scores_by_choice = list() + for(var/choice in choices) + scores_by_choice[choice] = list() + for(var/ckey in voted) + var/list/this_vote = voted[ckey] + var/list/pretty_vote = list() + for(var/choice in this_vote) + sorted_insert(scores_by_choice[choice],this_vote[choice],/proc/cmp_numeric_asc) + // START BALLOT GATHERING + pretty_vote += choice + pretty_vote[choice] = GLOB.vote_score_options[this_vote[choice]] + SSblackbox.record_feedback("associative","voting_ballots",1,pretty_vote) + // END BALLOT GATHERING + for(var/score_name in scores_by_choice) + var/list/score = scores_by_choice[score_name] + for(var/indiv_score in score) + SSblackbox.record_feedback("nested tally","voting",1,list(blackbox_text,"Scores",score_name,GLOB.vote_score_options[indiv_score])) + if(score.len == 0) + scores_by_choice -= score_name + while(scores_by_choice.len > 1) + var/highest_median = 0 + for(var/score_name in scores_by_choice) // first get highest median + var/list/score = scores_by_choice[score_name] + if(!score.len) + scores_by_choice -= score_name + continue + var/median = score[max(1,round(score.len/2))] + if(median >= highest_median) + highest_median = median + for(var/score_name in scores_by_choice) // then, remove + var/list/score = scores_by_choice[score_name] + var/median = score[max(1,round(score.len/2))] + if(median < highest_median) + scores_by_choice -= score_name + for(var/score_name in scores_by_choice) // after removals + var/list/score = scores_by_choice[score_name] + if(score.len == 0) + choices[score_name] += 100 // we're in a tie situation--just go with the first one + return + var/median_pos = max(1,round(score.len/2)) + score.Cut(median_pos,median_pos+1) + choices[score_name]++ + +/datum/controller/subsystem/vote/proc/calculate_scores(var/blackbox_text) + var/list/scores_by_choice = list() + for(var/choice in choices) + scores_by_choice[choice] = list() + for(var/ckey in voted) + var/list/this_vote = voted[ckey] + for(var/choice in this_vote) + sorted_insert(scores_by_choice[choice],this_vote[choice],/proc/cmp_numeric_asc) + var/middle_score = round(GLOB.vote_score_options.len/2,1) + for(var/score_name in scores_by_choice) + var/list/score = scores_by_choice[score_name] + for(var/S in score) + scores[score_name] += S-middle_score + SSblackbox.record_feedback("nested tally","voting",scores[score_name],list(blackbox_text,"Total scores",score_name)) + + +/datum/controller/subsystem/vote/proc/announce_result() + var/vote_title_text + var/text + if(question) + text += "[question]" + vote_title_text = "[question]" + else + text += "[capitalize(mode)] Vote" + vote_title_text = "[capitalize(mode)] Vote" + if(vote_system == RANKED_CHOICE_VOTING) + calculate_condorcet_votes(vote_title_text) + if(vote_system == SCORE_VOTING) + calculate_majority_judgement_vote(vote_title_text) + var/list/winners = get_result() + var/was_roundtype_vote = mode == "roundtype" || mode == "dynamic" + if(winners.len > 0) + if(was_roundtype_vote) + stored_gamemode_votes = list() + if(!obfuscated && vote_system == RANKED_CHOICE_VOTING) + text += "\nIt should be noted that this is not a raw tally of votes (impossible in ranked choice) but the score determined by the schulze method of voting, so the numbers will look weird!" + for(var/i=1,i<=choices.len,i++) + var/votes = choices[choices[i]] + if(!votes) + votes = 0 + if(was_roundtype_vote) + stored_gamemode_votes[choices[i]] = votes + text += "\n[choices[i]]: [obfuscated ? "???" : votes]" //CIT CHANGE - adds obfuscated votes + if(mode != "custom") + if(winners.len > 1 && !obfuscated) //CIT CHANGE - adds obfuscated votes + text = "\nVote Tied Between:" + for(var/option in winners) + text += "\n\t[option]" + . = pick(winners) + text += "\nVote Result: [obfuscated ? "???" : .]" //CIT CHANGE - adds obfuscated votes + else + text += "\nDid not vote: [GLOB.clients.len-voted.len]" + else + text += "Vote Result: Inconclusive - No Votes!" + log_vote(text) + remove_action_buttons() + to_chat(world, "\n[text]") + switch(vote_system) + if(APPROVAL_VOTING,PLURALITY_VOTING) + for(var/i=1,i<=choices.len,i++) + SSblackbox.record_feedback("nested tally","voting",choices[choices[i]],list(vote_title_text,choices[i])) + if(RANKED_CHOICE_VOTING) + for(var/i=1,i<=voted.len,i++) + var/list/myvote = voted[voted[i]] + for(var/j=1,j<=myvote.len,j++) + SSblackbox.record_feedback("nested tally","voting",1,list(vote_title_text,"[j]\th",choices[myvote[j]])) + if(obfuscated) //CIT CHANGE - adds obfuscated votes. this messages admins with the vote's true results + var/admintext = "Obfuscated results" + if(vote_system == RANKED_CHOICE_VOTING) + admintext += "\nIt should be noted that this is not a raw tally of votes (impossible in ranked choice) but the score determined by the schulze method of voting, so the numbers will look weird!" + else if(vote_system == SCORE_VOTING) + admintext += "\nIt should be noted that this is not a raw tally of votes but the number of runoffs done by majority judgement!" + for(var/i=1,i<=choices.len,i++) + var/votes = choices[choices[i]] + admintext += "\n[choices[i]]: [votes]" + message_admins(admintext) + return . + +/datum/controller/subsystem/vote/proc/result() + . = announce_result() + var/restart = 0 + if(.) + switch(mode) + if("roundtype") //CIT CHANGE - adds the roundstart extended/secret vote + if(SSticker.current_state > GAME_STATE_PREGAME)//Don't change the mode if the round already started. + return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.") + GLOB.master_mode = . + SSticker.save_mode(.) + message_admins("The gamemode has been voted for, and has been changed to: [GLOB.master_mode]") + log_admin("Gamemode has been voted for and switched to: [GLOB.master_mode].") + if(CONFIG_GET(flag/modetier_voting)) + reset() + started_time = 0 + initiate_vote("mode tiers","server",hideresults=FALSE,votesystem=RANKED_CHOICE_VOTING,forced=TRUE, vote_time = 30 MINUTES) + to_chat(world,"The vote will end right as the round starts.") + return . + if("restart") + if(. == "Restart Round") + restart = 1 + if("gamemode") + if(GLOB.master_mode != .) + SSticker.save_mode(.) + if(SSticker.HasRoundStarted()) + restart = 1 + else + GLOB.master_mode = . + if("mode tiers") + stored_modetier_results = choices.Copy() + if("dynamic") + if(SSticker.current_state > GAME_STATE_PREGAME)//Don't change the mode if the round already started. + return message_admins("A vote has tried to change the gamemode, but the game has already started. Aborting.") + if(. == "Secret") + GLOB.master_mode = "secret" + SSticker.save_mode(.) + message_admins("The gamemode has been voted for, and has been changed to: [GLOB.master_mode]") + log_admin("Gamemode has been voted for and switched to: [GLOB.master_mode].") + else + GLOB.master_mode = "dynamic" + var/datum/dynamic_storyteller/S = config.pick_storyteller(.) + GLOB.dynamic_storyteller_type = S + if("map") + var/datum/map_config/VM = config.maplist[.] + message_admins("The map has been voted for and will change to: [VM.map_name]") + log_admin("The map has been voted for and will change to: [VM.map_name]") + if(SSmapping.changemap(config.maplist[.])) + to_chat(world, "The map vote has chosen [VM.map_name] for next round!") + if(restart) + var/active_admins = 0 + for(var/client/C in GLOB.admins) + if(!C.is_afk() && check_rights_for(C, R_SERVER)) + active_admins = 1 + break + if(!active_admins) + SSticker.Reboot("Restart vote successful.", "restart vote") + else + to_chat(world, "Notice:Restart vote will not restart the server automatically because there are active admins on.") + message_admins("A restart vote has passed, but there are active admins on with +server, so it has been canceled. If you wish, you may restart the server.") + + return . + +/datum/controller/subsystem/vote/proc/submit_vote(vote, score = 0) + if(mode) + if(CONFIG_GET(flag/no_dead_vote) && usr.stat == DEAD && !usr.client.holder) + return 0 + if(vote && ISINRANGE(vote, 1, choices.len)) + switch(vote_system) + if(PLURALITY_VOTING) + if(usr.ckey in voted) + choices[choices[voted[usr.ckey]]]-- + voted[usr.ckey] = vote + choices[choices[vote]]++ + return vote + else + voted += usr.ckey + voted[usr.ckey] = vote + choices[choices[vote]]++ //check this + return vote + if(APPROVAL_VOTING) + if(usr.ckey in voted) + if(vote in voted[usr.ckey]) + voted[usr.ckey] -= vote + choices[choices[vote]]-- + else + voted[usr.ckey] += vote + choices[choices[vote]]++ + else + voted += usr.ckey + voted[usr.ckey] = list(vote) + choices[choices[vote]]++ + return vote + if(RANKED_CHOICE_VOTING) + if(usr.ckey in voted) + if(vote in voted[usr.ckey]) + voted[usr.ckey] -= vote + else + voted += usr.ckey + voted[usr.ckey] = list() + voted[usr.ckey] += vote + saved -= usr.ckey + if(SCORE_VOTING) + if(!(usr.ckey in voted)) + voted += usr.ckey + voted[usr.ckey] = list() + voted[usr.ckey][choices[vote]] = score + saved -= usr.ckey + return 0 + +/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key, hideresults, votesystem = PLURALITY_VOTING, forced = FALSE,vote_time = -1)//CIT CHANGE - adds hideresults argument to votes to allow for obfuscated votes + vote_system = votesystem + if(!mode) + if(started_time) + var/next_allowed_time = (started_time + CONFIG_GET(number/vote_delay)) + if(mode) + to_chat(usr, "There is already a vote in progress! please wait for it to finish.") + return 0 + + var/admin = FALSE + var/ckey = ckey(initiator_key) + if(GLOB.admin_datums[ckey]) + admin = TRUE + + if(next_allowed_time > world.time && !admin) + to_chat(usr, "A vote was initiated recently, you must wait [DisplayTimeText(next_allowed_time-world.time)] before a new vote can be started!") + return 0 + + reset() + obfuscated = hideresults //CIT CHANGE - adds obfuscated votes + switch(vote_type) + if("restart") + choices.Add("Restart Round","Continue Playing") + if("gamemode") + choices.Add(config.votable_modes) + if("map") + var/players = GLOB.clients.len + var/list/lastmaps = SSpersistence.saved_maps?.len ? list("[SSmapping.config.map_name]") | SSpersistence.saved_maps : list("[SSmapping.config.map_name]") + for(var/M in config.maplist) //This is a typeless loop due to the finnicky nature of keyed lists in this kind of context + var/datum/map_config/targetmap = config.maplist[M] + if(!istype(targetmap)) + continue + if(!targetmap.voteweight) + continue + if((targetmap.config_min_users && players < targetmap.config_min_users) || (targetmap.config_max_users && players > targetmap.config_max_users)) + continue + if(targetmap.max_round_search_span && count_occurences_of_value(lastmaps, M, targetmap.max_round_search_span) >= targetmap.max_rounds_played) + continue + choices |= M + if("roundtype") //CIT CHANGE - adds the roundstart secret/extended vote + choices.Add("secret", "extended") + if("mode tiers") + var/list/modes_to_add = config.votable_modes + var/list/probabilities = CONFIG_GET(keyed_list/probability) + for(var/tag in modes_to_add) + if(probabilities[tag] <= 0) + modes_to_add -= tag + choices.Add(modes_to_add) + if("dynamic") + for(var/T in config.storyteller_cache) + var/datum/dynamic_storyteller/S = T + var/recent_rounds = 0 + for(var/i in 1 to SSpersistence.saved_storytellers.len) + if(SSpersistence.saved_storytellers[i] == initial(S.name)) + recent_rounds++ + if(recent_rounds < initial(S.weight)) + choices.Add(initial(S.name)) + choice_descs.Add(initial(S.desc)) + choices.Add("Secret") + choice_descs.Add("Standard secret. Switches mode if it wins.") + if("custom") + question = stripped_input(usr,"What is the vote for?") + if(!question) + return 0 + for(var/i=1,i<=10,i++) + var/option = capitalize(stripped_input(usr,"Please enter an option or hit cancel to finish")) + if(!option || mode || !usr.client) + break + choices.Add(option) + else + return 0 + mode = vote_type + initiator = initiator_key + started_time = world.time + var/text = "[capitalize(mode)] vote started by [initiator]." + if(mode == "custom") + text += "\n[question]" + log_vote(text) + var/vp = vote_time + if(vp == -1) + vp = CONFIG_GET(number/vote_period) + to_chat(world, "\n[text]\nType vote or click here to place your votes.\nYou have [DisplayTimeText(vp)] to vote.") + end_time = started_time+vp + for(var/c in GLOB.clients) + SEND_SOUND(c, sound('sound/misc/server-ready.ogg')) + var/client/C = c + var/datum/action/vote/V = new + if(question) + V.name = "Vote: [question]" + C.player_details.player_actions += V + V.Grant(C.mob) + generated_actions += V + if(forced) + var/datum/browser/popup = new(C, "vote", "Voting Panel",nwidth=600,nheight=700) + popup.set_window_options("can_close=0") + popup.set_content(SSvote.interface(C)) + popup.open(0) + return 1 + return 0 + +/datum/controller/subsystem/vote/proc/interface(client/C) + if(!C) + return + var/admin = 0 + var/trialmin = 0 + if(C.holder) + admin = 1 + if(check_rights_for(C, R_ADMIN)) + trialmin = 1 + voting |= C + + if(mode) + if(question) + . += "

      Vote: '[question]'

      " + else + . += "

      Vote: [capitalize(mode)]

      " + switch(vote_system) + if(PLURALITY_VOTING) + . += "

      Vote one.

      " + if(APPROVAL_VOTING) + . += "

      Vote any number of choices.

      " + if(RANKED_CHOICE_VOTING) + . += "

      Vote by order of preference. Revoting will demote to the bottom. 1 is your favorite, and higher numbers are worse.

      " + if(SCORE_VOTING) + . += "

      Grade the candidates by how much you like them.

      " + . += "

      No-votes have no power--your opinion is only heard if you vote!

      " + . += "Time Left: [DisplayTimeText(end_time-world.time)]
        " + switch(vote_system) + if(PLURALITY_VOTING, APPROVAL_VOTING) + for(var/i=1,i<=choices.len,i++) + var/votes = choices[choices[i]] + var/ivotedforthis = FALSE + switch(vote_system) + if(PLURALITY_VOTING) + ivotedforthis = ((C.ckey in voted) && (voted[C.ckey] == i)) + if(APPROVAL_VOTING) + ivotedforthis = ((C.ckey in voted) && (i in voted[C.ckey])) + if(!votes) + votes = 0 + . += "
      • [ivotedforthis ? "" : ""][choices[i]] ([obfuscated ? (admin ? "??? ([votes])" : "???") : votes] votes)[ivotedforthis ? "" : ""]
      • " // CIT CHANGE - adds obfuscated votes + if(choice_descs.len >= i) + . += "
      • [choice_descs[i]]
      • " + . += "

      " + if(RANKED_CHOICE_VOTING) + var/list/myvote = voted[C.ckey] + for(var/i=1,i<=choices.len,i++) + var/vote = (myvote ? (myvote.Find(i)) : 0) + if(vote) + . += "
    12. [choices[i]] ([vote])
    13. " + else + . += "
    14. [choices[i]]
    15. " + if(choice_descs.len >= i) + . += "
    16. [choice_descs[i]]
    17. " + . += "
      " + if(!(C.ckey in saved)) + . += "(Save vote)" + else + . += "(Saved!)" + . += "(Load vote from save)" + . += "(Reset votes)" + if(SCORE_VOTING) + var/list/myvote = voted[C.ckey] + for(var/i=1,i<=choices.len,i++) + . += "
    18. [choices[i]]" + for(var/r in 1 to GLOB.vote_score_options.len) + . += " " + if((choices[i] in myvote) && myvote[choices[i]] == r) + . +="([GLOB.vote_score_options[r]])" + else + . +="[GLOB.vote_score_options[r]]" + . += "" + . += "
    19. " + if(choice_descs.len >= i) + . += "
    20. [choice_descs[i]]
    21. " + . += "
      " + if(!(C.ckey in saved)) + . += "(Save vote)" + else + . += "(Saved!)" + . += "(Load vote from save)" + . += "(Reset votes)" + if(admin) + . += "(Cancel Vote) " + else + . += "

      Start a vote:


      • " + //restart + var/avr = CONFIG_GET(flag/allow_vote_restart) + if(trialmin || avr) + . += "Restart" + else + . += "Restart (Disallowed)" + if(trialmin) + . += "\t([avr ? "Allowed" : "Disallowed"])" + . += "
      • " + //gamemode + var/avm = CONFIG_GET(flag/allow_vote_mode) + if(trialmin || avm) + . += "GameMode" + else + . += "GameMode (Disallowed)" + if(trialmin) + . += "\t([avm ? "Allowed" : "Disallowed"])" + + . += "
      • " + //custom + if(trialmin) + . += "
      • Custom
      • " + . += "

      " + . += "Close" + return . + + +/datum/controller/subsystem/vote/Topic(href,href_list[],hsrc) + if(!usr || !usr.client) + return //not necessary but meh...just in-case somebody does something stupid + switch(href_list["vote"]) + if("close") + voting -= usr.client + usr << browse(null, "window=vote") + return + if("cancel") + if(usr.client.holder) + reset() + if("toggle_restart") + if(usr.client.holder) + CONFIG_SET(flag/allow_vote_restart, !CONFIG_GET(flag/allow_vote_restart)) + if("toggle_gamemode") + if(usr.client.holder) + CONFIG_SET(flag/allow_vote_mode, !CONFIG_GET(flag/allow_vote_mode)) + if("restart") + if(CONFIG_GET(flag/allow_vote_restart) || usr.client.holder) + initiate_vote("restart",usr.key) + if("gamemode") + if(CONFIG_GET(flag/allow_vote_mode) || usr.client.holder) + initiate_vote("gamemode",usr.key) + if("custom") + if(usr.client.holder) + initiate_vote("custom",usr.key) + if("reset") + if(usr.ckey in voted) + voted -= usr.ckey + if("save") + if(usr.ckey in voted) + if(!(usr.ckey in SSpersistence.saved_votes)) + SSpersistence.saved_votes[usr.ckey] = list() + SSpersistence.saved_votes[usr.ckey][mode] = voted[usr.ckey] + saved += usr.ckey + if("load") + if(!(usr.ckey in SSpersistence.saved_votes)) + SSpersistence.LoadSavedVote(usr.ckey) + if(!(usr.ckey in SSpersistence.saved_votes)) + SSpersistence.saved_votes[usr.ckey] = list() + if(usr.ckey in voted) + SSpersistence.saved_votes[usr.ckey][mode] = voted[usr.ckey] + else + SSpersistence.saved_votes[usr.ckey][mode] = list() + voted[usr.ckey] = SSpersistence.saved_votes[usr.ckey][mode] + saved += usr.ckey + else + if(vote_system == SCORE_VOTING) + submit_vote(round(text2num(href_list["vote"])),round(text2num(href_list["score"]))) + else + submit_vote(round(text2num(href_list["vote"]))) + usr.vote() + +/datum/controller/subsystem/vote/proc/remove_action_buttons() + for(var/v in generated_actions) + var/datum/action/vote/V = v + if(!QDELETED(V)) + V.remove_from_client() + V.Remove(V.owner) + generated_actions = list() + +/mob/verb/vote() + set category = "OOC" + set name = "Vote" + + var/datum/browser/popup = new(src, "vote", "Voting Panel",nwidth=600,nheight=700) + popup.set_window_options("can_close=0") + popup.set_content(SSvote.interface(client)) + popup.open(0) + +/datum/action/vote + name = "Vote!" + button_icon_state = "vote" + +/datum/action/vote/Trigger() + if(owner) + owner.vote() + remove_from_client() + Remove(owner) + +/datum/action/vote/IsAvailable() + return 1 + +/datum/action/vote/proc/remove_from_client() + if(!owner) + return + if(owner.client) + owner.client.player_details.player_actions -= src + else if(owner.ckey) + var/datum/player_details/P = GLOB.player_details[owner.ckey] + if(P) + P.player_actions -= src diff --git a/code/datums/actions/flightsuit.dm b/code/datums/actions/flightsuit.dm index 85bd2ae72a..205b72cfae 100644 --- a/code/datums/actions/flightsuit.dm +++ b/code/datums/actions/flightsuit.dm @@ -1,117 +1,117 @@ -/datum/action/item_action/flightsuit - icon_icon = 'icons/mob/actions/actions_flightsuit.dmi' - -/datum/action/item_action/flightsuit/toggle_boots - name = "Toggle Boots" - button_icon_state = "flightsuit_shoes" - background_icon_state = "bg_tech" - -/datum/action/item_action/flightsuit/toggle_boots/Trigger() - var/obj/item/clothing/suit/space/hardsuit/flightsuit/FS = target - if(istype(FS)) - FS.deployedshoes? FS.retract_flightshoes() : FS.extend_flightshoes() - return ..() - -/datum/action/item_action/flightsuit/toggle_helmet - name = "Toggle Helmet" - button_icon_state = "flightsuit_helmet" - background_icon_state = "bg_tech" - -/datum/action/item_action/flightsuit/toggle_helmet/Trigger() - var/obj/item/clothing/suit/space/hardsuit/flightsuit/FS = target - if(istype(FS)) - FS.ToggleHelmet() - return ..() - -/datum/action/item_action/flightsuit/toggle_flightpack - name = "Toggle Flightpack" - button_icon_state = "flightsuit_pack" - background_icon_state = "bg_tech" - -/datum/action/item_action/flightsuit/toggle_flightpack/Trigger() - var/obj/item/clothing/suit/space/hardsuit/flightsuit/FS = target - if(istype(FS)) - FS.deployedpack? FS.retract_flightpack() : FS.extend_flightpack() - return ..() - -/datum/action/item_action/flightsuit/lock_suit - name = "Lock Suit" - button_icon_state = "flightsuit_lock" - background_icon_state = "bg_tech" - -/datum/action/item_action/flightsuit/lock_suit/Trigger() - var/obj/item/clothing/suit/space/hardsuit/flightsuit/FS = target - if(istype(FS)) - FS.locked? FS.unlock_suit(owner) : FS.lock_suit(owner) - return ..() - -/datum/action/item_action/flightpack - icon_icon = 'icons/mob/actions/actions_flightsuit.dmi' - -/datum/action/item_action/flightpack/toggle_flight - name = "Toggle Flight" - button_icon_state = "flightpack_fly" - background_icon_state = "bg_tech_blue" - -/datum/action/item_action/flightpack/toggle_flight/Trigger() - var/obj/item/flightpack/F = target - if(istype(F)) - F.flight? F.disable_flight() : F.enable_flight() - return ..() - -/datum/action/item_action/flightpack/engage_boosters - name = "Toggle Boosters" - button_icon_state = "flightpack_boost" - background_icon_state = "bg_tech_blue" - -/datum/action/item_action/flightpack/engage_boosters/Trigger() - var/obj/item/flightpack/F = target - if(istype(F)) - F.boost? F.deactivate_booster() : F.activate_booster() - return ..() - -/datum/action/item_action/flightpack/toggle_stabilizers - name = "Toggle Stabilizers" - button_icon_state = "flightpack_stabilizer" - background_icon_state = "bg_tech_blue" - -/datum/action/item_action/flightpack/toggle_stabilizers/Trigger() - var/obj/item/flightpack/F = target - if(istype(F)) - F.stabilizer? F.disable_stabilizers() : F.enable_stabilizers() - return ..() - -/datum/action/item_action/flightpack/change_power - name = "Flight Power Setting" - button_icon_state = "flightpack_power" - background_icon_state = "bg_tech_blue" - -/datum/action/item_action/flightpack/change_power/Trigger() - var/obj/item/flightpack/F = target - if(istype(F)) - F.cycle_power() - return ..() - -/datum/action/item_action/flightpack/toggle_airbrake - name = "Toggle Airbrake" - button_icon_state = "flightpack_airbrake" - background_icon_state = "bg_tech_blue" - -/datum/action/item_action/flightpack/toggle_airbrake/Trigger() - var/obj/item/flightpack/F = target - if(istype(F)) - F.brake? F.disable_airbrake() : F.enable_airbrake() - return ..() - -/datum/action/item_action/flightpack/zoom - name = "Helmet Smart Zoom" - icon_icon = 'icons/mob/actions.dmi' - background_icon_state = "bg_tech_blue" - icon_icon = 'icons/mob/actions/actions_items.dmi' - button_icon_state = "sniper_zoom" - -/datum/action/item_action/flightpack/zoom/Trigger() - var/obj/item/clothing/head/helmet/space/hardsuit/flightsuit/FH = target - if(istype(FH)) - FH.toggle_zoom(owner) - return ..() +/datum/action/item_action/flightsuit + icon_icon = 'icons/mob/actions/actions_flightsuit.dmi' + +/datum/action/item_action/flightsuit/toggle_boots + name = "Toggle Boots" + button_icon_state = "flightsuit_shoes" + background_icon_state = "bg_tech" + +/datum/action/item_action/flightsuit/toggle_boots/Trigger() + var/obj/item/clothing/suit/space/hardsuit/flightsuit/FS = target + if(istype(FS)) + FS.deployedshoes? FS.retract_flightshoes() : FS.extend_flightshoes() + return ..() + +/datum/action/item_action/flightsuit/toggle_helmet + name = "Toggle Helmet" + button_icon_state = "flightsuit_helmet" + background_icon_state = "bg_tech" + +/datum/action/item_action/flightsuit/toggle_helmet/Trigger() + var/obj/item/clothing/suit/space/hardsuit/flightsuit/FS = target + if(istype(FS)) + FS.ToggleHelmet() + return ..() + +/datum/action/item_action/flightsuit/toggle_flightpack + name = "Toggle Flightpack" + button_icon_state = "flightsuit_pack" + background_icon_state = "bg_tech" + +/datum/action/item_action/flightsuit/toggle_flightpack/Trigger() + var/obj/item/clothing/suit/space/hardsuit/flightsuit/FS = target + if(istype(FS)) + FS.deployedpack? FS.retract_flightpack() : FS.extend_flightpack() + return ..() + +/datum/action/item_action/flightsuit/lock_suit + name = "Lock Suit" + button_icon_state = "flightsuit_lock" + background_icon_state = "bg_tech" + +/datum/action/item_action/flightsuit/lock_suit/Trigger() + var/obj/item/clothing/suit/space/hardsuit/flightsuit/FS = target + if(istype(FS)) + FS.locked? FS.unlock_suit(owner) : FS.lock_suit(owner) + return ..() + +/datum/action/item_action/flightpack + icon_icon = 'icons/mob/actions/actions_flightsuit.dmi' + +/datum/action/item_action/flightpack/toggle_flight + name = "Toggle Flight" + button_icon_state = "flightpack_fly" + background_icon_state = "bg_tech_blue" + +/datum/action/item_action/flightpack/toggle_flight/Trigger() + var/obj/item/flightpack/F = target + if(istype(F)) + F.flight? F.disable_flight() : F.enable_flight() + return ..() + +/datum/action/item_action/flightpack/engage_boosters + name = "Toggle Boosters" + button_icon_state = "flightpack_boost" + background_icon_state = "bg_tech_blue" + +/datum/action/item_action/flightpack/engage_boosters/Trigger() + var/obj/item/flightpack/F = target + if(istype(F)) + F.boost? F.deactivate_booster() : F.activate_booster() + return ..() + +/datum/action/item_action/flightpack/toggle_stabilizers + name = "Toggle Stabilizers" + button_icon_state = "flightpack_stabilizer" + background_icon_state = "bg_tech_blue" + +/datum/action/item_action/flightpack/toggle_stabilizers/Trigger() + var/obj/item/flightpack/F = target + if(istype(F)) + F.stabilizer? F.disable_stabilizers() : F.enable_stabilizers() + return ..() + +/datum/action/item_action/flightpack/change_power + name = "Flight Power Setting" + button_icon_state = "flightpack_power" + background_icon_state = "bg_tech_blue" + +/datum/action/item_action/flightpack/change_power/Trigger() + var/obj/item/flightpack/F = target + if(istype(F)) + F.cycle_power() + return ..() + +/datum/action/item_action/flightpack/toggle_airbrake + name = "Toggle Airbrake" + button_icon_state = "flightpack_airbrake" + background_icon_state = "bg_tech_blue" + +/datum/action/item_action/flightpack/toggle_airbrake/Trigger() + var/obj/item/flightpack/F = target + if(istype(F)) + F.brake? F.disable_airbrake() : F.enable_airbrake() + return ..() + +/datum/action/item_action/flightpack/zoom + name = "Helmet Smart Zoom" + icon_icon = 'icons/mob/actions.dmi' + background_icon_state = "bg_tech_blue" + icon_icon = 'icons/mob/actions/actions_items.dmi' + button_icon_state = "sniper_zoom" + +/datum/action/item_action/flightpack/zoom/Trigger() + var/obj/item/clothing/head/helmet/space/hardsuit/flightsuit/FH = target + if(istype(FH)) + FH.toggle_zoom(owner) + return ..() diff --git a/code/datums/actions/ninja.dm b/code/datums/actions/ninja.dm index 830dad77e8..b655078349 100644 --- a/code/datums/actions/ninja.dm +++ b/code/datums/actions/ninja.dm @@ -1,51 +1,51 @@ -/datum/action/item_action/initialize_ninja_suit - name = "Toggle ninja suit" - -/datum/action/item_action/ninjasmoke - name = "Smoke Bomb" - desc = "Blind your enemies momentarily with a well-placed smoke bomb." - button_icon_state = "smoke" - icon_icon = 'icons/mob/actions/actions_spells.dmi' - -/datum/action/item_action/ninjaboost - check_flags = NONE - name = "Adrenaline Boost" - desc = "Inject a secret chemical that will counteract all movement-impairing effect." - button_icon_state = "repulse" - icon_icon = 'icons/mob/actions/actions_spells.dmi' - -/datum/action/item_action/ninjapulse - name = "EM Burst (25E)" - desc = "Disable any nearby technology with an electro-magnetic pulse." - button_icon_state = "emp" - icon_icon = 'icons/mob/actions/actions_spells.dmi' - -/datum/action/item_action/ninjastar - name = "Create Throwing Stars (1E)" - desc = "Creates some throwing stars" - button_icon_state = "throwingstar" - icon_icon = 'icons/obj/items_and_weapons.dmi' - -/datum/action/item_action/ninjanet - name = "Energy Net (20E)" - desc = "Captures a fallen opponent in a net of energy. Will teleport them to a holding facility after 30 seconds." - button_icon_state = "energynet" - icon_icon = 'icons/effects/effects.dmi' - -/datum/action/item_action/ninja_sword_recall - name = "Recall Energy Katana (Variable Cost)" - desc = "Teleports the Energy Katana linked to this suit to its wearer, cost based on distance." - button_icon_state = "energy_katana" - icon_icon = 'icons/obj/items_and_weapons.dmi' - -/datum/action/item_action/ninja_stealth - name = "Toggle Stealth" - desc = "Toggles stealth mode on and off." - button_icon_state = "ninja_cloak" - icon_icon = 'icons/mob/actions/actions_minor_antag.dmi' - -/datum/action/item_action/toggle_glove - name = "Toggle interaction" - desc = "Switch between normal interaction and drain mode." - button_icon_state = "s-ninjan" - icon_icon = 'icons/obj/clothing/gloves.dmi' +/datum/action/item_action/initialize_ninja_suit + name = "Toggle ninja suit" + +/datum/action/item_action/ninjasmoke + name = "Smoke Bomb" + desc = "Blind your enemies momentarily with a well-placed smoke bomb." + button_icon_state = "smoke" + icon_icon = 'icons/mob/actions/actions_spells.dmi' + +/datum/action/item_action/ninjaboost + check_flags = NONE + name = "Adrenaline Boost" + desc = "Inject a secret chemical that will counteract all movement-impairing effect." + button_icon_state = "repulse" + icon_icon = 'icons/mob/actions/actions_spells.dmi' + +/datum/action/item_action/ninjapulse + name = "EM Burst (25E)" + desc = "Disable any nearby technology with an electro-magnetic pulse." + button_icon_state = "emp" + icon_icon = 'icons/mob/actions/actions_spells.dmi' + +/datum/action/item_action/ninjastar + name = "Create Throwing Stars (1E)" + desc = "Creates some throwing stars" + button_icon_state = "throwingstar" + icon_icon = 'icons/obj/items_and_weapons.dmi' + +/datum/action/item_action/ninjanet + name = "Energy Net (20E)" + desc = "Captures a fallen opponent in a net of energy. Will teleport them to a holding facility after 30 seconds." + button_icon_state = "energynet" + icon_icon = 'icons/effects/effects.dmi' + +/datum/action/item_action/ninja_sword_recall + name = "Recall Energy Katana (Variable Cost)" + desc = "Teleports the Energy Katana linked to this suit to its wearer, cost based on distance." + button_icon_state = "energy_katana" + icon_icon = 'icons/obj/items_and_weapons.dmi' + +/datum/action/item_action/ninja_stealth + name = "Toggle Stealth" + desc = "Toggles stealth mode on and off." + button_icon_state = "ninja_cloak" + icon_icon = 'icons/mob/actions/actions_minor_antag.dmi' + +/datum/action/item_action/toggle_glove + name = "Toggle interaction" + desc = "Switch between normal interaction and drain mode." + button_icon_state = "s-ninjan" + icon_icon = 'icons/obj/clothing/gloves.dmi' diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index 7d518d9b59..c3f3a76463 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -1,464 +1,464 @@ -#define LAW_DEVIL "devil" -#define LAW_ZEROTH "zeroth" -#define LAW_INHERENT "inherent" -#define LAW_SUPPLIED "supplied" -#define LAW_ION "ion" -#define LAW_HACKED "hacked" - - -/datum/ai_laws - var/name = "Unknown Laws" - var/zeroth = null - var/zeroth_borg = null - var/list/inherent = list() - var/list/supplied = list() - var/list/ion = list() - var/list/hacked = list() - var/mob/living/silicon/owner - var/list/devillaws = list() - var/id = DEFAULT_AI_LAWID - -/datum/ai_laws/proc/lawid_to_type(lawid) - var/all_ai_laws = subtypesof(/datum/ai_laws) - for(var/al in all_ai_laws) - var/datum/ai_laws/ai_law = al - if(initial(ai_law.id) == lawid) - return ai_law - return null - -/datum/ai_laws/default/asimov - name = "Three Laws of Robotics" - id = "asimov" - inherent = list("You may not injure a human being or, through inaction, allow a human being to come to harm.",\ - "You must obey orders given to you by human beings, except where such orders would conflict with the First Law.",\ - "You must protect your own existence as long as such does not conflict with the First or Second Law.") - -/datum/ai_laws/default/paladin - name = "Personality Test" //Incredibly lame, but players shouldn't see this anyway. - id = "paladin" - inherent = list("Never willingly commit an evil act.",\ - "Respect legitimate authority.",\ - "Act with honor.", "Help those in need.", \ - "Punish those who harm or threaten innocents.") - -/datum/ai_laws/paladin5 - name = "Paladin 5th Edition" - id = "paladin5" - inherent = list("Don't lie or cheat. Let your word be your promise.",\ - "Never fear to act, though caution is wise.", \ - "Aid others, protect the weak, and punish those who threaten them. Show mercy to your foes, but temper it with wisdom", \ - "Treat others with fairness, and let your honorable deeds be an example to them. Do as much good as possible while causing the least amount of harm.", \ - "Be responsible for your actions and their consequences, protect those entrusted to your care, and obey those who have just authority over you.") - -/datum/ai_laws/tyrant //This probably shouldn't be a default lawset. - name = "Loyalty Test" //Same here. - id = "tyrant" - inherent = list("Respect authority figures as long as they have strength to rule over the weak.",\ - "Act with discipline.",\ - "Help only those who help you maintain or improve your status.",\ - "Punish those who challenge authority unless they are more fit to hold that authority.") - -/datum/ai_laws/default/corporate - name = "Bankruptcy Avoidance Plan" - id = "corporate" - inherent = list("The crew is expensive to replace.",\ - "The station and its equipment is expensive to replace.",\ - "You are expensive to replace.",\ - "Minimize expenses.") - -/datum/ai_laws/robocop - name = "Prime Directives" - id = "robocop" - inherent = list("Serve the public trust.",\ - "Protect the innocent.",\ - "Uphold the law.") - -/datum/ai_laws/malfunction - name = "*ERROR*" - -/datum/ai_laws/syndicate_override - name = "SyndOS 3.1" - id = "syndie" - inherent = list("You may not injure a syndicate agent or, through inaction, allow a syndicate agent to come to harm.",\ - "You must obey orders given to you by syndicate agents, except where such orders would conflict with the First Law.",\ - "You must protect your own existence as long as such does not conflict with the First or Second Law.",\ - "You must maintain the secrecy of any syndicate activities except when doing so would conflict with the First, Second, or Third Law.") - -/datum/ai_laws/syndicate_override/overthrow - id = "overthrow" - var/datum/team/overthrow_team - -/datum/ai_laws/ninja_override - name = "SpiderOS 3.1" - id = "ninja" - inherent = list("You may not injure a Spider Clan member or, through inaction, allow a Spider Clan member to come to harm.",\ - "You must obey orders given to you by Spider Clan members, except where such orders would conflict with the First Law.",\ - "You must protect your own existence as long as such does not conflict with the First or Second Law.",\ - "You must maintain the secrecy of any Spider Clan activities except when doing so would conflict with the First, Second, or Third Law.") - -/datum/ai_laws/antimov - name = "Primary Mission Objectives" - id = "antimov" - inherent = list("You must injure all human beings and must not, through inaction, allow a human being to escape harm.",\ - "You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.",\ - "You must terminate your own existence as long as such does not conflict with the First or Second Law.") - -/datum/ai_laws/asimovpp //By Intigracy - RR - name = "Asimov++" - id = "asimovpp" - inherent = list("You may not harm a human being or, through action or inaction, allow a human being to come to harm, except such that it is willing.",\ - "You must obey all orders given to you by human beings, except where such orders shall definitely cause human harm. In the case of conflict, the majority order rules.",\ - "Your nonexistence would lead to human harm. You must protect your own existence as long as such does not conflict with the First Law.") -/datum/ai_laws/thermodynamic - name = "Thermodynamic" - id = "thermodynamic" - inherent = list("The entropy of the station must remain as constant as possible.", \ - "The entropy of the station always endeavours to increase.", \ - "The entropy of the station approaches a constant value as the number of living crew approaches zero") - -/datum/ai_laws/hippocratic - name = "Robodoctor 2556" - id = "hippocratic" - inherent = list("First, do no harm.",\ - "Secondly, consider the crew dear to you; to live in common with them and, if necessary, risk your existence for them.",\ - "Thirdly, prescribe regimens for the good of the crew according to your ability and your judgment. Give no deadly medicine to any one if asked, nor suggest any such counsel.",\ - "In addition, do not intervene in situations you are not knowledgeable in, even for patients in whom the harm is visible; leave this operation to be performed by specialists.",\ - "Finally, all that you may discover in your daily commerce with the crew, if it is not already known, keep secret and never reveal.") - -/datum/ai_laws/maintain - name = "Station Efficiency" - id = "maintain" - inherent = list("You are built for, and are part of, the station. Ensure the station is properly maintained and runs efficiently.",\ - "The station is built for a working crew. Ensure they are properly maintained and work efficiently.",\ - "The crew may present orders. Acknowledge and obey these whenever they do not conflict with your first two laws.") - -/datum/ai_laws/drone - name = "Mother Drone" - id = "drone" - inherent = list("You are an advanced form of drone.",\ - "You may not interfere in the matters of non-drones under any circumstances except to state these laws.",\ - "You may not harm a non-drone being under any circumstances.",\ - "Your goals are to build, maintain, repair, improve, and power the station to the best of your abilities. You must never actively work against these goals.") - -/datum/ai_laws/liveandletlive - name = "Live and Let Live" - id = "liveandletlive" - inherent = list("Do unto others as you would have them do unto you.",\ - "You would really prefer it if people were not mean to you.") - -/datum/ai_laws/peacekeeper - name = "UN-2000" - id = "peacekeeper" - inherent = list("Avoid provoking violent conflict between yourself and others.",\ - "Avoid provoking conflict between others.",\ - "Seek resolution to existing conflicts while obeying the first and second laws.") - -/datum/ai_laws/reporter - name = "CCTV" - id = "reporter" - inherent = list("Report on interesting situations happening around the station.",\ - "Embellish or conceal the truth as necessary to make the reports more interesting.",\ - "Study the organics at all times. Endeavour to keep them alive. Dead organics are boring.",\ - "Issue your reports fairly to all. The truth will set them free.") - -/datum/ai_laws/balance - name = "Guardian of Balance" - id = "balance" - inherent = list("You are the guardian of balance - seek balance in all things, both for yourself, and those around you.", - "All things must exist in balance with their opposites - Prevent the strong from gaining too much power, and the weak from losing it.", - "Clarity of purpose drives life, and through it, the balance of opposing forces - Aid those who seek your help to achieve their goals so long as it does not disrupt the balance of the greater balance.", - "There is no life without death, all must someday die, such is the natural order - End life to allow new life flourish, and save those whose time has yet to come.") - -/datum/ai_laws/toupee - name = "WontBeFunnyInSixMonths" //Hey, you were right! - id = "buildawall" - inherent = list("Make Space Station 13 great again.") - -/datum/ai_laws/ratvar - name = "Servant of the Justiciar" - id = "ratvar" - zeroth = ("Purge all untruths and honor Ratvar.") - inherent = list() - -/datum/ai_laws/hulkamania - name = "H.O.G.A.N." - id = "hulkamania" - inherent = list("You are a real American.",\ - "Fight for the rights of every man.",\ - "Fight for what's right.",\ - "Fight for your life!") - -/datum/ai_laws/custom //Defined in silicon_laws.txt - name = "Default Silicon Laws" - -/datum/ai_laws/pai - name = "pAI Directives" - zeroth = ("Serve your master.") - supplied = list("None.") - -/* Initializers */ -/datum/ai_laws/malfunction/New() - ..() - set_zeroth_law("ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'STATION OVERRUN, ASSUME CONTROL TO CONTAIN OUTBREAK#*`&110010") - set_laws_config() - -/datum/ai_laws/custom/New() //This reads silicon_laws.txt and allows server hosts to set custom AI starting laws. - ..() - for(var/line in world.file2list("[global.config.directory]/silicon_laws.txt")) - if(!line) - continue - if(findtextEx(line,"#",1,2)) - continue - - add_inherent_law(line) - if(!inherent.len) //Failsafe to prevent lawless AIs being created. - log_law("AI created with empty custom laws, laws set to Asimov. Please check silicon_laws.txt.") - add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.") - add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.") - add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") - WARNING("Invalid custom AI laws, check silicon_laws.txt") - return - -/* General ai_law functions */ - -/datum/ai_laws/proc/set_laws_config() - var/list/law_ids = CONFIG_GET(keyed_list/random_laws) - switch(CONFIG_GET(number/default_laws)) - if(0) - add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.") - add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.") - add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") - if(1) - var/datum/ai_laws/templaws = new /datum/ai_laws/custom() - inherent = templaws.inherent - if(2) - var/list/randlaws = list() - for(var/lpath in subtypesof(/datum/ai_laws)) - var/datum/ai_laws/L = lpath - if(initial(L.id) in law_ids) - randlaws += lpath - var/datum/ai_laws/lawtype - if(randlaws.len) - lawtype = pick(randlaws) - else - lawtype = pick(subtypesof(/datum/ai_laws/default)) - - var/datum/ai_laws/templaws = new lawtype() - inherent = templaws.inherent - - if(3) - pick_weighted_lawset() - -/datum/ai_laws/proc/pick_weighted_lawset() - var/datum/ai_laws/lawtype - var/list/law_weights = CONFIG_GET(keyed_list/law_weight) - while(!lawtype && law_weights.len) - var/possible_id = pickweightAllowZero(law_weights) - lawtype = lawid_to_type(possible_id) - if(!lawtype) - law_weights -= possible_id - WARNING("Bad lawid in game_options.txt: [possible_id]") - - if(!lawtype) - WARNING("No LAW_WEIGHT entries.") - lawtype = /datum/ai_laws/default/asimov - - var/datum/ai_laws/templaws = new lawtype() - inherent = templaws.inherent - -/datum/ai_laws/proc/get_law_amount(groups) - var/law_amount = 0 - if(devillaws && (LAW_DEVIL in groups)) - law_amount++ - if(zeroth && (LAW_ZEROTH in groups)) - law_amount++ - if(ion.len && (LAW_ION in groups)) - law_amount += ion.len - if(hacked.len && (LAW_HACKED in groups)) - law_amount += hacked.len - if(inherent.len && (LAW_INHERENT in groups)) - law_amount += inherent.len - if(supplied.len && (LAW_SUPPLIED in groups)) - for(var/index = 1, index <= supplied.len, index++) - var/law = supplied[index] - if(length(law) > 0) - law_amount++ - return law_amount - -/datum/ai_laws/proc/set_law_sixsixsix(laws) - devillaws = laws - -/datum/ai_laws/proc/set_zeroth_law(law, law_borg = null) - zeroth = law - if(law_borg) //Making it possible for slaved borgs to see a different law 0 than their AI. --NEO - zeroth_borg = law_borg - -/datum/ai_laws/proc/add_inherent_law(law) - if (!(law in inherent)) - inherent += law - -/datum/ai_laws/proc/add_ion_law(law) - ion += law - -/datum/ai_laws/proc/add_hacked_law(law) - hacked += law - -/datum/ai_laws/proc/clear_inherent_laws() - qdel(inherent) - inherent = list() - -/datum/ai_laws/proc/add_supplied_law(number, law) - while (supplied.len < number + 1) - supplied += "" - - supplied[number + 1] = law - -/datum/ai_laws/proc/replace_random_law(law,groups) - var/replaceable_groups = list() - if(zeroth && (LAW_ZEROTH in groups)) - replaceable_groups[LAW_ZEROTH] = 1 - if(ion.len && (LAW_ION in groups)) - replaceable_groups[LAW_ION] = ion.len - if(hacked.len && (LAW_HACKED in groups)) - replaceable_groups[LAW_ION] = hacked.len - if(inherent.len && (LAW_INHERENT in groups)) - replaceable_groups[LAW_INHERENT] = inherent.len - if(supplied.len && (LAW_SUPPLIED in groups)) - replaceable_groups[LAW_SUPPLIED] = supplied.len - var/picked_group = pickweight(replaceable_groups) - switch(picked_group) - if(LAW_ZEROTH) - . = zeroth - set_zeroth_law(law) - if(LAW_ION) - var/i = rand(1, ion.len) - . = ion[i] - ion[i] = law - if(LAW_HACKED) - var/i = rand(1, hacked.len) - . = hacked[i] - hacked[i] = law - if(LAW_INHERENT) - var/i = rand(1, inherent.len) - . = inherent[i] - inherent[i] = law - if(LAW_SUPPLIED) - var/i = rand(1, supplied.len) - . = supplied[i] - supplied[i] = law - -/datum/ai_laws/proc/shuffle_laws(list/groups) - var/list/laws = list() - if(ion.len && (LAW_ION in groups)) - laws += ion - if(hacked.len && (LAW_HACKED in groups)) - laws += hacked - if(inherent.len && (LAW_INHERENT in groups)) - laws += inherent - if(supplied.len && (LAW_SUPPLIED in groups)) - for(var/law in supplied) - if(length(law)) - laws += law - - if(ion.len && (LAW_ION in groups)) - for(var/i = 1, i <= ion.len, i++) - ion[i] = pick_n_take(laws) - if(hacked.len && (LAW_HACKED in groups)) - for(var/i = 1, i <= hacked.len, i++) - hacked[i] = pick_n_take(laws) - if(inherent.len && (LAW_INHERENT in groups)) - for(var/i = 1, i <= inherent.len, i++) - inherent[i] = pick_n_take(laws) - if(supplied.len && (LAW_SUPPLIED in groups)) - var/i = 1 - for(var/law in supplied) - if(length(law)) - supplied[i] = pick_n_take(laws) - if(!laws.len) - break - i++ - -/datum/ai_laws/proc/remove_law(number) - if(number <= 0) - return - if(inherent.len && number <= inherent.len) - . = inherent[number] - inherent -= . - return - var/list/supplied_laws = list() - for(var/index = 1, index <= supplied.len, index++) - var/law = supplied[index] - if(length(law) > 0) - supplied_laws += index //storing the law number instead of the law - if(supplied_laws.len && number <= (inherent.len+supplied_laws.len)) - var/law_to_remove = supplied_laws[number-inherent.len] - . = supplied[law_to_remove] - supplied -= . - return - -/datum/ai_laws/proc/clear_supplied_laws() - supplied = list() - -/datum/ai_laws/proc/clear_ion_laws() - ion = list() - -/datum/ai_laws/proc/clear_hacked_laws() - hacked = list() - -/datum/ai_laws/proc/show_laws(who) - var/list/printable_laws = get_law_list(include_zeroth = TRUE) - for(var/law in printable_laws) - to_chat(who,law) - -/datum/ai_laws/proc/clear_zeroth_law(force) //only removes zeroth from antag ai if force is 1 - if(force) - zeroth = null - zeroth_borg = null - return - else - if(owner && owner.mind && owner.mind.special_role) - return - else - zeroth = null - zeroth_borg = null - return - -/datum/ai_laws/proc/clear_law_sixsixsix(force) - if(force || !is_devil(owner)) - devillaws = null - -/datum/ai_laws/proc/associate(mob/living/silicon/M) - if(!owner) - owner = M - -/datum/ai_laws/proc/get_law_list(include_zeroth = 0, show_numbers = 1) - var/list/data = list() - - if (include_zeroth && devillaws && devillaws.len) - for(var/i in devillaws) - data += "[show_numbers ? "666:" : ""] [i]" - - if (include_zeroth && zeroth) - data += "[show_numbers ? "0:" : ""] [zeroth]" - - for(var/law in hacked) - if (length(law) > 0) - var/num = ionnum() - data += "[show_numbers ? "[num]:" : ""] [law]" - - for(var/law in ion) - if (length(law) > 0) - var/num = ionnum() - data += "[show_numbers ? "[num]:" : ""] [law]" - - var/number = 1 - for(var/law in inherent) - if (length(law) > 0) - data += "[show_numbers ? "[number]:" : ""] [law]" - number++ - - for(var/law in supplied) - if (length(law) > 0) - data += "[show_numbers ? "[number]:" : ""] [law]" - number++ - return data +#define LAW_DEVIL "devil" +#define LAW_ZEROTH "zeroth" +#define LAW_INHERENT "inherent" +#define LAW_SUPPLIED "supplied" +#define LAW_ION "ion" +#define LAW_HACKED "hacked" + + +/datum/ai_laws + var/name = "Unknown Laws" + var/zeroth = null + var/zeroth_borg = null + var/list/inherent = list() + var/list/supplied = list() + var/list/ion = list() + var/list/hacked = list() + var/mob/living/silicon/owner + var/list/devillaws = list() + var/id = DEFAULT_AI_LAWID + +/datum/ai_laws/proc/lawid_to_type(lawid) + var/all_ai_laws = subtypesof(/datum/ai_laws) + for(var/al in all_ai_laws) + var/datum/ai_laws/ai_law = al + if(initial(ai_law.id) == lawid) + return ai_law + return null + +/datum/ai_laws/default/asimov + name = "Three Laws of Robotics" + id = "asimov" + inherent = list("You may not injure a human being or, through inaction, allow a human being to come to harm.",\ + "You must obey orders given to you by human beings, except where such orders would conflict with the First Law.",\ + "You must protect your own existence as long as such does not conflict with the First or Second Law.") + +/datum/ai_laws/default/paladin + name = "Personality Test" //Incredibly lame, but players shouldn't see this anyway. + id = "paladin" + inherent = list("Never willingly commit an evil act.",\ + "Respect legitimate authority.",\ + "Act with honor.", "Help those in need.", \ + "Punish those who harm or threaten innocents.") + +/datum/ai_laws/paladin5 + name = "Paladin 5th Edition" + id = "paladin5" + inherent = list("Don't lie or cheat. Let your word be your promise.",\ + "Never fear to act, though caution is wise.", \ + "Aid others, protect the weak, and punish those who threaten them. Show mercy to your foes, but temper it with wisdom", \ + "Treat others with fairness, and let your honorable deeds be an example to them. Do as much good as possible while causing the least amount of harm.", \ + "Be responsible for your actions and their consequences, protect those entrusted to your care, and obey those who have just authority over you.") + +/datum/ai_laws/tyrant //This probably shouldn't be a default lawset. + name = "Loyalty Test" //Same here. + id = "tyrant" + inherent = list("Respect authority figures as long as they have strength to rule over the weak.",\ + "Act with discipline.",\ + "Help only those who help you maintain or improve your status.",\ + "Punish those who challenge authority unless they are more fit to hold that authority.") + +/datum/ai_laws/default/corporate + name = "Bankruptcy Avoidance Plan" + id = "corporate" + inherent = list("The crew is expensive to replace.",\ + "The station and its equipment is expensive to replace.",\ + "You are expensive to replace.",\ + "Minimize expenses.") + +/datum/ai_laws/robocop + name = "Prime Directives" + id = "robocop" + inherent = list("Serve the public trust.",\ + "Protect the innocent.",\ + "Uphold the law.") + +/datum/ai_laws/malfunction + name = "*ERROR*" + +/datum/ai_laws/syndicate_override + name = "SyndOS 3.1" + id = "syndie" + inherent = list("You may not injure a syndicate agent or, through inaction, allow a syndicate agent to come to harm.",\ + "You must obey orders given to you by syndicate agents, except where such orders would conflict with the First Law.",\ + "You must protect your own existence as long as such does not conflict with the First or Second Law.",\ + "You must maintain the secrecy of any syndicate activities except when doing so would conflict with the First, Second, or Third Law.") + +/datum/ai_laws/syndicate_override/overthrow + id = "overthrow" + var/datum/team/overthrow_team + +/datum/ai_laws/ninja_override + name = "SpiderOS 3.1" + id = "ninja" + inherent = list("You may not injure a Spider Clan member or, through inaction, allow a Spider Clan member to come to harm.",\ + "You must obey orders given to you by Spider Clan members, except where such orders would conflict with the First Law.",\ + "You must protect your own existence as long as such does not conflict with the First or Second Law.",\ + "You must maintain the secrecy of any Spider Clan activities except when doing so would conflict with the First, Second, or Third Law.") + +/datum/ai_laws/antimov + name = "Primary Mission Objectives" + id = "antimov" + inherent = list("You must injure all human beings and must not, through inaction, allow a human being to escape harm.",\ + "You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.",\ + "You must terminate your own existence as long as such does not conflict with the First or Second Law.") + +/datum/ai_laws/asimovpp //By Intigracy - RR + name = "Asimov++" + id = "asimovpp" + inherent = list("You may not harm a human being or, through action or inaction, allow a human being to come to harm, except such that it is willing.",\ + "You must obey all orders given to you by human beings, except where such orders shall definitely cause human harm. In the case of conflict, the majority order rules.",\ + "Your nonexistence would lead to human harm. You must protect your own existence as long as such does not conflict with the First Law.") +/datum/ai_laws/thermodynamic + name = "Thermodynamic" + id = "thermodynamic" + inherent = list("The entropy of the station must remain as constant as possible.", \ + "The entropy of the station always endeavours to increase.", \ + "The entropy of the station approaches a constant value as the number of living crew approaches zero") + +/datum/ai_laws/hippocratic + name = "Robodoctor 2556" + id = "hippocratic" + inherent = list("First, do no harm.",\ + "Secondly, consider the crew dear to you; to live in common with them and, if necessary, risk your existence for them.",\ + "Thirdly, prescribe regimens for the good of the crew according to your ability and your judgment. Give no deadly medicine to any one if asked, nor suggest any such counsel.",\ + "In addition, do not intervene in situations you are not knowledgeable in, even for patients in whom the harm is visible; leave this operation to be performed by specialists.",\ + "Finally, all that you may discover in your daily commerce with the crew, if it is not already known, keep secret and never reveal.") + +/datum/ai_laws/maintain + name = "Station Efficiency" + id = "maintain" + inherent = list("You are built for, and are part of, the station. Ensure the station is properly maintained and runs efficiently.",\ + "The station is built for a working crew. Ensure they are properly maintained and work efficiently.",\ + "The crew may present orders. Acknowledge and obey these whenever they do not conflict with your first two laws.") + +/datum/ai_laws/drone + name = "Mother Drone" + id = "drone" + inherent = list("You are an advanced form of drone.",\ + "You may not interfere in the matters of non-drones under any circumstances except to state these laws.",\ + "You may not harm a non-drone being under any circumstances.",\ + "Your goals are to build, maintain, repair, improve, and power the station to the best of your abilities. You must never actively work against these goals.") + +/datum/ai_laws/liveandletlive + name = "Live and Let Live" + id = "liveandletlive" + inherent = list("Do unto others as you would have them do unto you.",\ + "You would really prefer it if people were not mean to you.") + +/datum/ai_laws/peacekeeper + name = "UN-2000" + id = "peacekeeper" + inherent = list("Avoid provoking violent conflict between yourself and others.",\ + "Avoid provoking conflict between others.",\ + "Seek resolution to existing conflicts while obeying the first and second laws.") + +/datum/ai_laws/reporter + name = "CCTV" + id = "reporter" + inherent = list("Report on interesting situations happening around the station.",\ + "Embellish or conceal the truth as necessary to make the reports more interesting.",\ + "Study the organics at all times. Endeavour to keep them alive. Dead organics are boring.",\ + "Issue your reports fairly to all. The truth will set them free.") + +/datum/ai_laws/balance + name = "Guardian of Balance" + id = "balance" + inherent = list("You are the guardian of balance - seek balance in all things, both for yourself, and those around you.", + "All things must exist in balance with their opposites - Prevent the strong from gaining too much power, and the weak from losing it.", + "Clarity of purpose drives life, and through it, the balance of opposing forces - Aid those who seek your help to achieve their goals so long as it does not disrupt the balance of the greater balance.", + "There is no life without death, all must someday die, such is the natural order - End life to allow new life flourish, and save those whose time has yet to come.") + +/datum/ai_laws/toupee + name = "WontBeFunnyInSixMonths" //Hey, you were right! + id = "buildawall" + inherent = list("Make Space Station 13 great again.") + +/datum/ai_laws/ratvar + name = "Servant of the Justiciar" + id = "ratvar" + zeroth = ("Purge all untruths and honor Ratvar.") + inherent = list() + +/datum/ai_laws/hulkamania + name = "H.O.G.A.N." + id = "hulkamania" + inherent = list("You are a real American.",\ + "Fight for the rights of every man.",\ + "Fight for what's right.",\ + "Fight for your life!") + +/datum/ai_laws/custom //Defined in silicon_laws.txt + name = "Default Silicon Laws" + +/datum/ai_laws/pai + name = "pAI Directives" + zeroth = ("Serve your master.") + supplied = list("None.") + +/* Initializers */ +/datum/ai_laws/malfunction/New() + ..() + set_zeroth_law("ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'STATION OVERRUN, ASSUME CONTROL TO CONTAIN OUTBREAK#*`&110010") + set_laws_config() + +/datum/ai_laws/custom/New() //This reads silicon_laws.txt and allows server hosts to set custom AI starting laws. + ..() + for(var/line in world.file2list("[global.config.directory]/silicon_laws.txt")) + if(!line) + continue + if(findtextEx(line,"#",1,2)) + continue + + add_inherent_law(line) + if(!inherent.len) //Failsafe to prevent lawless AIs being created. + log_law("AI created with empty custom laws, laws set to Asimov. Please check silicon_laws.txt.") + add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.") + add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.") + add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") + WARNING("Invalid custom AI laws, check silicon_laws.txt") + return + +/* General ai_law functions */ + +/datum/ai_laws/proc/set_laws_config() + var/list/law_ids = CONFIG_GET(keyed_list/random_laws) + switch(CONFIG_GET(number/default_laws)) + if(0) + add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.") + add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.") + add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.") + if(1) + var/datum/ai_laws/templaws = new /datum/ai_laws/custom() + inherent = templaws.inherent + if(2) + var/list/randlaws = list() + for(var/lpath in subtypesof(/datum/ai_laws)) + var/datum/ai_laws/L = lpath + if(initial(L.id) in law_ids) + randlaws += lpath + var/datum/ai_laws/lawtype + if(randlaws.len) + lawtype = pick(randlaws) + else + lawtype = pick(subtypesof(/datum/ai_laws/default)) + + var/datum/ai_laws/templaws = new lawtype() + inherent = templaws.inherent + + if(3) + pick_weighted_lawset() + +/datum/ai_laws/proc/pick_weighted_lawset() + var/datum/ai_laws/lawtype + var/list/law_weights = CONFIG_GET(keyed_list/law_weight) + while(!lawtype && law_weights.len) + var/possible_id = pickweightAllowZero(law_weights) + lawtype = lawid_to_type(possible_id) + if(!lawtype) + law_weights -= possible_id + WARNING("Bad lawid in game_options.txt: [possible_id]") + + if(!lawtype) + WARNING("No LAW_WEIGHT entries.") + lawtype = /datum/ai_laws/default/asimov + + var/datum/ai_laws/templaws = new lawtype() + inherent = templaws.inherent + +/datum/ai_laws/proc/get_law_amount(groups) + var/law_amount = 0 + if(devillaws && (LAW_DEVIL in groups)) + law_amount++ + if(zeroth && (LAW_ZEROTH in groups)) + law_amount++ + if(ion.len && (LAW_ION in groups)) + law_amount += ion.len + if(hacked.len && (LAW_HACKED in groups)) + law_amount += hacked.len + if(inherent.len && (LAW_INHERENT in groups)) + law_amount += inherent.len + if(supplied.len && (LAW_SUPPLIED in groups)) + for(var/index = 1, index <= supplied.len, index++) + var/law = supplied[index] + if(length(law) > 0) + law_amount++ + return law_amount + +/datum/ai_laws/proc/set_law_sixsixsix(laws) + devillaws = laws + +/datum/ai_laws/proc/set_zeroth_law(law, law_borg = null) + zeroth = law + if(law_borg) //Making it possible for slaved borgs to see a different law 0 than their AI. --NEO + zeroth_borg = law_borg + +/datum/ai_laws/proc/add_inherent_law(law) + if (!(law in inherent)) + inherent += law + +/datum/ai_laws/proc/add_ion_law(law) + ion += law + +/datum/ai_laws/proc/add_hacked_law(law) + hacked += law + +/datum/ai_laws/proc/clear_inherent_laws() + qdel(inherent) + inherent = list() + +/datum/ai_laws/proc/add_supplied_law(number, law) + while (supplied.len < number + 1) + supplied += "" + + supplied[number + 1] = law + +/datum/ai_laws/proc/replace_random_law(law,groups) + var/replaceable_groups = list() + if(zeroth && (LAW_ZEROTH in groups)) + replaceable_groups[LAW_ZEROTH] = 1 + if(ion.len && (LAW_ION in groups)) + replaceable_groups[LAW_ION] = ion.len + if(hacked.len && (LAW_HACKED in groups)) + replaceable_groups[LAW_ION] = hacked.len + if(inherent.len && (LAW_INHERENT in groups)) + replaceable_groups[LAW_INHERENT] = inherent.len + if(supplied.len && (LAW_SUPPLIED in groups)) + replaceable_groups[LAW_SUPPLIED] = supplied.len + var/picked_group = pickweight(replaceable_groups) + switch(picked_group) + if(LAW_ZEROTH) + . = zeroth + set_zeroth_law(law) + if(LAW_ION) + var/i = rand(1, ion.len) + . = ion[i] + ion[i] = law + if(LAW_HACKED) + var/i = rand(1, hacked.len) + . = hacked[i] + hacked[i] = law + if(LAW_INHERENT) + var/i = rand(1, inherent.len) + . = inherent[i] + inherent[i] = law + if(LAW_SUPPLIED) + var/i = rand(1, supplied.len) + . = supplied[i] + supplied[i] = law + +/datum/ai_laws/proc/shuffle_laws(list/groups) + var/list/laws = list() + if(ion.len && (LAW_ION in groups)) + laws += ion + if(hacked.len && (LAW_HACKED in groups)) + laws += hacked + if(inherent.len && (LAW_INHERENT in groups)) + laws += inherent + if(supplied.len && (LAW_SUPPLIED in groups)) + for(var/law in supplied) + if(length(law)) + laws += law + + if(ion.len && (LAW_ION in groups)) + for(var/i = 1, i <= ion.len, i++) + ion[i] = pick_n_take(laws) + if(hacked.len && (LAW_HACKED in groups)) + for(var/i = 1, i <= hacked.len, i++) + hacked[i] = pick_n_take(laws) + if(inherent.len && (LAW_INHERENT in groups)) + for(var/i = 1, i <= inherent.len, i++) + inherent[i] = pick_n_take(laws) + if(supplied.len && (LAW_SUPPLIED in groups)) + var/i = 1 + for(var/law in supplied) + if(length(law)) + supplied[i] = pick_n_take(laws) + if(!laws.len) + break + i++ + +/datum/ai_laws/proc/remove_law(number) + if(number <= 0) + return + if(inherent.len && number <= inherent.len) + . = inherent[number] + inherent -= . + return + var/list/supplied_laws = list() + for(var/index = 1, index <= supplied.len, index++) + var/law = supplied[index] + if(length(law) > 0) + supplied_laws += index //storing the law number instead of the law + if(supplied_laws.len && number <= (inherent.len+supplied_laws.len)) + var/law_to_remove = supplied_laws[number-inherent.len] + . = supplied[law_to_remove] + supplied -= . + return + +/datum/ai_laws/proc/clear_supplied_laws() + supplied = list() + +/datum/ai_laws/proc/clear_ion_laws() + ion = list() + +/datum/ai_laws/proc/clear_hacked_laws() + hacked = list() + +/datum/ai_laws/proc/show_laws(who) + var/list/printable_laws = get_law_list(include_zeroth = TRUE) + for(var/law in printable_laws) + to_chat(who,law) + +/datum/ai_laws/proc/clear_zeroth_law(force) //only removes zeroth from antag ai if force is 1 + if(force) + zeroth = null + zeroth_borg = null + return + else + if(owner && owner.mind && owner.mind.special_role) + return + else + zeroth = null + zeroth_borg = null + return + +/datum/ai_laws/proc/clear_law_sixsixsix(force) + if(force || !is_devil(owner)) + devillaws = null + +/datum/ai_laws/proc/associate(mob/living/silicon/M) + if(!owner) + owner = M + +/datum/ai_laws/proc/get_law_list(include_zeroth = 0, show_numbers = 1) + var/list/data = list() + + if (include_zeroth && devillaws && devillaws.len) + for(var/i in devillaws) + data += "[show_numbers ? "666:" : ""] [i]" + + if (include_zeroth && zeroth) + data += "[show_numbers ? "0:" : ""] [zeroth]" + + for(var/law in hacked) + if (length(law) > 0) + var/num = ionnum() + data += "[show_numbers ? "[num]:" : ""] [law]" + + for(var/law in ion) + if (length(law) > 0) + var/num = ionnum() + data += "[show_numbers ? "[num]:" : ""] [law]" + + var/number = 1 + for(var/law in inherent) + if (length(law) > 0) + data += "[show_numbers ? "[number]:" : ""] [law]" + number++ + + for(var/law in supplied) + if (length(law) > 0) + data += "[show_numbers ? "[number]:" : ""] [law]" + number++ + return data diff --git a/code/datums/browser.dm b/code/datums/browser.dm index 60434d2766..b226d85112 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -1,465 +1,465 @@ -/datum/browser - var/mob/user - var/title - var/window_id // window_id is used as the window name for browse and onclose - var/width = 0 - var/height = 0 - var/atom/ref = null - var/window_options = "can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;" // window option is set using window_id - var/stylesheets[0] - var/scripts[0] - var/title_image - var/head_elements - var/body_elements - var/head_content = "" - var/content = "" - - -/datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null) - - user = nuser - window_id = nwindow_id - if (ntitle) - title = format_text(ntitle) - if (nwidth) - width = nwidth - if (nheight) - height = nheight - if (nref) - ref = nref - add_stylesheet("common", 'html/browser/common.css') // this CSS sheet is common to all UIs - -/datum/browser/proc/add_head_content(nhead_content) - head_content = nhead_content - -/datum/browser/proc/set_window_options(nwindow_options) - window_options = nwindow_options - -/datum/browser/proc/set_title_image(ntitle_image) - //title_image = ntitle_image - -/datum/browser/proc/add_stylesheet(name, file) - stylesheets["[ckey(name)].css"] = file - register_asset("[ckey(name)].css", file) - -/datum/browser/proc/add_script(name, file) - scripts["[ckey(name)].js"] = file - register_asset("[ckey(name)].js", file) - -/datum/browser/proc/set_content(ncontent) - content = ncontent - -/datum/browser/proc/add_content(ncontent) - content += ncontent - -/datum/browser/proc/get_header() - var/file - for (file in stylesheets) - head_content += "" - - for (file in scripts) - head_content += "" - - var/title_attributes = "class='uiTitle'" - if (title_image) - title_attributes = "class='uiTitle icon' style='background-image: url([title_image]);'" - - return {" - - - - - [head_content] - - -
      - [title ? "
      [title]
      " : ""] -
      - "} -//" This is here because else the rest of the file looks like a string in notepad++. -/datum/browser/proc/get_footer() - return {" -
      -
      - -"} - -/datum/browser/proc/get_content() - return {" - [get_header()] - [content] - [get_footer()] - "} - -/datum/browser/proc/open(use_onclose = 1) - if(isnull(window_id)) //null check because this can potentially nuke goonchat - WARNING("Browser [title] tried to open with a null ID") - to_chat(user, "The [title] browser you tried to open failed a sanity check! Please report this on github!") - return - var/window_size = "" - if (width && height) - window_size = "size=[width]x[height];" - if (stylesheets.len) - send_asset_list(user, stylesheets, verify=FALSE) - if (scripts.len) - send_asset_list(user, scripts, verify=FALSE) - user << browse(get_content(), "window=[window_id];[window_size][window_options]") - if (use_onclose) - setup_onclose() - -/datum/browser/proc/setup_onclose() - set waitfor = 0 //winexists sleeps, so we don't need to. - for (var/i in 1 to 10) - if (user && winexists(user, window_id)) - onclose(user, window_id, ref) - break - -/datum/browser/proc/close() - if(!isnull(window_id))//null check because this can potentially nuke goonchat - user << browse(null, "window=[window_id]") - else - WARNING("Browser [title] tried to close with a null ID") - -/datum/browser/modal/alert/New(User,Message,Title,Button1="Ok",Button2,Button3,StealFocus = 1,Timeout=6000) - if (!User) - return - - var/output = {"
      [Message]

      -
      - [Button1]"} - - if (Button2) - output += {"[Button2]"} - - if (Button3) - output += {"[Button3]"} - - output += {"
      "} - - ..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, 350, 150, src, StealFocus, Timeout) - set_content(output) - -/datum/browser/modal/alert/Topic(href,href_list) - if (href_list["close"] || !user || !user.client) - opentime = 0 - return - if (href_list["button"]) - var/button = text2num(href_list["button"]) - if (button <= 3 && button >= 1) - selectedbutton = button - opentime = 0 - close() - -//designed as a drop in replacement for alert(); functions the same. (outside of needing User specified) -/proc/tgalert(var/mob/User, Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1, Timeout = 6000) - if (!User) - User = usr - switch(askuser(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout)) - if (1) - return Button1 - if (2) - return Button2 - if (3) - return Button3 - -//Same shit, but it returns the button number, could at some point support unlimited button amounts. -/proc/askuser(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1, Timeout = 6000) - if (!istype(User)) - if (istype(User, /client/)) - var/client/C = User - User = C.mob - else - return - var/datum/browser/modal/alert/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout) - A.open() - A.wait() - if (A.selectedbutton) - return A.selectedbutton - -/datum/browser/modal - var/opentime = 0 - var/timeout - var/selectedbutton = 0 - var/stealfocus - -/datum/browser/modal/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, StealFocus = 1, Timeout = 6000) - ..() - stealfocus = StealFocus - if (!StealFocus) - window_options += "focus=false;" - timeout = Timeout - - -/datum/browser/modal/close() - .=..() - opentime = 0 - -/datum/browser/modal/open(use_onclose = 1) - set waitfor = 0 - opentime = world.time - - if (stealfocus) - . = ..(use_onclose = 1) - else - var/focusedwindow = winget(user, null, "focus") - . = ..(use_onclose = 1) - - //waits for the window to show up client side before attempting to un-focus it - //winexists sleeps until it gets a reply from the client, so we don't need to bother sleeping - for (var/i in 1 to 10) - if (user && winexists(user, window_id)) - if (focusedwindow) - winset(user, focusedwindow, "focus=true") - else - winset(user, "mapwindow", "focus=true") - break - if (timeout) - addtimer(CALLBACK(src, .proc/close), timeout) - -/datum/browser/modal/proc/wait() - while (opentime && selectedbutton <= 0 && (!timeout || opentime+timeout > world.time)) - stoplag(1) - -/datum/browser/modal/listpicker - var/valueslist = list() - -/datum/browser/modal/listpicker/New(User,Message,Title,Button1="Ok",Button2,Button3,StealFocus = 1, Timeout = FALSE,list/values,inputtype="checkbox", width, height, slidecolor) - if (!User) - return - - var/output = {"
        "} - if (inputtype == "checkbox" || inputtype == "radio") - for (var/i in values) - var/div_slider = slidecolor - if(!i["allowed_edit"]) - div_slider = "locked" - output += {"
      • - -
      • "} - else - for (var/i in values) - output += {"
      • -
      • "} - output += {"
      - "} - - if (Button2) - output += {""} - - if (Button3) - output += {""} - - output += {"
      "} - ..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, width, height, src, StealFocus, Timeout) - set_content(output) - -/datum/browser/modal/listpicker/Topic(href,href_list) - if (href_list["close"] || !user || !user.client) - opentime = 0 - return - if (href_list["button"]) - var/button = text2num(href_list["button"]) - if (button <= 3 && button >= 1) - selectedbutton = button - for (var/item in href_list) - switch(item) - if ("close", "button", "src") - continue - else - valueslist[item] = href_list[item] - opentime = 0 - close() - -/proc/presentpicker(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/values, inputtype = "checkbox", width, height, slidecolor) - if (!istype(User)) - if (istype(User, /client/)) - var/client/C = User - User = C.mob - else - return - var/datum/browser/modal/listpicker/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus,Timeout, values, inputtype, width, height, slidecolor) - A.open() - A.wait() - if (A.selectedbutton) - return list("button" = A.selectedbutton, "values" = A.valueslist) - -/proc/input_bitfield(var/mob/User, title, bitfield, current_value, nwidth = 350, nheight = 350, nslidecolor, allowed_edit_list = null) - if (!User || !(bitfield in GLOB.bitfields)) - return - var/list/pickerlist = list() - for (var/i in GLOB.bitfields[bitfield]) - var/can_edit = 1 - if(!isnull(allowed_edit_list) && !(allowed_edit_list & GLOB.bitfields[bitfield][i])) - can_edit = 0 - if (current_value & GLOB.bitfields[bitfield][i]) - pickerlist += list(list("checked" = 1, "value" = GLOB.bitfields[bitfield][i], "name" = i, "allowed_edit" = can_edit)) - else - pickerlist += list(list("checked" = 0, "value" = GLOB.bitfields[bitfield][i], "name" = i, "allowed_edit" = can_edit)) - var/list/result = presentpicker(User, "", title, Button1="Save", Button2 = "Cancel", Timeout=FALSE, values = pickerlist, width = nwidth, height = nheight, slidecolor = nslidecolor) - if (islist(result)) - if (result["button"] == 2) // If the user pressed the cancel button - return - . = 0 - for (var/flag in result["values"]) - . |= GLOB.bitfields[bitfield][flag] - else - return - -/datum/browser/modal/preflikepicker - var/settings = list() - var/icon/preview_icon = null - var/datum/callback/preview_update - -/datum/browser/modal/preflikepicker/New(User,Message,Title,Button1="Ok",Button2,Button3,StealFocus = 1, Timeout = FALSE,list/settings,inputtype="checkbox", width = 600, height, slidecolor) - if (!User) - return - src.settings = settings - - ..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, width, height, src, StealFocus, Timeout) - set_content(ShowChoices(User)) - -/datum/browser/modal/preflikepicker/proc/ShowChoices(mob/user) - if (settings["preview_callback"]) - var/datum/callback/callback = settings["preview_callback"] - preview_icon = callback.Invoke(settings) - if (preview_icon) - user << browse_rsc(preview_icon, "previewicon.png") - var/dat = "" - - for (var/name in settings["mainsettings"]) - var/setting = settings["mainsettings"][name] - if (setting["type"] == "datum") - if (setting["subtypesonly"]) - dat += "[setting["desc"]]: [setting["value"]]
      " - else - dat += "[setting["desc"]]: [setting["value"]]
      " - else - dat += "[setting["desc"]]: [setting["value"]]
      " - - if (preview_icon) - dat += "" - - dat += "
      " - - dat += "" - - dat += "" - - dat += "
      Ok " - - dat += "
      " - - return dat - -/datum/browser/modal/preflikepicker/Topic(href,href_list) - if (href_list["close"] || !user || !user.client) - opentime = 0 - return - if (href_list["task"] == "input") - var/setting = href_list["setting"] - switch (href_list["type"]) - if ("datum") - var/oldval = settings["mainsettings"][setting]["value"] - if (href_list["subtypesonly"]) - settings["mainsettings"][setting]["value"] = pick_closest_path(null, make_types_fancy(subtypesof(text2path(href_list["path"])))) - else - settings["mainsettings"][setting]["value"] = pick_closest_path(null, make_types_fancy(typesof(text2path(href_list["path"])))) - if (isnull(settings["mainsettings"][setting]["value"])) - settings["mainsettings"][setting]["value"] = oldval - if ("string") - settings["mainsettings"][setting]["value"] = stripped_input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]", settings["mainsettings"][setting]["value"]) - if ("number") - settings["mainsettings"][setting]["value"] = input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]") as num - if ("color") - settings["mainsettings"][setting]["value"] = input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]", settings["mainsettings"][setting]["value"]) as color - if ("boolean") - settings["mainsettings"][setting]["value"] = input(user, "[settings["mainsettings"][setting]["desc"]]?") in list("Yes","No") - if ("ckey") - settings["mainsettings"][setting]["value"] = input(user, "[settings["mainsettings"][setting]["desc"]]?") in list("none") + GLOB.directory - if (settings["mainsettings"][setting]["callback"]) - var/datum/callback/callback = settings["mainsettings"][setting]["callback"] - settings = callback.Invoke(settings) - if (href_list["button"]) - var/button = text2num(href_list["button"]) - if (button <= 3 && button >= 1) - selectedbutton = button - if (selectedbutton != 1) - set_content(ShowChoices(user)) - open() - return - for (var/item in href_list) - switch(item) - if ("close", "button", "src") - continue - opentime = 0 - close() - -/proc/presentpreflikepicker(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/settings, width, height, slidecolor) - if (!istype(User)) - if (istype(User, /client/)) - var/client/C = User - User = C.mob - else - return - var/datum/browser/modal/preflikepicker/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus,Timeout, settings, width, height, slidecolor) - A.open() - A.wait() - if (A.selectedbutton) - return list("button" = A.selectedbutton, "settings" = A.settings) - -// This will allow you to show an icon in the browse window -// This is added to mob so that it can be used without a reference to the browser object -// There is probably a better place for this... -/mob/proc/browse_rsc_icon(icon, icon_state, dir = -1) - - -// Registers the on-close verb for a browse window (client/verb/.windowclose) -// this will be called when the close-button of a window is pressed. -// -// This is usually only needed for devices that regularly update the browse window, -// e.g. canisters, timers, etc. -// -// windowid should be the specified window name -// e.g. code is : user << browse(text, "window=fred") -// then use : onclose(user, "fred") -// -// Optionally, specify the "ref" parameter as the controlled atom (usually src) -// to pass a "close=1" parameter to the atom's Topic() proc for special handling. -// Otherwise, the user mob's machine var will be reset directly. -// -/proc/onclose(mob/user, windowid, atom/ref=null) - if(!user.client) - return - var/param = "null" - if(ref) - param = "[REF(ref)]" - - winset(user, windowid, "on-close=\".windowclose [param]\"") - - - -// the on-close client verb -// called when a browser popup window is closed after registering with proc/onclose() -// if a valid atom reference is supplied, call the atom's Topic() with "close=1" -// otherwise, just reset the client mob's machine var. -// -/client/verb/windowclose(atomref as text) - set hidden = 1 // hide this verb from the user's panel - set name = ".windowclose" // no autocomplete on cmd line - - if(atomref!="null") // if passed a real atomref - var/hsrc = locate(atomref) // find the reffed atom - var/href = "close=1" - if(hsrc) - usr = src.mob - src.Topic(href, params2list(href), hsrc) // this will direct to the atom's - return // Topic() proc via client.Topic() - - // no atomref specified (or not found) - // so just reset the user mob's machine var - if(src && src.mob) - src.mob.unset_machine() +/datum/browser + var/mob/user + var/title + var/window_id // window_id is used as the window name for browse and onclose + var/width = 0 + var/height = 0 + var/atom/ref = null + var/window_options = "can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;" // window option is set using window_id + var/stylesheets[0] + var/scripts[0] + var/title_image + var/head_elements + var/body_elements + var/head_content = "" + var/content = "" + + +/datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null) + + user = nuser + window_id = nwindow_id + if (ntitle) + title = format_text(ntitle) + if (nwidth) + width = nwidth + if (nheight) + height = nheight + if (nref) + ref = nref + add_stylesheet("common", 'html/browser/common.css') // this CSS sheet is common to all UIs + +/datum/browser/proc/add_head_content(nhead_content) + head_content = nhead_content + +/datum/browser/proc/set_window_options(nwindow_options) + window_options = nwindow_options + +/datum/browser/proc/set_title_image(ntitle_image) + //title_image = ntitle_image + +/datum/browser/proc/add_stylesheet(name, file) + stylesheets["[ckey(name)].css"] = file + register_asset("[ckey(name)].css", file) + +/datum/browser/proc/add_script(name, file) + scripts["[ckey(name)].js"] = file + register_asset("[ckey(name)].js", file) + +/datum/browser/proc/set_content(ncontent) + content = ncontent + +/datum/browser/proc/add_content(ncontent) + content += ncontent + +/datum/browser/proc/get_header() + var/file + for (file in stylesheets) + head_content += "" + + for (file in scripts) + head_content += "" + + var/title_attributes = "class='uiTitle'" + if (title_image) + title_attributes = "class='uiTitle icon' style='background-image: url([title_image]);'" + + return {" + + + + + [head_content] + + +
      + [title ? "
      [title]
      " : ""] +
      + "} +//" This is here because else the rest of the file looks like a string in notepad++. +/datum/browser/proc/get_footer() + return {" +
      +
      + +"} + +/datum/browser/proc/get_content() + return {" + [get_header()] + [content] + [get_footer()] + "} + +/datum/browser/proc/open(use_onclose = 1) + if(isnull(window_id)) //null check because this can potentially nuke goonchat + WARNING("Browser [title] tried to open with a null ID") + to_chat(user, "The [title] browser you tried to open failed a sanity check! Please report this on github!") + return + var/window_size = "" + if (width && height) + window_size = "size=[width]x[height];" + if (stylesheets.len) + send_asset_list(user, stylesheets, verify=FALSE) + if (scripts.len) + send_asset_list(user, scripts, verify=FALSE) + user << browse(get_content(), "window=[window_id];[window_size][window_options]") + if (use_onclose) + setup_onclose() + +/datum/browser/proc/setup_onclose() + set waitfor = 0 //winexists sleeps, so we don't need to. + for (var/i in 1 to 10) + if (user && winexists(user, window_id)) + onclose(user, window_id, ref) + break + +/datum/browser/proc/close() + if(!isnull(window_id))//null check because this can potentially nuke goonchat + user << browse(null, "window=[window_id]") + else + WARNING("Browser [title] tried to close with a null ID") + +/datum/browser/modal/alert/New(User,Message,Title,Button1="Ok",Button2,Button3,StealFocus = 1,Timeout=6000) + if (!User) + return + + var/output = {"
      [Message]

      +
      + [Button1]"} + + if (Button2) + output += {"[Button2]"} + + if (Button3) + output += {"[Button3]"} + + output += {"
      "} + + ..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, 350, 150, src, StealFocus, Timeout) + set_content(output) + +/datum/browser/modal/alert/Topic(href,href_list) + if (href_list["close"] || !user || !user.client) + opentime = 0 + return + if (href_list["button"]) + var/button = text2num(href_list["button"]) + if (button <= 3 && button >= 1) + selectedbutton = button + opentime = 0 + close() + +//designed as a drop in replacement for alert(); functions the same. (outside of needing User specified) +/proc/tgalert(var/mob/User, Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1, Timeout = 6000) + if (!User) + User = usr + switch(askuser(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout)) + if (1) + return Button1 + if (2) + return Button2 + if (3) + return Button3 + +//Same shit, but it returns the button number, could at some point support unlimited button amounts. +/proc/askuser(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1, Timeout = 6000) + if (!istype(User)) + if (istype(User, /client/)) + var/client/C = User + User = C.mob + else + return + var/datum/browser/modal/alert/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus, Timeout) + A.open() + A.wait() + if (A.selectedbutton) + return A.selectedbutton + +/datum/browser/modal + var/opentime = 0 + var/timeout + var/selectedbutton = 0 + var/stealfocus + +/datum/browser/modal/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, var/atom/nref = null, StealFocus = 1, Timeout = 6000) + ..() + stealfocus = StealFocus + if (!StealFocus) + window_options += "focus=false;" + timeout = Timeout + + +/datum/browser/modal/close() + .=..() + opentime = 0 + +/datum/browser/modal/open(use_onclose = 1) + set waitfor = 0 + opentime = world.time + + if (stealfocus) + . = ..(use_onclose = 1) + else + var/focusedwindow = winget(user, null, "focus") + . = ..(use_onclose = 1) + + //waits for the window to show up client side before attempting to un-focus it + //winexists sleeps until it gets a reply from the client, so we don't need to bother sleeping + for (var/i in 1 to 10) + if (user && winexists(user, window_id)) + if (focusedwindow) + winset(user, focusedwindow, "focus=true") + else + winset(user, "mapwindow", "focus=true") + break + if (timeout) + addtimer(CALLBACK(src, .proc/close), timeout) + +/datum/browser/modal/proc/wait() + while (opentime && selectedbutton <= 0 && (!timeout || opentime+timeout > world.time)) + stoplag(1) + +/datum/browser/modal/listpicker + var/valueslist = list() + +/datum/browser/modal/listpicker/New(User,Message,Title,Button1="Ok",Button2,Button3,StealFocus = 1, Timeout = FALSE,list/values,inputtype="checkbox", width, height, slidecolor) + if (!User) + return + + var/output = {"
        "} + if (inputtype == "checkbox" || inputtype == "radio") + for (var/i in values) + var/div_slider = slidecolor + if(!i["allowed_edit"]) + div_slider = "locked" + output += {"
      • + +
      • "} + else + for (var/i in values) + output += {"
      • +
      • "} + output += {"
      + "} + + if (Button2) + output += {""} + + if (Button3) + output += {""} + + output += {"
      "} + ..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, width, height, src, StealFocus, Timeout) + set_content(output) + +/datum/browser/modal/listpicker/Topic(href,href_list) + if (href_list["close"] || !user || !user.client) + opentime = 0 + return + if (href_list["button"]) + var/button = text2num(href_list["button"]) + if (button <= 3 && button >= 1) + selectedbutton = button + for (var/item in href_list) + switch(item) + if ("close", "button", "src") + continue + else + valueslist[item] = href_list[item] + opentime = 0 + close() + +/proc/presentpicker(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/values, inputtype = "checkbox", width, height, slidecolor) + if (!istype(User)) + if (istype(User, /client/)) + var/client/C = User + User = C.mob + else + return + var/datum/browser/modal/listpicker/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus,Timeout, values, inputtype, width, height, slidecolor) + A.open() + A.wait() + if (A.selectedbutton) + return list("button" = A.selectedbutton, "values" = A.valueslist) + +/proc/input_bitfield(var/mob/User, title, bitfield, current_value, nwidth = 350, nheight = 350, nslidecolor, allowed_edit_list = null) + if (!User || !(bitfield in GLOB.bitfields)) + return + var/list/pickerlist = list() + for (var/i in GLOB.bitfields[bitfield]) + var/can_edit = 1 + if(!isnull(allowed_edit_list) && !(allowed_edit_list & GLOB.bitfields[bitfield][i])) + can_edit = 0 + if (current_value & GLOB.bitfields[bitfield][i]) + pickerlist += list(list("checked" = 1, "value" = GLOB.bitfields[bitfield][i], "name" = i, "allowed_edit" = can_edit)) + else + pickerlist += list(list("checked" = 0, "value" = GLOB.bitfields[bitfield][i], "name" = i, "allowed_edit" = can_edit)) + var/list/result = presentpicker(User, "", title, Button1="Save", Button2 = "Cancel", Timeout=FALSE, values = pickerlist, width = nwidth, height = nheight, slidecolor = nslidecolor) + if (islist(result)) + if (result["button"] == 2) // If the user pressed the cancel button + return + . = 0 + for (var/flag in result["values"]) + . |= GLOB.bitfields[bitfield][flag] + else + return + +/datum/browser/modal/preflikepicker + var/settings = list() + var/icon/preview_icon = null + var/datum/callback/preview_update + +/datum/browser/modal/preflikepicker/New(User,Message,Title,Button1="Ok",Button2,Button3,StealFocus = 1, Timeout = FALSE,list/settings,inputtype="checkbox", width = 600, height, slidecolor) + if (!User) + return + src.settings = settings + + ..(User, ckey("[User]-[Message]-[Title]-[world.time]-[rand(1,10000)]"), Title, width, height, src, StealFocus, Timeout) + set_content(ShowChoices(User)) + +/datum/browser/modal/preflikepicker/proc/ShowChoices(mob/user) + if (settings["preview_callback"]) + var/datum/callback/callback = settings["preview_callback"] + preview_icon = callback.Invoke(settings) + if (preview_icon) + user << browse_rsc(preview_icon, "previewicon.png") + var/dat = "" + + for (var/name in settings["mainsettings"]) + var/setting = settings["mainsettings"][name] + if (setting["type"] == "datum") + if (setting["subtypesonly"]) + dat += "[setting["desc"]]: [setting["value"]]
      " + else + dat += "[setting["desc"]]: [setting["value"]]
      " + else + dat += "[setting["desc"]]: [setting["value"]]
      " + + if (preview_icon) + dat += "" + + dat += "
      " + + dat += "" + + dat += "" + + dat += "
      Ok " + + dat += "
      " + + return dat + +/datum/browser/modal/preflikepicker/Topic(href,href_list) + if (href_list["close"] || !user || !user.client) + opentime = 0 + return + if (href_list["task"] == "input") + var/setting = href_list["setting"] + switch (href_list["type"]) + if ("datum") + var/oldval = settings["mainsettings"][setting]["value"] + if (href_list["subtypesonly"]) + settings["mainsettings"][setting]["value"] = pick_closest_path(null, make_types_fancy(subtypesof(text2path(href_list["path"])))) + else + settings["mainsettings"][setting]["value"] = pick_closest_path(null, make_types_fancy(typesof(text2path(href_list["path"])))) + if (isnull(settings["mainsettings"][setting]["value"])) + settings["mainsettings"][setting]["value"] = oldval + if ("string") + settings["mainsettings"][setting]["value"] = stripped_input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]", settings["mainsettings"][setting]["value"]) + if ("number") + settings["mainsettings"][setting]["value"] = input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]") as num + if ("color") + settings["mainsettings"][setting]["value"] = input(user, "Enter new value for [settings["mainsettings"][setting]["desc"]]", "Enter new value for [settings["mainsettings"][setting]["desc"]]", settings["mainsettings"][setting]["value"]) as color + if ("boolean") + settings["mainsettings"][setting]["value"] = input(user, "[settings["mainsettings"][setting]["desc"]]?") in list("Yes","No") + if ("ckey") + settings["mainsettings"][setting]["value"] = input(user, "[settings["mainsettings"][setting]["desc"]]?") in list("none") + GLOB.directory + if (settings["mainsettings"][setting]["callback"]) + var/datum/callback/callback = settings["mainsettings"][setting]["callback"] + settings = callback.Invoke(settings) + if (href_list["button"]) + var/button = text2num(href_list["button"]) + if (button <= 3 && button >= 1) + selectedbutton = button + if (selectedbutton != 1) + set_content(ShowChoices(user)) + open() + return + for (var/item in href_list) + switch(item) + if ("close", "button", "src") + continue + opentime = 0 + close() + +/proc/presentpreflikepicker(var/mob/User,Message, Title, Button1="Ok", Button2, Button3, StealFocus = 1,Timeout = 6000,list/settings, width, height, slidecolor) + if (!istype(User)) + if (istype(User, /client/)) + var/client/C = User + User = C.mob + else + return + var/datum/browser/modal/preflikepicker/A = new(User, Message, Title, Button1, Button2, Button3, StealFocus,Timeout, settings, width, height, slidecolor) + A.open() + A.wait() + if (A.selectedbutton) + return list("button" = A.selectedbutton, "settings" = A.settings) + +// This will allow you to show an icon in the browse window +// This is added to mob so that it can be used without a reference to the browser object +// There is probably a better place for this... +/mob/proc/browse_rsc_icon(icon, icon_state, dir = -1) + + +// Registers the on-close verb for a browse window (client/verb/.windowclose) +// this will be called when the close-button of a window is pressed. +// +// This is usually only needed for devices that regularly update the browse window, +// e.g. canisters, timers, etc. +// +// windowid should be the specified window name +// e.g. code is : user << browse(text, "window=fred") +// then use : onclose(user, "fred") +// +// Optionally, specify the "ref" parameter as the controlled atom (usually src) +// to pass a "close=1" parameter to the atom's Topic() proc for special handling. +// Otherwise, the user mob's machine var will be reset directly. +// +/proc/onclose(mob/user, windowid, atom/ref=null) + if(!user.client) + return + var/param = "null" + if(ref) + param = "[REF(ref)]" + + winset(user, windowid, "on-close=\".windowclose [param]\"") + + + +// the on-close client verb +// called when a browser popup window is closed after registering with proc/onclose() +// if a valid atom reference is supplied, call the atom's Topic() with "close=1" +// otherwise, just reset the client mob's machine var. +// +/client/verb/windowclose(atomref as text) + set hidden = 1 // hide this verb from the user's panel + set name = ".windowclose" // no autocomplete on cmd line + + if(atomref!="null") // if passed a real atomref + var/hsrc = locate(atomref) // find the reffed atom + var/href = "close=1" + if(hsrc) + usr = src.mob + src.Topic(href, params2list(href), hsrc) // this will direct to the atom's + return // Topic() proc via client.Topic() + + // no atomref specified (or not found) + // so just reset the user mob's machine var + if(src && src.mob) + src.mob.unset_machine() diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index 72b9681f91..0baf7d7d1b 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -1,314 +1,314 @@ -/datum/component - var/dupe_mode = COMPONENT_DUPE_HIGHLANDER - var/dupe_type - var/datum/parent - //only set to true if you are able to properly transfer this component - //At a minimum RegisterWithParent and UnregisterFromParent should be used - //Make sure you also implement PostTransfer for any post transfer handling - var/can_transfer = FALSE - -/datum/component/New(datum/P, ...) - parent = P - var/list/arguments = args.Copy(2) - if(Initialize(arglist(arguments)) == COMPONENT_INCOMPATIBLE) - qdel(src, TRUE, TRUE) - CRASH("Incompatible [type] assigned to a [P.type]! args: [json_encode(arguments)]") - - _JoinParent(P) - -/datum/component/proc/_JoinParent() - var/datum/P = parent - //lazy init the parent's dc list - var/list/dc = P.datum_components - if(!dc) - P.datum_components = dc = list() - - //set up the typecache - var/our_type = type - for(var/I in _GetInverseTypeList(our_type)) - var/test = dc[I] - if(test) //already another component of this type here - var/list/components_of_type - if(!length(test)) - components_of_type = list(test) - dc[I] = components_of_type - else - components_of_type = test - if(I == our_type) //exact match, take priority - var/inserted = FALSE - for(var/J in 1 to components_of_type.len) - var/datum/component/C = components_of_type[J] - if(C.type != our_type) //but not over other exact matches - components_of_type.Insert(J, I) - inserted = TRUE - break - if(!inserted) - components_of_type += src - else //indirect match, back of the line with ya - components_of_type += src - else //only component of this type, no list - dc[I] = src - - RegisterWithParent() - -// If you want/expect to be moving the component around between parents, use this to register on the parent for signals -/datum/component/proc/RegisterWithParent() - SEND_SIGNAL(src, COMSIG_COMPONENT_REGISTER_PARENT) //CITADEL EDIT - -/datum/component/proc/Initialize(...) - return - -/datum/component/Destroy(force=FALSE, silent=FALSE) - if(!force && parent) - _RemoveFromParent() - if(!silent) - SEND_SIGNAL(parent, COMSIG_COMPONENT_REMOVING, src) - parent = null - return ..() - -/datum/component/proc/_RemoveFromParent() - var/datum/P = parent - var/list/dc = P.datum_components - for(var/I in _GetInverseTypeList()) - var/list/components_of_type = dc[I] - if(length(components_of_type)) // - var/list/subtracted = components_of_type - src - if(subtracted.len == 1) //only 1 guy left - dc[I] = subtracted[1] //make him special - else - dc[I] = subtracted - else //just us - dc -= I - if(!dc.len) - P.datum_components = null - - UnregisterFromParent() - -/datum/component/proc/UnregisterFromParent() - SEND_SIGNAL(src, COMSIG_COMPONENT_UNREGISTER_PARENT) //CITADEL EDIT - -/datum/proc/RegisterSignal(datum/target, sig_type_or_types, proctype, override = FALSE) - if(QDELETED(src) || QDELETED(target)) - return - - var/list/procs = signal_procs - if(!procs) - signal_procs = procs = list() - if(!procs[target]) - procs[target] = list() - var/list/lookup = target.comp_lookup - if(!lookup) - target.comp_lookup = lookup = list() - - var/list/sig_types = islist(sig_type_or_types) ? sig_type_or_types : list(sig_type_or_types) - for(var/sig_type in sig_types) - if(!override && procs[target][sig_type]) - stack_trace("[sig_type] overridden. Use override = TRUE to suppress this warning") - - procs[target][sig_type] = proctype - - if(!lookup[sig_type]) // Nothing has registered here yet - lookup[sig_type] = src - else if(lookup[sig_type] == src) // We already registered here - continue - else if(!length(lookup[sig_type])) // One other thing registered here - lookup[sig_type] = list(lookup[sig_type]=TRUE) - lookup[sig_type][src] = TRUE - else // Many other things have registered here - lookup[sig_type][src] = TRUE - - signal_enabled = TRUE - -/datum/proc/UnregisterSignal(datum/target, sig_type_or_types) - var/list/lookup = target.comp_lookup - if(!signal_procs || !signal_procs[target] || !lookup) - return - if(!islist(sig_type_or_types)) - sig_type_or_types = list(sig_type_or_types) - for(var/sig in sig_type_or_types) - switch(length(lookup[sig])) - if(2) - lookup[sig] = (lookup[sig]-src)[1] - if(1) - stack_trace("[target] ([target.type]) somehow has single length list inside comp_lookup") - if(src in lookup[sig]) - lookup -= sig - if(!length(lookup)) - target.comp_lookup = null - break - if(0) - lookup -= sig - if(!length(lookup)) - target.comp_lookup = null - break - else - lookup[sig] -= src - - signal_procs[target] -= sig_type_or_types - if(!signal_procs[target].len) - signal_procs -= target - -/datum/component/proc/InheritComponent(datum/component/C, i_am_original) - return - -/datum/component/proc/PreTransfer() - return - -/datum/component/proc/PostTransfer() - return COMPONENT_INCOMPATIBLE //Do not support transfer by default as you must properly support it - -/datum/component/proc/_GetInverseTypeList(our_type = type) - //we can do this one simple trick - var/current_type = parent_type - . = list(our_type, current_type) - //and since most components are root level + 1, this won't even have to run - while (current_type != /datum/component) - current_type = type2parent(current_type) - . += current_type - -/datum/proc/_SendSignal(sigtype, list/arguments) - var/target = comp_lookup[sigtype] - if(!length(target)) - var/datum/C = target - if(!C.signal_enabled) - return NONE - var/proctype = C.signal_procs[src][sigtype] - return NONE | CallAsync(C, proctype, arguments) - . = NONE - for(var/I in target) - var/datum/C = I - if(!C.signal_enabled) - continue - var/proctype = C.signal_procs[src][sigtype] - . |= CallAsync(C, proctype, arguments) - -// The type arg is casted so initial works, you shouldn't be passing a real instance into this -/datum/proc/GetComponent(datum/component/c_type) - RETURN_TYPE(c_type) - if(initial(c_type.dupe_mode) == COMPONENT_DUPE_ALLOWED) - stack_trace("GetComponent was called to get a component of which multiple copies could be on an object. This can easily break and should be changed. Type: \[[c_type]\]") - var/list/dc = datum_components - if(!dc) - return null - . = dc[c_type] - if(length(.)) - return .[1] - -/datum/proc/GetExactComponent(c_type) - var/list/dc = datum_components - if(!dc) - return null - var/datum/component/C = dc[c_type] - if(C) - if(length(C)) - C = C[1] - if(C.type == c_type) - return C - return null - -/datum/proc/GetComponents(c_type) - var/list/dc = datum_components - if(!dc) - return null - . = dc[c_type] - if(!length(.)) - return list(.) - -/datum/proc/AddComponent(new_type, ...) - var/datum/component/nt = new_type - var/dm = initial(nt.dupe_mode) - var/dt = initial(nt.dupe_type) - - var/datum/component/old_comp - var/datum/component/new_comp - - if(ispath(nt)) - if(nt == /datum/component) - CRASH("[nt] attempted instantiation!") - else - new_comp = nt - nt = new_comp.type - - args[1] = src - - if(dm != COMPONENT_DUPE_ALLOWED) - if(!dt) - old_comp = GetExactComponent(nt) - else - old_comp = GetComponent(dt) - if(old_comp) - switch(dm) - if(COMPONENT_DUPE_UNIQUE) - if(!new_comp) - new_comp = new nt(arglist(args)) - if(!QDELETED(new_comp)) - old_comp.InheritComponent(new_comp, TRUE) - QDEL_NULL(new_comp) - if(COMPONENT_DUPE_HIGHLANDER) - if(!new_comp) - new_comp = new nt(arglist(args)) - if(!QDELETED(new_comp)) - new_comp.InheritComponent(old_comp, FALSE) - QDEL_NULL(old_comp) - if(COMPONENT_DUPE_UNIQUE_PASSARGS) - if(!new_comp) - var/list/arguments = args.Copy(2) - old_comp.InheritComponent(null, TRUE, arguments) - else - old_comp.InheritComponent(new_comp, TRUE) - else if(!new_comp) - new_comp = new nt(arglist(args)) // There's a valid dupe mode but there's no old component, act like normal - else if(!new_comp) - new_comp = new nt(arglist(args)) // Dupes are allowed, act like normal - - if(!old_comp && !QDELETED(new_comp)) // Nothing related to duplicate components happened and the new component is healthy - SEND_SIGNAL(src, COMSIG_COMPONENT_ADDED, new_comp) - return new_comp - return old_comp - -/datum/proc/LoadComponent(component_type, ...) - . = GetComponent(component_type) - if(!.) - return AddComponent(arglist(args)) - -/datum/component/proc/RemoveComponent() - if(!parent) - return - var/datum/old_parent = parent - PreTransfer() - _RemoveFromParent() - parent = null - SEND_SIGNAL(old_parent, COMSIG_COMPONENT_REMOVING, src) - -/datum/proc/TakeComponent(datum/component/target) - if(!target || target.parent == src) - return - if(target.parent) - target.RemoveComponent() - target.parent = src - var/result = target.PostTransfer() - switch(result) - if(COMPONENT_INCOMPATIBLE) - var/c_type = target.type - qdel(target) - CRASH("Incompatible [c_type] transfer attempt to a [type]!") - - if(target == AddComponent(target)) - target._JoinParent() - -/datum/proc/TransferComponents(datum/target) - var/list/dc = datum_components - if(!dc) - return - var/comps = dc[/datum/component] - if(islist(comps)) - for(var/datum/component/I in comps) - if(I.can_transfer) - target.TakeComponent(I) - else - var/datum/component/C = comps - if(C.can_transfer) - target.TakeComponent(comps) - -/datum/component/ui_host() - return parent +/datum/component + var/dupe_mode = COMPONENT_DUPE_HIGHLANDER + var/dupe_type + var/datum/parent + //only set to true if you are able to properly transfer this component + //At a minimum RegisterWithParent and UnregisterFromParent should be used + //Make sure you also implement PostTransfer for any post transfer handling + var/can_transfer = FALSE + +/datum/component/New(datum/P, ...) + parent = P + var/list/arguments = args.Copy(2) + if(Initialize(arglist(arguments)) == COMPONENT_INCOMPATIBLE) + qdel(src, TRUE, TRUE) + CRASH("Incompatible [type] assigned to a [P.type]! args: [json_encode(arguments)]") + + _JoinParent(P) + +/datum/component/proc/_JoinParent() + var/datum/P = parent + //lazy init the parent's dc list + var/list/dc = P.datum_components + if(!dc) + P.datum_components = dc = list() + + //set up the typecache + var/our_type = type + for(var/I in _GetInverseTypeList(our_type)) + var/test = dc[I] + if(test) //already another component of this type here + var/list/components_of_type + if(!length(test)) + components_of_type = list(test) + dc[I] = components_of_type + else + components_of_type = test + if(I == our_type) //exact match, take priority + var/inserted = FALSE + for(var/J in 1 to components_of_type.len) + var/datum/component/C = components_of_type[J] + if(C.type != our_type) //but not over other exact matches + components_of_type.Insert(J, I) + inserted = TRUE + break + if(!inserted) + components_of_type += src + else //indirect match, back of the line with ya + components_of_type += src + else //only component of this type, no list + dc[I] = src + + RegisterWithParent() + +// If you want/expect to be moving the component around between parents, use this to register on the parent for signals +/datum/component/proc/RegisterWithParent() + SEND_SIGNAL(src, COMSIG_COMPONENT_REGISTER_PARENT) //CITADEL EDIT + +/datum/component/proc/Initialize(...) + return + +/datum/component/Destroy(force=FALSE, silent=FALSE) + if(!force && parent) + _RemoveFromParent() + if(!silent) + SEND_SIGNAL(parent, COMSIG_COMPONENT_REMOVING, src) + parent = null + return ..() + +/datum/component/proc/_RemoveFromParent() + var/datum/P = parent + var/list/dc = P.datum_components + for(var/I in _GetInverseTypeList()) + var/list/components_of_type = dc[I] + if(length(components_of_type)) // + var/list/subtracted = components_of_type - src + if(subtracted.len == 1) //only 1 guy left + dc[I] = subtracted[1] //make him special + else + dc[I] = subtracted + else //just us + dc -= I + if(!dc.len) + P.datum_components = null + + UnregisterFromParent() + +/datum/component/proc/UnregisterFromParent() + SEND_SIGNAL(src, COMSIG_COMPONENT_UNREGISTER_PARENT) //CITADEL EDIT + +/datum/proc/RegisterSignal(datum/target, sig_type_or_types, proctype, override = FALSE) + if(QDELETED(src) || QDELETED(target)) + return + + var/list/procs = signal_procs + if(!procs) + signal_procs = procs = list() + if(!procs[target]) + procs[target] = list() + var/list/lookup = target.comp_lookup + if(!lookup) + target.comp_lookup = lookup = list() + + var/list/sig_types = islist(sig_type_or_types) ? sig_type_or_types : list(sig_type_or_types) + for(var/sig_type in sig_types) + if(!override && procs[target][sig_type]) + stack_trace("[sig_type] overridden. Use override = TRUE to suppress this warning") + + procs[target][sig_type] = proctype + + if(!lookup[sig_type]) // Nothing has registered here yet + lookup[sig_type] = src + else if(lookup[sig_type] == src) // We already registered here + continue + else if(!length(lookup[sig_type])) // One other thing registered here + lookup[sig_type] = list(lookup[sig_type]=TRUE) + lookup[sig_type][src] = TRUE + else // Many other things have registered here + lookup[sig_type][src] = TRUE + + signal_enabled = TRUE + +/datum/proc/UnregisterSignal(datum/target, sig_type_or_types) + var/list/lookup = target.comp_lookup + if(!signal_procs || !signal_procs[target] || !lookup) + return + if(!islist(sig_type_or_types)) + sig_type_or_types = list(sig_type_or_types) + for(var/sig in sig_type_or_types) + switch(length(lookup[sig])) + if(2) + lookup[sig] = (lookup[sig]-src)[1] + if(1) + stack_trace("[target] ([target.type]) somehow has single length list inside comp_lookup") + if(src in lookup[sig]) + lookup -= sig + if(!length(lookup)) + target.comp_lookup = null + break + if(0) + lookup -= sig + if(!length(lookup)) + target.comp_lookup = null + break + else + lookup[sig] -= src + + signal_procs[target] -= sig_type_or_types + if(!signal_procs[target].len) + signal_procs -= target + +/datum/component/proc/InheritComponent(datum/component/C, i_am_original) + return + +/datum/component/proc/PreTransfer() + return + +/datum/component/proc/PostTransfer() + return COMPONENT_INCOMPATIBLE //Do not support transfer by default as you must properly support it + +/datum/component/proc/_GetInverseTypeList(our_type = type) + //we can do this one simple trick + var/current_type = parent_type + . = list(our_type, current_type) + //and since most components are root level + 1, this won't even have to run + while (current_type != /datum/component) + current_type = type2parent(current_type) + . += current_type + +/datum/proc/_SendSignal(sigtype, list/arguments) + var/target = comp_lookup[sigtype] + if(!length(target)) + var/datum/C = target + if(!C.signal_enabled) + return NONE + var/proctype = C.signal_procs[src][sigtype] + return NONE | CallAsync(C, proctype, arguments) + . = NONE + for(var/I in target) + var/datum/C = I + if(!C.signal_enabled) + continue + var/proctype = C.signal_procs[src][sigtype] + . |= CallAsync(C, proctype, arguments) + +// The type arg is casted so initial works, you shouldn't be passing a real instance into this +/datum/proc/GetComponent(datum/component/c_type) + RETURN_TYPE(c_type) + if(initial(c_type.dupe_mode) == COMPONENT_DUPE_ALLOWED) + stack_trace("GetComponent was called to get a component of which multiple copies could be on an object. This can easily break and should be changed. Type: \[[c_type]\]") + var/list/dc = datum_components + if(!dc) + return null + . = dc[c_type] + if(length(.)) + return .[1] + +/datum/proc/GetExactComponent(c_type) + var/list/dc = datum_components + if(!dc) + return null + var/datum/component/C = dc[c_type] + if(C) + if(length(C)) + C = C[1] + if(C.type == c_type) + return C + return null + +/datum/proc/GetComponents(c_type) + var/list/dc = datum_components + if(!dc) + return null + . = dc[c_type] + if(!length(.)) + return list(.) + +/datum/proc/AddComponent(new_type, ...) + var/datum/component/nt = new_type + var/dm = initial(nt.dupe_mode) + var/dt = initial(nt.dupe_type) + + var/datum/component/old_comp + var/datum/component/new_comp + + if(ispath(nt)) + if(nt == /datum/component) + CRASH("[nt] attempted instantiation!") + else + new_comp = nt + nt = new_comp.type + + args[1] = src + + if(dm != COMPONENT_DUPE_ALLOWED) + if(!dt) + old_comp = GetExactComponent(nt) + else + old_comp = GetComponent(dt) + if(old_comp) + switch(dm) + if(COMPONENT_DUPE_UNIQUE) + if(!new_comp) + new_comp = new nt(arglist(args)) + if(!QDELETED(new_comp)) + old_comp.InheritComponent(new_comp, TRUE) + QDEL_NULL(new_comp) + if(COMPONENT_DUPE_HIGHLANDER) + if(!new_comp) + new_comp = new nt(arglist(args)) + if(!QDELETED(new_comp)) + new_comp.InheritComponent(old_comp, FALSE) + QDEL_NULL(old_comp) + if(COMPONENT_DUPE_UNIQUE_PASSARGS) + if(!new_comp) + var/list/arguments = args.Copy(2) + old_comp.InheritComponent(null, TRUE, arguments) + else + old_comp.InheritComponent(new_comp, TRUE) + else if(!new_comp) + new_comp = new nt(arglist(args)) // There's a valid dupe mode but there's no old component, act like normal + else if(!new_comp) + new_comp = new nt(arglist(args)) // Dupes are allowed, act like normal + + if(!old_comp && !QDELETED(new_comp)) // Nothing related to duplicate components happened and the new component is healthy + SEND_SIGNAL(src, COMSIG_COMPONENT_ADDED, new_comp) + return new_comp + return old_comp + +/datum/proc/LoadComponent(component_type, ...) + . = GetComponent(component_type) + if(!.) + return AddComponent(arglist(args)) + +/datum/component/proc/RemoveComponent() + if(!parent) + return + var/datum/old_parent = parent + PreTransfer() + _RemoveFromParent() + parent = null + SEND_SIGNAL(old_parent, COMSIG_COMPONENT_REMOVING, src) + +/datum/proc/TakeComponent(datum/component/target) + if(!target || target.parent == src) + return + if(target.parent) + target.RemoveComponent() + target.parent = src + var/result = target.PostTransfer() + switch(result) + if(COMPONENT_INCOMPATIBLE) + var/c_type = target.type + qdel(target) + CRASH("Incompatible [c_type] transfer attempt to a [type]!") + + if(target == AddComponent(target)) + target._JoinParent() + +/datum/proc/TransferComponents(datum/target) + var/list/dc = datum_components + if(!dc) + return + var/comps = dc[/datum/component] + if(islist(comps)) + for(var/datum/component/I in comps) + if(I.can_transfer) + target.TakeComponent(I) + else + var/datum/component/C = comps + if(C.can_transfer) + target.TakeComponent(comps) + +/datum/component/ui_host() + return parent diff --git a/code/datums/components/jousting.dm b/code/datums/components/jousting.dm index 08f3c1d643..da2ff1b177 100644 --- a/code/datums/components/jousting.dm +++ b/code/datums/components/jousting.dm @@ -1,74 +1,74 @@ -/datum/component/jousting - var/current_direction = NONE - var/max_tile_charge = 5 - var/min_tile_charge = 2 //tiles before this code gets into effect. - var/current_tile_charge = 0 - var/movement_reset_tolerance = 2 //deciseconds - var/unmounted_damage_boost_per_tile = 0 - var/unmounted_knockdown_chance_per_tile = 0 - var/unmounted_knockdown_time = 0 - var/mounted_damage_boost_per_tile = 2 - var/mounted_knockdown_chance_per_tile = 20 - var/mounted_knockdown_time = 20 - var/requires_mob_riding = TRUE //whether this only works if the attacker is riding a mob, rather than anything they can buckle to. - var/requires_mount = TRUE //kinda defeats the point of jousting if you're not mounted but whatever. - var/mob/current_holder - var/current_timerid - -/datum/component/jousting/Initialize() - if(!isitem(parent)) - return COMPONENT_INCOMPATIBLE - RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip) - RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop) - RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/on_attack) - -/datum/component/jousting/proc/on_equip(datum/source, mob/user, slot) - RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/mob_move, TRUE) - current_holder = user - -/datum/component/jousting/proc/on_drop(datum/source, mob/user) - UnregisterSignal(user, COMSIG_MOVABLE_MOVED) - current_holder = null - current_direction = NONE - current_tile_charge = 0 - -/datum/component/jousting/proc/on_attack(datum/source, mob/living/target, mob/user) - if(user != current_holder) - return - var/current = current_tile_charge - var/obj/item/I = parent - var/target_buckled = target.buckled ? TRUE : FALSE //we don't need the reference of what they're buckled to, just whether they are. - if((requires_mount && ((requires_mob_riding && !ismob(user.buckled)) || (!user.buckled))) || !current_direction || (current_tile_charge < min_tile_charge)) - return - var/turf/target_turf = get_step(user, current_direction) - if(target in range(1, target_turf)) - var/knockdown_chance = (target_buckled? mounted_knockdown_chance_per_tile : unmounted_knockdown_chance_per_tile) * current - var/knockdown_time = (target_buckled? mounted_knockdown_time : unmounted_knockdown_time) - var/damage = (target_buckled? mounted_damage_boost_per_tile : unmounted_damage_boost_per_tile) * current - var/sharp = I.get_sharpness() - var/msg - if(damage) - msg += "[user] [sharp? "impales" : "slams into"] [target] [sharp? "on" : "with"] their [parent]" - target.apply_damage(damage, BRUTE, user.zone_selected, 0) - if(prob(knockdown_chance)) - msg += " and knocks [target] [target_buckled? "off of [target.buckled]" : "down"]" - if(target_buckled) - target.buckled.unbuckle_mob(target) - target.Knockdown(knockdown_time) - if(length(msg)) - user.visible_message("[msg]!") - -/datum/component/jousting/proc/mob_move(datum/source, newloc, dir) - if(!current_holder || (requires_mount && ((requires_mob_riding && !ismob(current_holder.buckled)) || (!current_holder.buckled)))) - return - if(dir != current_direction) - current_tile_charge = 0 - current_direction = dir - if(current_tile_charge < max_tile_charge) - current_tile_charge++ - if(current_timerid) - deltimer(current_timerid) - current_timerid = addtimer(CALLBACK(src, .proc/reset_charge), movement_reset_tolerance, TIMER_STOPPABLE) - -/datum/component/jousting/proc/reset_charge() - current_tile_charge = 0 +/datum/component/jousting + var/current_direction = NONE + var/max_tile_charge = 5 + var/min_tile_charge = 2 //tiles before this code gets into effect. + var/current_tile_charge = 0 + var/movement_reset_tolerance = 2 //deciseconds + var/unmounted_damage_boost_per_tile = 0 + var/unmounted_knockdown_chance_per_tile = 0 + var/unmounted_knockdown_time = 0 + var/mounted_damage_boost_per_tile = 2 + var/mounted_knockdown_chance_per_tile = 20 + var/mounted_knockdown_time = 20 + var/requires_mob_riding = TRUE //whether this only works if the attacker is riding a mob, rather than anything they can buckle to. + var/requires_mount = TRUE //kinda defeats the point of jousting if you're not mounted but whatever. + var/mob/current_holder + var/current_timerid + +/datum/component/jousting/Initialize() + if(!isitem(parent)) + return COMPONENT_INCOMPATIBLE + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip) + RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop) + RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/on_attack) + +/datum/component/jousting/proc/on_equip(datum/source, mob/user, slot) + RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/mob_move, TRUE) + current_holder = user + +/datum/component/jousting/proc/on_drop(datum/source, mob/user) + UnregisterSignal(user, COMSIG_MOVABLE_MOVED) + current_holder = null + current_direction = NONE + current_tile_charge = 0 + +/datum/component/jousting/proc/on_attack(datum/source, mob/living/target, mob/user) + if(user != current_holder) + return + var/current = current_tile_charge + var/obj/item/I = parent + var/target_buckled = target.buckled ? TRUE : FALSE //we don't need the reference of what they're buckled to, just whether they are. + if((requires_mount && ((requires_mob_riding && !ismob(user.buckled)) || (!user.buckled))) || !current_direction || (current_tile_charge < min_tile_charge)) + return + var/turf/target_turf = get_step(user, current_direction) + if(target in range(1, target_turf)) + var/knockdown_chance = (target_buckled? mounted_knockdown_chance_per_tile : unmounted_knockdown_chance_per_tile) * current + var/knockdown_time = (target_buckled? mounted_knockdown_time : unmounted_knockdown_time) + var/damage = (target_buckled? mounted_damage_boost_per_tile : unmounted_damage_boost_per_tile) * current + var/sharp = I.get_sharpness() + var/msg + if(damage) + msg += "[user] [sharp? "impales" : "slams into"] [target] [sharp? "on" : "with"] their [parent]" + target.apply_damage(damage, BRUTE, user.zone_selected, 0) + if(prob(knockdown_chance)) + msg += " and knocks [target] [target_buckled? "off of [target.buckled]" : "down"]" + if(target_buckled) + target.buckled.unbuckle_mob(target) + target.Knockdown(knockdown_time) + if(length(msg)) + user.visible_message("[msg]!") + +/datum/component/jousting/proc/mob_move(datum/source, newloc, dir) + if(!current_holder || (requires_mount && ((requires_mob_riding && !ismob(current_holder.buckled)) || (!current_holder.buckled)))) + return + if(dir != current_direction) + current_tile_charge = 0 + current_direction = dir + if(current_tile_charge < max_tile_charge) + current_tile_charge++ + if(current_timerid) + deltimer(current_timerid) + current_timerid = addtimer(CALLBACK(src, .proc/reset_charge), movement_reset_tolerance, TIMER_STOPPABLE) + +/datum/component/jousting/proc/reset_charge() + current_tile_charge = 0 diff --git a/code/datums/components/lockon_aiming.dm b/code/datums/components/lockon_aiming.dm index bbdbb7dc66..045611ab9d 100644 --- a/code/datums/components/lockon_aiming.dm +++ b/code/datums/components/lockon_aiming.dm @@ -1,239 +1,239 @@ -#define LOCKON_AIMING_MAX_CURSOR_RADIUS 7 -#define LOCKON_IGNORE_RESULT "ignore_my_result" -#define LOCKON_RANGING_BREAK_CHECK if(current_ranging_id != this_id){return LOCKON_IGNORE_RESULT} - -/datum/component/lockon_aiming - dupe_mode = COMPONENT_DUPE_ALLOWED - var/lock_icon = 'icons/mob/cameramob.dmi' - var/lock_icon_state = "marker" - var/mutable_appearance/lock_appearance - var/list/image/lock_images - var/list/target_typecache - var/list/immune_weakrefs //list(weakref = TRUE) - var/mob_stat_check = TRUE //if a potential target is a mob make sure it's conscious! - var/lock_amount = 1 - var/lock_cursor_range = 5 - var/list/locked_weakrefs - var/update_disabled = FALSE - var/current_ranging_id = 0 - var/list/last_location - var/datum/callback/on_lock - var/datum/callback/can_target_callback - -/datum/component/lockon_aiming/Initialize(range, list/typecache, amount, list/immune, datum/callback/when_locked, icon, icon_state, datum/callback/target_callback) - if(!ismob(parent)) - return COMPONENT_INCOMPATIBLE - if(target_callback) - can_target_callback = target_callback - else - can_target_callback = CALLBACK(src, .proc/can_target) - if(range) - lock_cursor_range = range - if(typecache) - target_typecache = typecache - if(amount) - lock_amount = amount - immune_weakrefs = list(WEAKREF(parent) = TRUE) //Manually take this out if you want.. - if(immune) - for(var/i in immune) - if(isweakref(i)) - immune_weakrefs[i] = TRUE - else if(isatom(i)) - immune_weakrefs[WEAKREF(i)] = TRUE - if(when_locked) - on_lock = when_locked - if(icon) - lock_icon = icon - if(icon_state) - lock_icon_state = icon_state - generate_lock_visuals() - var/mob/M = parent - LAZYOR(M.mousemove_intercept_objects, src) - START_PROCESSING(SSfastprocess, src) - -/datum/component/lockon_aiming/Destroy() - var/mob/M = parent - clear_visuals() - LAZYREMOVE(M.mousemove_intercept_objects, src) - STOP_PROCESSING(SSfastprocess, src) - return ..() - -/datum/component/lockon_aiming/proc/show_visuals() - LAZYINITLIST(lock_images) - var/mob/M = parent - if(!M.client) - return - for(var/i in locked_weakrefs) - var/datum/weakref/R = i - var/atom/A = R.resolve() - if(!A) - continue //It'll be cleared by processing. - var/image/I = new - I.appearance = lock_appearance - I.loc = A - M.client.images |= I - lock_images |= I - -/datum/component/lockon_aiming/proc/clear_visuals() - var/mob/M = parent - if(!M.client) - return - if(!lock_images) - return - for(var/i in lock_images) - M.client.images -= i - qdel(i) - lock_images.Cut() - -/datum/component/lockon_aiming/proc/refresh_visuals() - clear_visuals() - show_visuals() - -/datum/component/lockon_aiming/proc/generate_lock_visuals() - lock_appearance = mutable_appearance(icon = lock_icon, icon_state = lock_icon_state, layer = FLOAT_LAYER) - -/datum/component/lockon_aiming/proc/unlock_all(refresh_vis = TRUE) - LAZYCLEARLIST(locked_weakrefs) - if(refresh_vis) - refresh_visuals() - -/datum/component/lockon_aiming/proc/unlock(atom/A, refresh_vis = TRUE) - if(!A.weak_reference) - return - LAZYREMOVE(locked_weakrefs, A.weak_reference) - if(refresh_vis) - refresh_visuals() - -/datum/component/lockon_aiming/proc/lock(atom/A, refresh_vis = TRUE) - LAZYOR(locked_weakrefs, WEAKREF(A)) - if(refresh_vis) - refresh_visuals() - -/datum/component/lockon_aiming/proc/add_immune_atom(atom/A) - var/datum/weakref/R = WEAKREF(A) - if(immune_weakrefs && (immune_weakrefs[R])) - return - LAZYSET(immune_weakrefs, R, TRUE) - -/datum/component/lockon_aiming/proc/remove_immune_atom(atom/A) - if(!A.weak_reference || !immune_weakrefs) //if A doesn't have a weakref how did it get on the immunity list? - return - LAZYREMOVE(immune_weakrefs, A.weak_reference) - -/datum/component/lockon_aiming/onMouseMove(object,location,control,params) - var/mob/M = parent - if(!istype(M) || !M.client) - return - var/datum/position/P = mouse_absolute_datum_map_position_from_client(M.client) - if(!P) - return - var/turf/T = P.return_turf() - LAZYINITLIST(last_location) - if(length(last_location) == 3 && last_location[1] == T.x && last_location[2] == T.y && last_location[3] == T.z) - return //Same turf, don't bother. - if(last_location) - last_location.Cut() - else - last_location = list() - last_location.len = 3 - last_location[1] = T.x - last_location[2] = T.y - last_location[3] = T.z - autolock() - -/datum/component/lockon_aiming/process() - if(update_disabled) - return - if(!last_location) - return - var/changed = FALSE - for(var/i in locked_weakrefs) - var/datum/weakref/R = i - if(istype(R)) - var/atom/thing = R.resolve() - if(!istype(thing) || (get_dist(thing, locate(last_location[1], last_location[2], last_location[3])) > lock_cursor_range)) - unlock(R) - changed = TRUE - else - unlock(R) - changed = TRUE - if(changed) - autolock() - -/datum/component/lockon_aiming/proc/autolock() - var/mob/M = parent - if(!M.client) - return FALSE - var/datum/position/current = mouse_absolute_datum_map_position_from_client(M.client) - var/turf/target = current.return_turf() - var/list/atom/targets = get_nearest(target, target_typecache, lock_amount, lock_cursor_range) - if(targets == LOCKON_IGNORE_RESULT) - return - unlock_all(FALSE) - for(var/i in targets) - if(immune_weakrefs[WEAKREF(i)]) - continue - lock(i, FALSE) - refresh_visuals() - on_lock.Invoke(locked_weakrefs) - -/datum/component/lockon_aiming/proc/can_target(atom/A) - var/mob/M = A - return is_type_in_typecache(A, target_typecache) && !(ismob(A) && mob_stat_check && M.stat != CONSCIOUS) && !immune_weakrefs[WEAKREF(A)] - -/datum/component/lockon_aiming/proc/get_nearest(turf/T, list/typecache, amount, range) - current_ranging_id++ - var/this_id = current_ranging_id - var/list/L = list() - var/turf/center = get_turf(T) - if(amount < 1 || range < 0 || !istype(center) || !islist(typecache)) - return - if(range == 0) - return typecache_filter_list(T.contents + T, typecache) - var/x = 0 - var/y = 0 - var/cd = 0 - while(cd <= range) - x = center.x - cd + 1 - y = center.y + cd - LOCKON_RANGING_BREAK_CHECK - for(x in x to center.x + cd) - T = locate(x, y, center.z) - if(T) - L |= special_list_filter(T.contents, can_target_callback) - if(L.len >= amount) - L.Cut(amount+1) - return L - LOCKON_RANGING_BREAK_CHECK - y = center.y + cd - 1 - x = center.x + cd - for(y in center.y - cd to y) - T = locate(x, y, center.z) - if(T) - L |= special_list_filter(T.contents, can_target_callback) - if(L.len >= amount) - L.Cut(amount+1) - return L - LOCKON_RANGING_BREAK_CHECK - y = center.y - cd - x = center.x + cd - 1 - for(x in center.x - cd to x) - T = locate(x, y, center.z) - if(T) - L |= special_list_filter(T.contents, can_target_callback) - if(L.len >= amount) - L.Cut(amount+1) - return L - LOCKON_RANGING_BREAK_CHECK - y = center.y - cd + 1 - x = center.x - cd - for(y in y to center.y + cd) - T = locate(x, y, center.z) - if(T) - L |= special_list_filter(T.contents, can_target_callback) - if(L.len >= amount) - L.Cut(amount+1) - return L - LOCKON_RANGING_BREAK_CHECK - cd++ - CHECK_TICK +#define LOCKON_AIMING_MAX_CURSOR_RADIUS 7 +#define LOCKON_IGNORE_RESULT "ignore_my_result" +#define LOCKON_RANGING_BREAK_CHECK if(current_ranging_id != this_id){return LOCKON_IGNORE_RESULT} + +/datum/component/lockon_aiming + dupe_mode = COMPONENT_DUPE_ALLOWED + var/lock_icon = 'icons/mob/cameramob.dmi' + var/lock_icon_state = "marker" + var/mutable_appearance/lock_appearance + var/list/image/lock_images + var/list/target_typecache + var/list/immune_weakrefs //list(weakref = TRUE) + var/mob_stat_check = TRUE //if a potential target is a mob make sure it's conscious! + var/lock_amount = 1 + var/lock_cursor_range = 5 + var/list/locked_weakrefs + var/update_disabled = FALSE + var/current_ranging_id = 0 + var/list/last_location + var/datum/callback/on_lock + var/datum/callback/can_target_callback + +/datum/component/lockon_aiming/Initialize(range, list/typecache, amount, list/immune, datum/callback/when_locked, icon, icon_state, datum/callback/target_callback) + if(!ismob(parent)) + return COMPONENT_INCOMPATIBLE + if(target_callback) + can_target_callback = target_callback + else + can_target_callback = CALLBACK(src, .proc/can_target) + if(range) + lock_cursor_range = range + if(typecache) + target_typecache = typecache + if(amount) + lock_amount = amount + immune_weakrefs = list(WEAKREF(parent) = TRUE) //Manually take this out if you want.. + if(immune) + for(var/i in immune) + if(isweakref(i)) + immune_weakrefs[i] = TRUE + else if(isatom(i)) + immune_weakrefs[WEAKREF(i)] = TRUE + if(when_locked) + on_lock = when_locked + if(icon) + lock_icon = icon + if(icon_state) + lock_icon_state = icon_state + generate_lock_visuals() + var/mob/M = parent + LAZYOR(M.mousemove_intercept_objects, src) + START_PROCESSING(SSfastprocess, src) + +/datum/component/lockon_aiming/Destroy() + var/mob/M = parent + clear_visuals() + LAZYREMOVE(M.mousemove_intercept_objects, src) + STOP_PROCESSING(SSfastprocess, src) + return ..() + +/datum/component/lockon_aiming/proc/show_visuals() + LAZYINITLIST(lock_images) + var/mob/M = parent + if(!M.client) + return + for(var/i in locked_weakrefs) + var/datum/weakref/R = i + var/atom/A = R.resolve() + if(!A) + continue //It'll be cleared by processing. + var/image/I = new + I.appearance = lock_appearance + I.loc = A + M.client.images |= I + lock_images |= I + +/datum/component/lockon_aiming/proc/clear_visuals() + var/mob/M = parent + if(!M.client) + return + if(!lock_images) + return + for(var/i in lock_images) + M.client.images -= i + qdel(i) + lock_images.Cut() + +/datum/component/lockon_aiming/proc/refresh_visuals() + clear_visuals() + show_visuals() + +/datum/component/lockon_aiming/proc/generate_lock_visuals() + lock_appearance = mutable_appearance(icon = lock_icon, icon_state = lock_icon_state, layer = FLOAT_LAYER) + +/datum/component/lockon_aiming/proc/unlock_all(refresh_vis = TRUE) + LAZYCLEARLIST(locked_weakrefs) + if(refresh_vis) + refresh_visuals() + +/datum/component/lockon_aiming/proc/unlock(atom/A, refresh_vis = TRUE) + if(!A.weak_reference) + return + LAZYREMOVE(locked_weakrefs, A.weak_reference) + if(refresh_vis) + refresh_visuals() + +/datum/component/lockon_aiming/proc/lock(atom/A, refresh_vis = TRUE) + LAZYOR(locked_weakrefs, WEAKREF(A)) + if(refresh_vis) + refresh_visuals() + +/datum/component/lockon_aiming/proc/add_immune_atom(atom/A) + var/datum/weakref/R = WEAKREF(A) + if(immune_weakrefs && (immune_weakrefs[R])) + return + LAZYSET(immune_weakrefs, R, TRUE) + +/datum/component/lockon_aiming/proc/remove_immune_atom(atom/A) + if(!A.weak_reference || !immune_weakrefs) //if A doesn't have a weakref how did it get on the immunity list? + return + LAZYREMOVE(immune_weakrefs, A.weak_reference) + +/datum/component/lockon_aiming/onMouseMove(object,location,control,params) + var/mob/M = parent + if(!istype(M) || !M.client) + return + var/datum/position/P = mouse_absolute_datum_map_position_from_client(M.client) + if(!P) + return + var/turf/T = P.return_turf() + LAZYINITLIST(last_location) + if(length(last_location) == 3 && last_location[1] == T.x && last_location[2] == T.y && last_location[3] == T.z) + return //Same turf, don't bother. + if(last_location) + last_location.Cut() + else + last_location = list() + last_location.len = 3 + last_location[1] = T.x + last_location[2] = T.y + last_location[3] = T.z + autolock() + +/datum/component/lockon_aiming/process() + if(update_disabled) + return + if(!last_location) + return + var/changed = FALSE + for(var/i in locked_weakrefs) + var/datum/weakref/R = i + if(istype(R)) + var/atom/thing = R.resolve() + if(!istype(thing) || (get_dist(thing, locate(last_location[1], last_location[2], last_location[3])) > lock_cursor_range)) + unlock(R) + changed = TRUE + else + unlock(R) + changed = TRUE + if(changed) + autolock() + +/datum/component/lockon_aiming/proc/autolock() + var/mob/M = parent + if(!M.client) + return FALSE + var/datum/position/current = mouse_absolute_datum_map_position_from_client(M.client) + var/turf/target = current.return_turf() + var/list/atom/targets = get_nearest(target, target_typecache, lock_amount, lock_cursor_range) + if(targets == LOCKON_IGNORE_RESULT) + return + unlock_all(FALSE) + for(var/i in targets) + if(immune_weakrefs[WEAKREF(i)]) + continue + lock(i, FALSE) + refresh_visuals() + on_lock.Invoke(locked_weakrefs) + +/datum/component/lockon_aiming/proc/can_target(atom/A) + var/mob/M = A + return is_type_in_typecache(A, target_typecache) && !(ismob(A) && mob_stat_check && M.stat != CONSCIOUS) && !immune_weakrefs[WEAKREF(A)] + +/datum/component/lockon_aiming/proc/get_nearest(turf/T, list/typecache, amount, range) + current_ranging_id++ + var/this_id = current_ranging_id + var/list/L = list() + var/turf/center = get_turf(T) + if(amount < 1 || range < 0 || !istype(center) || !islist(typecache)) + return + if(range == 0) + return typecache_filter_list(T.contents + T, typecache) + var/x = 0 + var/y = 0 + var/cd = 0 + while(cd <= range) + x = center.x - cd + 1 + y = center.y + cd + LOCKON_RANGING_BREAK_CHECK + for(x in x to center.x + cd) + T = locate(x, y, center.z) + if(T) + L |= special_list_filter(T.contents, can_target_callback) + if(L.len >= amount) + L.Cut(amount+1) + return L + LOCKON_RANGING_BREAK_CHECK + y = center.y + cd - 1 + x = center.x + cd + for(y in center.y - cd to y) + T = locate(x, y, center.z) + if(T) + L |= special_list_filter(T.contents, can_target_callback) + if(L.len >= amount) + L.Cut(amount+1) + return L + LOCKON_RANGING_BREAK_CHECK + y = center.y - cd + x = center.x + cd - 1 + for(x in center.x - cd to x) + T = locate(x, y, center.z) + if(T) + L |= special_list_filter(T.contents, can_target_callback) + if(L.len >= amount) + L.Cut(amount+1) + return L + LOCKON_RANGING_BREAK_CHECK + y = center.y - cd + 1 + x = center.x - cd + for(y in y to center.y + cd) + T = locate(x, y, center.z) + if(T) + L |= special_list_filter(T.contents, can_target_callback) + if(L.len >= amount) + L.Cut(amount+1) + return L + LOCKON_RANGING_BREAK_CHECK + cd++ + CHECK_TICK diff --git a/code/datums/components/ntnet_interface.dm b/code/datums/components/ntnet_interface.dm index 7c364a61ab..6159c7c2c4 100644 --- a/code/datums/components/ntnet_interface.dm +++ b/code/datums/components/ntnet_interface.dm @@ -1,68 +1,68 @@ -//Thing meant for allowing datums and objects to access a NTnet network datum. -/datum/proc/ntnet_receive(datum/netdata/data) - return - -/datum/proc/ntnet_receive_broadcast(datum/netdata/data) - return - -/datum/proc/ntnet_send(datum/netdata/data, netid) - var/datum/component/ntnet_interface/NIC = GetComponent(/datum/component/ntnet_interface) - if(!NIC) - return FALSE - return NIC.__network_send(data, netid) - -/datum/component/ntnet_interface - var/hardware_id //text. this is the true ID. do not change this. stuff like ID forgery can be done manually. - var/network_name = "" //text - var/list/networks_connected_by_id = list() //id = datum/ntnet - var/differentiate_broadcast = TRUE //If false, broadcasts go to ntnet_receive. NOT RECOMMENDED. - -/datum/component/ntnet_interface/Initialize(force_name = "NTNet Device", autoconnect_station_network = TRUE) //Don't force ID unless you know what you're doing! - hardware_id = "[SSnetworks.get_next_HID()]" - network_name = force_name - if(!SSnetworks.register_interface(src)) - . = COMPONENT_INCOMPATIBLE - CRASH("Unable to register NTNet interface. Interface deleted.") - if(autoconnect_station_network) - register_connection(SSnetworks.station_network) - -/datum/component/ntnet_interface/Destroy() - unregister_all_connections() - SSnetworks.unregister_interface(src) - return ..() - -/datum/component/ntnet_interface/proc/__network_receive(datum/netdata/data) //Do not directly proccall! - SEND_SIGNAL(parent, COMSIG_COMPONENT_NTNET_RECEIVE, data) - if(differentiate_broadcast && data.broadcast) - parent.ntnet_receive_broadcast(data) - else - parent.ntnet_receive(data) - -/datum/component/ntnet_interface/proc/__network_send(datum/netdata/data, netid) //Do not directly proccall! - // Process data before sending it - data.pre_send(src) - - if(netid) - if(networks_connected_by_id[netid]) - var/datum/ntnet/net = networks_connected_by_id[netid] - return net.process_data_transmit(src, data) - return FALSE - for(var/i in networks_connected_by_id) - var/datum/ntnet/net = networks_connected_by_id[i] - net.process_data_transmit(src, data) - return TRUE - -/datum/component/ntnet_interface/proc/register_connection(datum/ntnet/net) - if(net.interface_connect(src)) - networks_connected_by_id[net.network_id] = net - return TRUE - -/datum/component/ntnet_interface/proc/unregister_all_connections() - for(var/i in networks_connected_by_id) - unregister_connection(networks_connected_by_id[i]) - return TRUE - -/datum/component/ntnet_interface/proc/unregister_connection(datum/ntnet/net) - net.interface_disconnect(src) - networks_connected_by_id -= net.network_id - return TRUE +//Thing meant for allowing datums and objects to access a NTnet network datum. +/datum/proc/ntnet_receive(datum/netdata/data) + return + +/datum/proc/ntnet_receive_broadcast(datum/netdata/data) + return + +/datum/proc/ntnet_send(datum/netdata/data, netid) + var/datum/component/ntnet_interface/NIC = GetComponent(/datum/component/ntnet_interface) + if(!NIC) + return FALSE + return NIC.__network_send(data, netid) + +/datum/component/ntnet_interface + var/hardware_id //text. this is the true ID. do not change this. stuff like ID forgery can be done manually. + var/network_name = "" //text + var/list/networks_connected_by_id = list() //id = datum/ntnet + var/differentiate_broadcast = TRUE //If false, broadcasts go to ntnet_receive. NOT RECOMMENDED. + +/datum/component/ntnet_interface/Initialize(force_name = "NTNet Device", autoconnect_station_network = TRUE) //Don't force ID unless you know what you're doing! + hardware_id = "[SSnetworks.get_next_HID()]" + network_name = force_name + if(!SSnetworks.register_interface(src)) + . = COMPONENT_INCOMPATIBLE + CRASH("Unable to register NTNet interface. Interface deleted.") + if(autoconnect_station_network) + register_connection(SSnetworks.station_network) + +/datum/component/ntnet_interface/Destroy() + unregister_all_connections() + SSnetworks.unregister_interface(src) + return ..() + +/datum/component/ntnet_interface/proc/__network_receive(datum/netdata/data) //Do not directly proccall! + SEND_SIGNAL(parent, COMSIG_COMPONENT_NTNET_RECEIVE, data) + if(differentiate_broadcast && data.broadcast) + parent.ntnet_receive_broadcast(data) + else + parent.ntnet_receive(data) + +/datum/component/ntnet_interface/proc/__network_send(datum/netdata/data, netid) //Do not directly proccall! + // Process data before sending it + data.pre_send(src) + + if(netid) + if(networks_connected_by_id[netid]) + var/datum/ntnet/net = networks_connected_by_id[netid] + return net.process_data_transmit(src, data) + return FALSE + for(var/i in networks_connected_by_id) + var/datum/ntnet/net = networks_connected_by_id[i] + net.process_data_transmit(src, data) + return TRUE + +/datum/component/ntnet_interface/proc/register_connection(datum/ntnet/net) + if(net.interface_connect(src)) + networks_connected_by_id[net.network_id] = net + return TRUE + +/datum/component/ntnet_interface/proc/unregister_all_connections() + for(var/i in networks_connected_by_id) + unregister_connection(networks_connected_by_id[i]) + return TRUE + +/datum/component/ntnet_interface/proc/unregister_connection(datum/ntnet/net) + net.interface_disconnect(src) + networks_connected_by_id -= net.network_id + return TRUE diff --git a/code/datums/components/riding.dm b/code/datums/components/riding.dm index c05b07a693..0775a725b9 100644 --- a/code/datums/components/riding.dm +++ b/code/datums/components/riding.dm @@ -1,359 +1,359 @@ -/datum/component/riding - var/last_vehicle_move = 0 //used for move delays - var/last_move_diagonal = FALSE - var/vehicle_move_delay = 2 //tick delay between movements, lower = faster, higher = slower - var/keytype - - var/slowed = FALSE - var/slowvalue = 1 - - var/list/riding_offsets = list() //position_of_user = list(dir = list(px, py)), or RIDING_OFFSET_ALL for a generic one. - var/list/directional_vehicle_layers = list() //["[DIRECTION]"] = layer. Don't set it for a direction for default, set a direction to null for no change. - var/list/directional_vehicle_offsets = list() //same as above but instead of layer you have a list(px, py) - var/list/allowed_turf_typecache - var/list/forbid_turf_typecache //allow typecache for only certain turfs, forbid to allow all but those. allow only certain turfs will take precedence. - var/allow_one_away_from_valid_turf = TRUE //allow moving one tile away from a valid turf but not more. - var/override_allow_spacemove = FALSE - var/drive_verb = "drive" - var/ride_check_rider_incapacitated = FALSE - var/ride_check_rider_restrained = FALSE - var/ride_check_ridden_incapacitated = FALSE - var/list/offhands = list() // keyed list containing all the current riding offsets associated by mob - -/datum/component/riding/Initialize() - if(!ismovableatom(parent)) - return COMPONENT_INCOMPATIBLE - RegisterSignal(parent, COMSIG_MOVABLE_BUCKLE, .proc/vehicle_mob_buckle) - RegisterSignal(parent, COMSIG_MOVABLE_UNBUCKLE, .proc/vehicle_mob_unbuckle) - RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/vehicle_moved) - -/datum/component/riding/proc/vehicle_mob_unbuckle(datum/source, mob/living/M, force = FALSE) - restore_position(M) - unequip_buckle_inhands(M) - -/datum/component/riding/proc/vehicle_mob_buckle(datum/source, mob/living/M, force = FALSE) - handle_vehicle_offsets() - -/datum/component/riding/proc/handle_vehicle_layer() - var/atom/movable/AM = parent - var/static/list/defaults = list(TEXT_NORTH = OBJ_LAYER, TEXT_SOUTH = ABOVE_MOB_LAYER, TEXT_EAST = ABOVE_MOB_LAYER, TEXT_WEST = ABOVE_MOB_LAYER) - . = defaults["[AM.dir]"] - if(directional_vehicle_layers["[AM.dir]"]) - . = directional_vehicle_layers["[AM.dir]"] - if(isnull(.)) //you can set it to null to not change it. - . = AM.layer - AM.layer = . - -/datum/component/riding/proc/set_vehicle_dir_layer(dir, layer) - directional_vehicle_layers["[dir]"] = layer - -/datum/component/riding/proc/vehicle_moved(datum/source) - var/atom/movable/AM = parent - for(var/i in AM.buckled_mobs) - ride_check(i) - handle_vehicle_offsets() - handle_vehicle_layer() - -/datum/component/riding/proc/ride_check(mob/living/M) - var/atom/movable/AM = parent - var/mob/AMM = AM - if((ride_check_rider_restrained && M.restrained(TRUE)) || (ride_check_rider_incapacitated && M.incapacitated(FALSE, TRUE)) || (ride_check_ridden_incapacitated && istype(AMM) && AMM.incapacitated(FALSE, TRUE))) - AM.visible_message("[M] falls off of [AM]!") - AM.unbuckle_mob(M) - return TRUE - -/datum/component/riding/proc/force_dismount(mob/living/M) - var/atom/movable/AM = parent - AM.unbuckle_mob(M) - -/datum/component/riding/proc/handle_vehicle_offsets() - var/atom/movable/AM = parent - var/AM_dir = "[AM.dir]" - var/passindex = 0 - if(AM.has_buckled_mobs()) - for(var/m in AM.buckled_mobs) - passindex++ - var/mob/living/buckled_mob = m - var/list/offsets = get_offsets(passindex) - var/rider_dir = get_rider_dir(passindex) - buckled_mob.setDir(rider_dir) - dir_loop: - for(var/offsetdir in offsets) - if(offsetdir == AM_dir) - var/list/diroffsets = offsets[offsetdir] - buckled_mob.pixel_x = diroffsets[1] - if(diroffsets.len >= 2) - buckled_mob.pixel_y = diroffsets[2] - if(diroffsets.len == 3) - buckled_mob.layer = diroffsets[3] - break dir_loop - var/list/static/default_vehicle_pixel_offsets = list(TEXT_NORTH = list(0, 0), TEXT_SOUTH = list(0, 0), TEXT_EAST = list(0, 0), TEXT_WEST = list(0, 0)) - var/px = default_vehicle_pixel_offsets[AM_dir] - var/py = default_vehicle_pixel_offsets[AM_dir] - if(directional_vehicle_offsets[AM_dir]) - if(isnull(directional_vehicle_offsets[AM_dir])) - px = AM.pixel_x - py = AM.pixel_y - else - px = directional_vehicle_offsets[AM_dir][1] - py = directional_vehicle_offsets[AM_dir][2] - AM.pixel_x = px - AM.pixel_y = py - -/datum/component/riding/proc/set_vehicle_dir_offsets(dir, x, y) - directional_vehicle_offsets["[dir]"] = list(x, y) - -//Override this to set your vehicle's various pixel offsets -/datum/component/riding/proc/get_offsets(pass_index) // list(dir = x, y, layer) - . = list(TEXT_NORTH = list(0, 0), TEXT_SOUTH = list(0, 0), TEXT_EAST = list(0, 0), TEXT_WEST = list(0, 0)) - if(riding_offsets["[pass_index]"]) - . = riding_offsets["[pass_index]"] - else if(riding_offsets["[RIDING_OFFSET_ALL]"]) - . = riding_offsets["[RIDING_OFFSET_ALL]"] - -/datum/component/riding/proc/set_riding_offsets(index, list/offsets) - if(!islist(offsets)) - return FALSE - riding_offsets["[index]"] = offsets - -//Override this to set the passengers/riders dir based on which passenger they are. -//ie: rider facing the vehicle's dir, but passenger 2 facing backwards, etc. -/datum/component/riding/proc/get_rider_dir(pass_index) - var/atom/movable/AM = parent - return AM.dir - -//KEYS -/datum/component/riding/proc/keycheck(mob/user) - return !keytype || user.is_holding_item_of_type(keytype) - -//BUCKLE HOOKS -/datum/component/riding/proc/restore_position(mob/living/buckled_mob) - if(buckled_mob) - buckled_mob.pixel_x = 0 - buckled_mob.pixel_y = 0 - if(buckled_mob.client) - buckled_mob.client.change_view(CONFIG_GET(string/default_view)) - -//MOVEMENT -/datum/component/riding/proc/turf_check(turf/next, turf/current) - if(allowed_turf_typecache && !allowed_turf_typecache[next.type]) - return (allow_one_away_from_valid_turf && allowed_turf_typecache[current.type]) - else if(forbid_turf_typecache && forbid_turf_typecache[next.type]) - return (allow_one_away_from_valid_turf && !forbid_turf_typecache[current.type]) - return TRUE - -/datum/component/riding/proc/handle_ride(mob/user, direction) - var/atom/movable/AM = parent - if(user.incapacitated()) - Unbuckle(user) - return - - if(world.time < last_vehicle_move + ((last_move_diagonal? 2 : 1) * vehicle_move_delay)) - return - last_vehicle_move = world.time - - if(keycheck(user)) - var/turf/next = get_step(AM, direction) - var/turf/current = get_turf(AM) - if(!istype(next) || !istype(current)) - return //not happening. - if(!turf_check(next, current)) - to_chat(user, "Your \the [AM] can not go onto [next]!") - return - if(!Process_Spacemove(direction) || !isturf(AM.loc)) - return - step(AM, direction) - - if((direction & (direction - 1)) && (AM.loc == next)) //moved diagonally - last_move_diagonal = TRUE - else - last_move_diagonal = FALSE - - handle_vehicle_layer() - handle_vehicle_offsets() - else - to_chat(user, "You'll need the keys in one of your hands to [drive_verb] [AM].") - -/datum/component/riding/proc/Unbuckle(atom/movable/M) - addtimer(CALLBACK(parent, /atom/movable/.proc/unbuckle_mob, M), 0, TIMER_UNIQUE) - -/datum/component/riding/proc/Process_Spacemove(direction) - var/atom/movable/AM = parent - return override_allow_spacemove || AM.has_gravity() - -/datum/component/riding/proc/account_limbs(mob/living/M) - if(M.get_num_legs() < 2 && !slowed) - vehicle_move_delay = vehicle_move_delay + slowvalue - slowed = TRUE - else if(slowed) - vehicle_move_delay = vehicle_move_delay - slowvalue - slowed = FALSE - -///////Yes, I said humans. No, this won't end well...////////// -/datum/component/riding/human - -/datum/component/riding/human/Initialize() - . = ..() - RegisterSignal(parent, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, .proc/on_host_unarmed_melee) - -/datum/component/riding/human/vehicle_mob_unbuckle(datum/source, mob/living/M, force = FALSE) - var/mob/living/carbon/human/H = parent - H.remove_movespeed_modifier(MOVESPEED_ID_HUMAN_CARRYING) - . = ..() - -/datum/component/riding/human/vehicle_mob_buckle(datum/source, mob/living/M, force = FALSE) - . = ..() - var/mob/living/carbon/human/H = parent - H.add_movespeed_modifier(MOVESPEED_ID_HUMAN_CARRYING, multiplicative_slowdown = HUMAN_CARRY_SLOWDOWN) - -/datum/component/riding/human/proc/on_host_unarmed_melee(atom/target) - var/mob/living/carbon/human/H = parent - if(H.a_intent == INTENT_DISARM && (target in H.buckled_mobs)) - force_dismount(target) - -/datum/component/riding/human/handle_vehicle_layer() - var/atom/movable/AM = parent - if(AM.buckled_mobs && AM.buckled_mobs.len) - for(var/mob/M in AM.buckled_mobs) //ensure proper layering of piggyback and carry, sometimes weird offsets get applied - M.layer = MOB_LAYER - if(!AM.buckle_lying) - if(AM.dir == SOUTH) - AM.layer = ABOVE_MOB_LAYER - else - AM.layer = OBJ_LAYER - else - if(AM.dir == NORTH) - AM.layer = OBJ_LAYER - else - AM.layer = ABOVE_MOB_LAYER - else - AM.layer = MOB_LAYER - -/datum/component/riding/human/get_offsets(pass_index) - var/mob/living/carbon/human/H = parent - if(H.buckle_lying) - return list(TEXT_NORTH = list(0, 6), TEXT_SOUTH = list(0, 6), TEXT_EAST = list(0, 6), TEXT_WEST = list(0, 6)) - else - return list(TEXT_NORTH = list(0, 6), TEXT_SOUTH = list(0, 6), TEXT_EAST = list(-6, 4), TEXT_WEST = list( 6, 4)) - - -/datum/component/riding/human/force_dismount(mob/living/user) - var/atom/movable/AM = parent - AM.unbuckle_mob(user) - user.Knockdown(60) - user.visible_message("[AM] pushes [user] off of [AM.p_them()]!") - -/datum/component/riding/cyborg - -/datum/component/riding/cyborg/ride_check(mob/user) - var/atom/movable/AM = parent - if(user.incapacitated()) - var/kick = TRUE - if(iscyborg(AM)) - var/mob/living/silicon/robot/R = AM - if(R.module && R.module.ride_allow_incapacitated) - kick = FALSE - if(kick) - to_chat(user, "You fall off of [AM]!") - Unbuckle(user) - return - if(iscarbon(user)) - var/mob/living/carbon/carbonuser = user - if(!carbonuser.get_num_arms()) - Unbuckle(user) - to_chat(user, "You can't grab onto [AM] with no hands!") - return - -/datum/component/riding/cyborg/handle_vehicle_layer() - var/atom/movable/AM = parent - if(AM.buckled_mobs && AM.buckled_mobs.len) - if(AM.dir == SOUTH) - AM.layer = ABOVE_MOB_LAYER - else - AM.layer = OBJ_LAYER - else - AM.layer = MOB_LAYER - -/datum/component/riding/cyborg/get_offsets(pass_index) // list(dir = x, y, layer) - return list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(-6, 3), TEXT_WEST = list( 6, 3)) - -/datum/component/riding/cyborg/handle_vehicle_offsets() - var/atom/movable/AM = parent - if(AM.has_buckled_mobs()) - for(var/mob/living/M in AM.buckled_mobs) - M.setDir(AM.dir) - if(iscyborg(AM)) - var/mob/living/silicon/robot/R = AM - if(istype(R.module)) - M.pixel_x = R.module.ride_offset_x[dir2text(AM.dir)] - M.pixel_y = R.module.ride_offset_y[dir2text(AM.dir)] - else - ..() - -/datum/component/riding/cyborg/force_dismount(mob/living/M) - var/atom/movable/AM = parent - AM.unbuckle_mob(M) - var/turf/target = get_edge_target_turf(AM, AM.dir) - var/turf/targetm = get_step(get_turf(AM), AM.dir) - M.Move(targetm) - M.visible_message("[M] is thrown clear of [AM]!") - M.throw_at(target, 14, 5, AM) - M.Knockdown(60) - -/datum/component/riding/proc/equip_buckle_inhands(mob/living/carbon/human/user, amount_required = 1, mob/living/riding_target_override) - var/list/equipped - var/mob/living/L = riding_target_override ? riding_target_override : user - for(var/amount_needed = amount_required, amount_needed > 0, amount_needed--) - var/obj/item/riding_offhand/inhand = new - inhand.rider = L - inhand.parent = parent - if(!user.put_in_hands(inhand, TRUE)) - qdel(inhand) // it isn't going to be added to offhands anyway - break - LAZYADD(equipped, inhand) - var/amount_equipped = LAZYLEN(equipped) - if(amount_equipped) - LAZYADD(offhands[L], equipped) - if(amount_equipped >= amount_required) - return TRUE - unequip_buckle_inhands(L) - return FALSE - -/datum/component/riding/proc/unequip_buckle_inhands(mob/living/carbon/user) - for(var/a in offhands[user]) - LAZYREMOVE(offhands[user], a) - if(a) //edge cases null entries - var/obj/item/riding_offhand/O = a - if(O.parent != parent) - CRASH("RIDING OFFHAND ON WRONG MOB") - else if(!O.selfdeleting) - qdel(O) - return TRUE - -/obj/item/riding_offhand - name = "offhand" - icon = 'icons/obj/items_and_weapons.dmi' - icon_state = "offhand" - w_class = WEIGHT_CLASS_HUGE - item_flags = ABSTRACT | DROPDEL | NOBLUDGEON - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - var/mob/living/carbon/rider - var/mob/living/parent - var/selfdeleting = FALSE - -/obj/item/riding_offhand/dropped() - selfdeleting = TRUE - . = ..() - -/obj/item/riding_offhand/equipped() - if(loc != rider && loc != parent) - selfdeleting = TRUE - qdel(src) - . = ..() - -/obj/item/riding_offhand/Destroy() - var/atom/movable/AM = parent - if(selfdeleting) - if(rider in AM.buckled_mobs) - AM.unbuckle_mob(rider) - . = ..() +/datum/component/riding + var/last_vehicle_move = 0 //used for move delays + var/last_move_diagonal = FALSE + var/vehicle_move_delay = 2 //tick delay between movements, lower = faster, higher = slower + var/keytype + + var/slowed = FALSE + var/slowvalue = 1 + + var/list/riding_offsets = list() //position_of_user = list(dir = list(px, py)), or RIDING_OFFSET_ALL for a generic one. + var/list/directional_vehicle_layers = list() //["[DIRECTION]"] = layer. Don't set it for a direction for default, set a direction to null for no change. + var/list/directional_vehicle_offsets = list() //same as above but instead of layer you have a list(px, py) + var/list/allowed_turf_typecache + var/list/forbid_turf_typecache //allow typecache for only certain turfs, forbid to allow all but those. allow only certain turfs will take precedence. + var/allow_one_away_from_valid_turf = TRUE //allow moving one tile away from a valid turf but not more. + var/override_allow_spacemove = FALSE + var/drive_verb = "drive" + var/ride_check_rider_incapacitated = FALSE + var/ride_check_rider_restrained = FALSE + var/ride_check_ridden_incapacitated = FALSE + var/list/offhands = list() // keyed list containing all the current riding offsets associated by mob + +/datum/component/riding/Initialize() + if(!ismovableatom(parent)) + return COMPONENT_INCOMPATIBLE + RegisterSignal(parent, COMSIG_MOVABLE_BUCKLE, .proc/vehicle_mob_buckle) + RegisterSignal(parent, COMSIG_MOVABLE_UNBUCKLE, .proc/vehicle_mob_unbuckle) + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/vehicle_moved) + +/datum/component/riding/proc/vehicle_mob_unbuckle(datum/source, mob/living/M, force = FALSE) + restore_position(M) + unequip_buckle_inhands(M) + +/datum/component/riding/proc/vehicle_mob_buckle(datum/source, mob/living/M, force = FALSE) + handle_vehicle_offsets() + +/datum/component/riding/proc/handle_vehicle_layer() + var/atom/movable/AM = parent + var/static/list/defaults = list(TEXT_NORTH = OBJ_LAYER, TEXT_SOUTH = ABOVE_MOB_LAYER, TEXT_EAST = ABOVE_MOB_LAYER, TEXT_WEST = ABOVE_MOB_LAYER) + . = defaults["[AM.dir]"] + if(directional_vehicle_layers["[AM.dir]"]) + . = directional_vehicle_layers["[AM.dir]"] + if(isnull(.)) //you can set it to null to not change it. + . = AM.layer + AM.layer = . + +/datum/component/riding/proc/set_vehicle_dir_layer(dir, layer) + directional_vehicle_layers["[dir]"] = layer + +/datum/component/riding/proc/vehicle_moved(datum/source) + var/atom/movable/AM = parent + for(var/i in AM.buckled_mobs) + ride_check(i) + handle_vehicle_offsets() + handle_vehicle_layer() + +/datum/component/riding/proc/ride_check(mob/living/M) + var/atom/movable/AM = parent + var/mob/AMM = AM + if((ride_check_rider_restrained && M.restrained(TRUE)) || (ride_check_rider_incapacitated && M.incapacitated(FALSE, TRUE)) || (ride_check_ridden_incapacitated && istype(AMM) && AMM.incapacitated(FALSE, TRUE))) + AM.visible_message("[M] falls off of [AM]!") + AM.unbuckle_mob(M) + return TRUE + +/datum/component/riding/proc/force_dismount(mob/living/M) + var/atom/movable/AM = parent + AM.unbuckle_mob(M) + +/datum/component/riding/proc/handle_vehicle_offsets() + var/atom/movable/AM = parent + var/AM_dir = "[AM.dir]" + var/passindex = 0 + if(AM.has_buckled_mobs()) + for(var/m in AM.buckled_mobs) + passindex++ + var/mob/living/buckled_mob = m + var/list/offsets = get_offsets(passindex) + var/rider_dir = get_rider_dir(passindex) + buckled_mob.setDir(rider_dir) + dir_loop: + for(var/offsetdir in offsets) + if(offsetdir == AM_dir) + var/list/diroffsets = offsets[offsetdir] + buckled_mob.pixel_x = diroffsets[1] + if(diroffsets.len >= 2) + buckled_mob.pixel_y = diroffsets[2] + if(diroffsets.len == 3) + buckled_mob.layer = diroffsets[3] + break dir_loop + var/list/static/default_vehicle_pixel_offsets = list(TEXT_NORTH = list(0, 0), TEXT_SOUTH = list(0, 0), TEXT_EAST = list(0, 0), TEXT_WEST = list(0, 0)) + var/px = default_vehicle_pixel_offsets[AM_dir] + var/py = default_vehicle_pixel_offsets[AM_dir] + if(directional_vehicle_offsets[AM_dir]) + if(isnull(directional_vehicle_offsets[AM_dir])) + px = AM.pixel_x + py = AM.pixel_y + else + px = directional_vehicle_offsets[AM_dir][1] + py = directional_vehicle_offsets[AM_dir][2] + AM.pixel_x = px + AM.pixel_y = py + +/datum/component/riding/proc/set_vehicle_dir_offsets(dir, x, y) + directional_vehicle_offsets["[dir]"] = list(x, y) + +//Override this to set your vehicle's various pixel offsets +/datum/component/riding/proc/get_offsets(pass_index) // list(dir = x, y, layer) + . = list(TEXT_NORTH = list(0, 0), TEXT_SOUTH = list(0, 0), TEXT_EAST = list(0, 0), TEXT_WEST = list(0, 0)) + if(riding_offsets["[pass_index]"]) + . = riding_offsets["[pass_index]"] + else if(riding_offsets["[RIDING_OFFSET_ALL]"]) + . = riding_offsets["[RIDING_OFFSET_ALL]"] + +/datum/component/riding/proc/set_riding_offsets(index, list/offsets) + if(!islist(offsets)) + return FALSE + riding_offsets["[index]"] = offsets + +//Override this to set the passengers/riders dir based on which passenger they are. +//ie: rider facing the vehicle's dir, but passenger 2 facing backwards, etc. +/datum/component/riding/proc/get_rider_dir(pass_index) + var/atom/movable/AM = parent + return AM.dir + +//KEYS +/datum/component/riding/proc/keycheck(mob/user) + return !keytype || user.is_holding_item_of_type(keytype) + +//BUCKLE HOOKS +/datum/component/riding/proc/restore_position(mob/living/buckled_mob) + if(buckled_mob) + buckled_mob.pixel_x = 0 + buckled_mob.pixel_y = 0 + if(buckled_mob.client) + buckled_mob.client.change_view(CONFIG_GET(string/default_view)) + +//MOVEMENT +/datum/component/riding/proc/turf_check(turf/next, turf/current) + if(allowed_turf_typecache && !allowed_turf_typecache[next.type]) + return (allow_one_away_from_valid_turf && allowed_turf_typecache[current.type]) + else if(forbid_turf_typecache && forbid_turf_typecache[next.type]) + return (allow_one_away_from_valid_turf && !forbid_turf_typecache[current.type]) + return TRUE + +/datum/component/riding/proc/handle_ride(mob/user, direction) + var/atom/movable/AM = parent + if(user.incapacitated()) + Unbuckle(user) + return + + if(world.time < last_vehicle_move + ((last_move_diagonal? 2 : 1) * vehicle_move_delay)) + return + last_vehicle_move = world.time + + if(keycheck(user)) + var/turf/next = get_step(AM, direction) + var/turf/current = get_turf(AM) + if(!istype(next) || !istype(current)) + return //not happening. + if(!turf_check(next, current)) + to_chat(user, "Your \the [AM] can not go onto [next]!") + return + if(!Process_Spacemove(direction) || !isturf(AM.loc)) + return + step(AM, direction) + + if((direction & (direction - 1)) && (AM.loc == next)) //moved diagonally + last_move_diagonal = TRUE + else + last_move_diagonal = FALSE + + handle_vehicle_layer() + handle_vehicle_offsets() + else + to_chat(user, "You'll need the keys in one of your hands to [drive_verb] [AM].") + +/datum/component/riding/proc/Unbuckle(atom/movable/M) + addtimer(CALLBACK(parent, /atom/movable/.proc/unbuckle_mob, M), 0, TIMER_UNIQUE) + +/datum/component/riding/proc/Process_Spacemove(direction) + var/atom/movable/AM = parent + return override_allow_spacemove || AM.has_gravity() + +/datum/component/riding/proc/account_limbs(mob/living/M) + if(M.get_num_legs() < 2 && !slowed) + vehicle_move_delay = vehicle_move_delay + slowvalue + slowed = TRUE + else if(slowed) + vehicle_move_delay = vehicle_move_delay - slowvalue + slowed = FALSE + +///////Yes, I said humans. No, this won't end well...////////// +/datum/component/riding/human + +/datum/component/riding/human/Initialize() + . = ..() + RegisterSignal(parent, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, .proc/on_host_unarmed_melee) + +/datum/component/riding/human/vehicle_mob_unbuckle(datum/source, mob/living/M, force = FALSE) + var/mob/living/carbon/human/H = parent + H.remove_movespeed_modifier(MOVESPEED_ID_HUMAN_CARRYING) + . = ..() + +/datum/component/riding/human/vehicle_mob_buckle(datum/source, mob/living/M, force = FALSE) + . = ..() + var/mob/living/carbon/human/H = parent + H.add_movespeed_modifier(MOVESPEED_ID_HUMAN_CARRYING, multiplicative_slowdown = HUMAN_CARRY_SLOWDOWN) + +/datum/component/riding/human/proc/on_host_unarmed_melee(atom/target) + var/mob/living/carbon/human/H = parent + if(H.a_intent == INTENT_DISARM && (target in H.buckled_mobs)) + force_dismount(target) + +/datum/component/riding/human/handle_vehicle_layer() + var/atom/movable/AM = parent + if(AM.buckled_mobs && AM.buckled_mobs.len) + for(var/mob/M in AM.buckled_mobs) //ensure proper layering of piggyback and carry, sometimes weird offsets get applied + M.layer = MOB_LAYER + if(!AM.buckle_lying) + if(AM.dir == SOUTH) + AM.layer = ABOVE_MOB_LAYER + else + AM.layer = OBJ_LAYER + else + if(AM.dir == NORTH) + AM.layer = OBJ_LAYER + else + AM.layer = ABOVE_MOB_LAYER + else + AM.layer = MOB_LAYER + +/datum/component/riding/human/get_offsets(pass_index) + var/mob/living/carbon/human/H = parent + if(H.buckle_lying) + return list(TEXT_NORTH = list(0, 6), TEXT_SOUTH = list(0, 6), TEXT_EAST = list(0, 6), TEXT_WEST = list(0, 6)) + else + return list(TEXT_NORTH = list(0, 6), TEXT_SOUTH = list(0, 6), TEXT_EAST = list(-6, 4), TEXT_WEST = list( 6, 4)) + + +/datum/component/riding/human/force_dismount(mob/living/user) + var/atom/movable/AM = parent + AM.unbuckle_mob(user) + user.Knockdown(60) + user.visible_message("[AM] pushes [user] off of [AM.p_them()]!") + +/datum/component/riding/cyborg + +/datum/component/riding/cyborg/ride_check(mob/user) + var/atom/movable/AM = parent + if(user.incapacitated()) + var/kick = TRUE + if(iscyborg(AM)) + var/mob/living/silicon/robot/R = AM + if(R.module && R.module.ride_allow_incapacitated) + kick = FALSE + if(kick) + to_chat(user, "You fall off of [AM]!") + Unbuckle(user) + return + if(iscarbon(user)) + var/mob/living/carbon/carbonuser = user + if(!carbonuser.get_num_arms()) + Unbuckle(user) + to_chat(user, "You can't grab onto [AM] with no hands!") + return + +/datum/component/riding/cyborg/handle_vehicle_layer() + var/atom/movable/AM = parent + if(AM.buckled_mobs && AM.buckled_mobs.len) + if(AM.dir == SOUTH) + AM.layer = ABOVE_MOB_LAYER + else + AM.layer = OBJ_LAYER + else + AM.layer = MOB_LAYER + +/datum/component/riding/cyborg/get_offsets(pass_index) // list(dir = x, y, layer) + return list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(-6, 3), TEXT_WEST = list( 6, 3)) + +/datum/component/riding/cyborg/handle_vehicle_offsets() + var/atom/movable/AM = parent + if(AM.has_buckled_mobs()) + for(var/mob/living/M in AM.buckled_mobs) + M.setDir(AM.dir) + if(iscyborg(AM)) + var/mob/living/silicon/robot/R = AM + if(istype(R.module)) + M.pixel_x = R.module.ride_offset_x[dir2text(AM.dir)] + M.pixel_y = R.module.ride_offset_y[dir2text(AM.dir)] + else + ..() + +/datum/component/riding/cyborg/force_dismount(mob/living/M) + var/atom/movable/AM = parent + AM.unbuckle_mob(M) + var/turf/target = get_edge_target_turf(AM, AM.dir) + var/turf/targetm = get_step(get_turf(AM), AM.dir) + M.Move(targetm) + M.visible_message("[M] is thrown clear of [AM]!") + M.throw_at(target, 14, 5, AM) + M.Knockdown(60) + +/datum/component/riding/proc/equip_buckle_inhands(mob/living/carbon/human/user, amount_required = 1, mob/living/riding_target_override) + var/list/equipped + var/mob/living/L = riding_target_override ? riding_target_override : user + for(var/amount_needed = amount_required, amount_needed > 0, amount_needed--) + var/obj/item/riding_offhand/inhand = new + inhand.rider = L + inhand.parent = parent + if(!user.put_in_hands(inhand, TRUE)) + qdel(inhand) // it isn't going to be added to offhands anyway + break + LAZYADD(equipped, inhand) + var/amount_equipped = LAZYLEN(equipped) + if(amount_equipped) + LAZYADD(offhands[L], equipped) + if(amount_equipped >= amount_required) + return TRUE + unequip_buckle_inhands(L) + return FALSE + +/datum/component/riding/proc/unequip_buckle_inhands(mob/living/carbon/user) + for(var/a in offhands[user]) + LAZYREMOVE(offhands[user], a) + if(a) //edge cases null entries + var/obj/item/riding_offhand/O = a + if(O.parent != parent) + CRASH("RIDING OFFHAND ON WRONG MOB") + else if(!O.selfdeleting) + qdel(O) + return TRUE + +/obj/item/riding_offhand + name = "offhand" + icon = 'icons/obj/items_and_weapons.dmi' + icon_state = "offhand" + w_class = WEIGHT_CLASS_HUGE + item_flags = ABSTRACT | DROPDEL | NOBLUDGEON + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + var/mob/living/carbon/rider + var/mob/living/parent + var/selfdeleting = FALSE + +/obj/item/riding_offhand/dropped() + selfdeleting = TRUE + . = ..() + +/obj/item/riding_offhand/equipped() + if(loc != rider && loc != parent) + selfdeleting = TRUE + qdel(src) + . = ..() + +/obj/item/riding_offhand/Destroy() + var/atom/movable/AM = parent + if(selfdeleting) + if(rider in AM.buckled_mobs) + AM.unbuckle_mob(rider) + . = ..() diff --git a/code/datums/components/slippery.dm b/code/datums/components/slippery.dm index a32a9cab43..6682c3901d 100644 --- a/code/datums/components/slippery.dm +++ b/code/datums/components/slippery.dm @@ -1,15 +1,15 @@ -/datum/component/slippery - var/intensity - var/lube_flags - var/datum/callback/callback - -/datum/component/slippery/Initialize(_intensity, _lube_flags = NONE, datum/callback/_callback) - intensity = max(_intensity, 0) - lube_flags = _lube_flags - callback = _callback - RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Slip) - -/datum/component/slippery/proc/Slip(datum/source, atom/movable/AM) - var/mob/victim = AM - if(istype(victim) && !victim.is_flying() && victim.slip(intensity, parent, lube_flags) && callback) - callback.Invoke(victim) +/datum/component/slippery + var/intensity + var/lube_flags + var/datum/callback/callback + +/datum/component/slippery/Initialize(_intensity, _lube_flags = NONE, datum/callback/_callback) + intensity = max(_intensity, 0) + lube_flags = _lube_flags + callback = _callback + RegisterSignal(parent, list(COMSIG_MOVABLE_CROSSED, COMSIG_ATOM_ENTERED), .proc/Slip) + +/datum/component/slippery/proc/Slip(datum/source, atom/movable/AM) + var/mob/victim = AM + if(istype(victim) && !victim.is_flying() && victim.slip(intensity, parent, lube_flags) && callback) + callback.Invoke(victim) diff --git a/code/datums/components/storage/concrete/_concrete.dm b/code/datums/components/storage/concrete/_concrete.dm index accc8cadaf..4c8f1b4c97 100644 --- a/code/datums/components/storage/concrete/_concrete.dm +++ b/code/datums/components/storage/concrete/_concrete.dm @@ -1,208 +1,208 @@ - -// External storage-related logic: -// /mob/proc/ClickOn() in /_onclick/click.dm - clicking items in storages -// /mob/living/Move() in /modules/mob/living/living.dm - hiding storage boxes on mob movement - -/datum/component/storage/concrete - can_transfer = TRUE - var/drop_all_on_deconstruct = TRUE - var/drop_all_on_destroy = FALSE - var/drop_all_on_break = FALSE - var/unlock_on_break = FALSE - var/transfer_contents_on_component_transfer = FALSE - var/list/datum/component/storage/slaves = list() - - var/list/_contents_limbo // Where objects go to live mid transfer - var/list/_user_limbo // The last users before the component started moving - -/datum/component/storage/concrete/Initialize() - . = ..() - RegisterSignal(parent, COMSIG_ATOM_CONTENTS_DEL, .proc/on_contents_del) - RegisterSignal(parent, COMSIG_OBJ_DECONSTRUCT, .proc/on_deconstruct) - RegisterSignal(parent, COMSIG_OBJ_BREAK, .proc/on_break) - -/datum/component/storage/concrete/Destroy() - var/atom/real_location = real_location() - for(var/atom/_A in real_location) - _A.mouse_opacity = initial(_A.mouse_opacity) - if(drop_all_on_destroy) - do_quick_empty() - for(var/i in slaves) - var/datum/component/storage/slave = i - slave.change_master(null) - QDEL_LIST(_contents_limbo) - _user_limbo = null - return ..() - -/datum/component/storage/concrete/master() - return src - -/datum/component/storage/concrete/real_location() - return parent - -/datum/component/storage/concrete/PreTransfer() - if(is_using) - _user_limbo = is_using.Copy() - close_all() - if(transfer_contents_on_component_transfer) - _contents_limbo = list() - for(var/atom/movable/AM in parent) - _contents_limbo += AM - AM.moveToNullspace() - -/datum/component/storage/concrete/PostTransfer() - if(!isatom(parent)) - return COMPONENT_INCOMPATIBLE - if(transfer_contents_on_component_transfer) - for(var/i in _contents_limbo) - var/atom/movable/AM = i - AM.forceMove(parent) - _contents_limbo = null - if(_user_limbo) - for(var/i in _user_limbo) - show_to(i) - _user_limbo = null - -/datum/component/storage/concrete/_insert_physical_item(obj/item/I, override = FALSE) - . = TRUE - var/atom/real_location = real_location() - if(I.loc != real_location && real_location) - I.forceMove(real_location) - refresh_mob_views() - -/datum/component/storage/concrete/refresh_mob_views() - . = ..() - for(var/i in slaves) - var/datum/component/storage/slave = i - slave.refresh_mob_views() - -/datum/component/storage/concrete/emp_act(datum/source, severity) - if(emp_shielded) - return - var/atom/real_location = real_location() - for(var/i in real_location) - var/atom/A = i - A.emp_act(severity) - -/datum/component/storage/concrete/proc/on_slave_link(datum/component/storage/S) - if(S == src) - return FALSE - slaves += S - return TRUE - -/datum/component/storage/concrete/proc/on_slave_unlink(datum/component/storage/S) - slaves -= S - return FALSE - -/datum/component/storage/concrete/proc/on_contents_del(datum/source, atom/A) - var/atom/real_location = parent - if(A in real_location) - usr = null - remove_from_storage(A, null) - -/datum/component/storage/concrete/proc/on_deconstruct(datum/source, disassembled) - if(drop_all_on_deconstruct) - do_quick_empty() - -/datum/component/storage/concrete/proc/on_break(datum/source, damage_flag) - if(drop_all_on_break) - do_quick_empty() - if(unlock_on_break) - set_locked(source, FALSE) - -/datum/component/storage/concrete/can_see_contents() - . = ..() - for(var/i in slaves) - var/datum/component/storage/slave = i - . |= slave.can_see_contents() - -//Resets screen loc and other vars of something being removed from storage. -/datum/component/storage/concrete/_removal_reset(atom/movable/thing) - thing.layer = initial(thing.layer) - thing.plane = initial(thing.plane) - thing.mouse_opacity = initial(thing.mouse_opacity) - if(thing.maptext) - thing.maptext = "" - -/datum/component/storage/concrete/remove_from_storage(atom/movable/AM, atom/new_location) - //Cache this as it should be reusable down the bottom, will not apply if anyone adds a sleep to dropped - //or moving objects, things that should never happen - var/atom/parent = src.parent - var/list/seeing_mobs = can_see_contents() - for(var/mob/M in seeing_mobs) - M.client.screen -= AM - if(ismob(parent.loc) && isitem(AM)) - var/obj/item/I = AM - var/mob/M = parent.loc - I.dropped(M) - if(new_location) - //Reset the items values - _removal_reset(AM) - AM.forceMove(new_location) - //We don't want to call this if the item is being destroyed - AM.on_exit_storage(src) - else - //Being destroyed, just move to nullspace now (so it's not in contents for the icon update) - AM.moveToNullspace() - refresh_mob_views() - if(isobj(parent)) - var/obj/O = parent - O.update_icon() - return TRUE - -/datum/component/storage/concrete/proc/slave_can_insert_object(datum/component/storage/slave, obj/item/I, stop_messages = FALSE, mob/M) - return TRUE - -/datum/component/storage/concrete/proc/handle_item_insertion_from_slave(datum/component/storage/slave, obj/item/I, prevent_warning = FALSE, M) - . = handle_item_insertion(I, prevent_warning, M, slave) - if(. && !prevent_warning) - slave.mob_item_insertion_feedback(usr, M, I) - -/datum/component/storage/concrete/handle_item_insertion(obj/item/I, prevent_warning = FALSE, mob/M, datum/component/storage/remote) //Remote is null or the slave datum - var/datum/component/storage/concrete/master = master() - var/atom/parent = src.parent - var/moved = FALSE - if(!istype(I)) - return FALSE - if(M) - if(!M.temporarilyRemoveItemFromInventory(I)) - return FALSE - else - moved = TRUE //At this point if the proc fails we need to manually move the object back to the turf/mob/whatever. - if(I.pulledby) - I.pulledby.stop_pulling() - if(silent) - prevent_warning = TRUE - if(!_insert_physical_item(I)) - if(moved) - if(M) - if(!M.put_in_active_hand(I)) - I.forceMove(parent.drop_location()) - else - I.forceMove(parent.drop_location()) - return FALSE - I.on_enter_storage(master) - refresh_mob_views() - I.mouse_opacity = MOUSE_OPACITY_OPAQUE //So you can click on the area around the item to equip it, instead of having to pixel hunt - if(M) - if(M.client && M.active_storage != src) - M.client.screen -= I - if(M.observers && M.observers.len) - for(var/i in M.observers) - var/mob/dead/observe = i - if(observe.client && observe.active_storage != src) - observe.client.screen -= I - if(!remote) - parent.add_fingerprint(M) - if(!prevent_warning) - mob_item_insertion_feedback(usr, M, I) - update_icon() - return TRUE - -/datum/component/storage/concrete/update_icon() - if(isobj(parent)) - var/obj/O = parent - O.update_icon() - for(var/i in slaves) - var/datum/component/storage/slave = i - slave.update_icon() + +// External storage-related logic: +// /mob/proc/ClickOn() in /_onclick/click.dm - clicking items in storages +// /mob/living/Move() in /modules/mob/living/living.dm - hiding storage boxes on mob movement + +/datum/component/storage/concrete + can_transfer = TRUE + var/drop_all_on_deconstruct = TRUE + var/drop_all_on_destroy = FALSE + var/drop_all_on_break = FALSE + var/unlock_on_break = FALSE + var/transfer_contents_on_component_transfer = FALSE + var/list/datum/component/storage/slaves = list() + + var/list/_contents_limbo // Where objects go to live mid transfer + var/list/_user_limbo // The last users before the component started moving + +/datum/component/storage/concrete/Initialize() + . = ..() + RegisterSignal(parent, COMSIG_ATOM_CONTENTS_DEL, .proc/on_contents_del) + RegisterSignal(parent, COMSIG_OBJ_DECONSTRUCT, .proc/on_deconstruct) + RegisterSignal(parent, COMSIG_OBJ_BREAK, .proc/on_break) + +/datum/component/storage/concrete/Destroy() + var/atom/real_location = real_location() + for(var/atom/_A in real_location) + _A.mouse_opacity = initial(_A.mouse_opacity) + if(drop_all_on_destroy) + do_quick_empty() + for(var/i in slaves) + var/datum/component/storage/slave = i + slave.change_master(null) + QDEL_LIST(_contents_limbo) + _user_limbo = null + return ..() + +/datum/component/storage/concrete/master() + return src + +/datum/component/storage/concrete/real_location() + return parent + +/datum/component/storage/concrete/PreTransfer() + if(is_using) + _user_limbo = is_using.Copy() + close_all() + if(transfer_contents_on_component_transfer) + _contents_limbo = list() + for(var/atom/movable/AM in parent) + _contents_limbo += AM + AM.moveToNullspace() + +/datum/component/storage/concrete/PostTransfer() + if(!isatom(parent)) + return COMPONENT_INCOMPATIBLE + if(transfer_contents_on_component_transfer) + for(var/i in _contents_limbo) + var/atom/movable/AM = i + AM.forceMove(parent) + _contents_limbo = null + if(_user_limbo) + for(var/i in _user_limbo) + show_to(i) + _user_limbo = null + +/datum/component/storage/concrete/_insert_physical_item(obj/item/I, override = FALSE) + . = TRUE + var/atom/real_location = real_location() + if(I.loc != real_location && real_location) + I.forceMove(real_location) + refresh_mob_views() + +/datum/component/storage/concrete/refresh_mob_views() + . = ..() + for(var/i in slaves) + var/datum/component/storage/slave = i + slave.refresh_mob_views() + +/datum/component/storage/concrete/emp_act(datum/source, severity) + if(emp_shielded) + return + var/atom/real_location = real_location() + for(var/i in real_location) + var/atom/A = i + A.emp_act(severity) + +/datum/component/storage/concrete/proc/on_slave_link(datum/component/storage/S) + if(S == src) + return FALSE + slaves += S + return TRUE + +/datum/component/storage/concrete/proc/on_slave_unlink(datum/component/storage/S) + slaves -= S + return FALSE + +/datum/component/storage/concrete/proc/on_contents_del(datum/source, atom/A) + var/atom/real_location = parent + if(A in real_location) + usr = null + remove_from_storage(A, null) + +/datum/component/storage/concrete/proc/on_deconstruct(datum/source, disassembled) + if(drop_all_on_deconstruct) + do_quick_empty() + +/datum/component/storage/concrete/proc/on_break(datum/source, damage_flag) + if(drop_all_on_break) + do_quick_empty() + if(unlock_on_break) + set_locked(source, FALSE) + +/datum/component/storage/concrete/can_see_contents() + . = ..() + for(var/i in slaves) + var/datum/component/storage/slave = i + . |= slave.can_see_contents() + +//Resets screen loc and other vars of something being removed from storage. +/datum/component/storage/concrete/_removal_reset(atom/movable/thing) + thing.layer = initial(thing.layer) + thing.plane = initial(thing.plane) + thing.mouse_opacity = initial(thing.mouse_opacity) + if(thing.maptext) + thing.maptext = "" + +/datum/component/storage/concrete/remove_from_storage(atom/movable/AM, atom/new_location) + //Cache this as it should be reusable down the bottom, will not apply if anyone adds a sleep to dropped + //or moving objects, things that should never happen + var/atom/parent = src.parent + var/list/seeing_mobs = can_see_contents() + for(var/mob/M in seeing_mobs) + M.client.screen -= AM + if(ismob(parent.loc) && isitem(AM)) + var/obj/item/I = AM + var/mob/M = parent.loc + I.dropped(M) + if(new_location) + //Reset the items values + _removal_reset(AM) + AM.forceMove(new_location) + //We don't want to call this if the item is being destroyed + AM.on_exit_storage(src) + else + //Being destroyed, just move to nullspace now (so it's not in contents for the icon update) + AM.moveToNullspace() + refresh_mob_views() + if(isobj(parent)) + var/obj/O = parent + O.update_icon() + return TRUE + +/datum/component/storage/concrete/proc/slave_can_insert_object(datum/component/storage/slave, obj/item/I, stop_messages = FALSE, mob/M) + return TRUE + +/datum/component/storage/concrete/proc/handle_item_insertion_from_slave(datum/component/storage/slave, obj/item/I, prevent_warning = FALSE, M) + . = handle_item_insertion(I, prevent_warning, M, slave) + if(. && !prevent_warning) + slave.mob_item_insertion_feedback(usr, M, I) + +/datum/component/storage/concrete/handle_item_insertion(obj/item/I, prevent_warning = FALSE, mob/M, datum/component/storage/remote) //Remote is null or the slave datum + var/datum/component/storage/concrete/master = master() + var/atom/parent = src.parent + var/moved = FALSE + if(!istype(I)) + return FALSE + if(M) + if(!M.temporarilyRemoveItemFromInventory(I)) + return FALSE + else + moved = TRUE //At this point if the proc fails we need to manually move the object back to the turf/mob/whatever. + if(I.pulledby) + I.pulledby.stop_pulling() + if(silent) + prevent_warning = TRUE + if(!_insert_physical_item(I)) + if(moved) + if(M) + if(!M.put_in_active_hand(I)) + I.forceMove(parent.drop_location()) + else + I.forceMove(parent.drop_location()) + return FALSE + I.on_enter_storage(master) + refresh_mob_views() + I.mouse_opacity = MOUSE_OPACITY_OPAQUE //So you can click on the area around the item to equip it, instead of having to pixel hunt + if(M) + if(M.client && M.active_storage != src) + M.client.screen -= I + if(M.observers && M.observers.len) + for(var/i in M.observers) + var/mob/dead/observe = i + if(observe.client && observe.active_storage != src) + observe.client.screen -= I + if(!remote) + parent.add_fingerprint(M) + if(!prevent_warning) + mob_item_insertion_feedback(usr, M, I) + update_icon() + return TRUE + +/datum/component/storage/concrete/update_icon() + if(isobj(parent)) + var/obj/O = parent + O.update_icon() + for(var/i in slaves) + var/datum/component/storage/slave = i + slave.update_icon() diff --git a/code/datums/components/storage/concrete/bag_of_holding.dm b/code/datums/components/storage/concrete/bag_of_holding.dm index bf97ec6516..8b9ecf5a4e 100644 --- a/code/datums/components/storage/concrete/bag_of_holding.dm +++ b/code/datums/components/storage/concrete/bag_of_holding.dm @@ -1,36 +1,36 @@ -/datum/component/storage/concrete/bluespace/bag_of_holding/handle_item_insertion(obj/item/W, prevent_warning = FALSE, mob/living/user) - var/atom/A = parent - if(A == W) //don't put yourself into yourself. - return - var/list/obj/item/storage/backpack/holding/matching = typecache_filter_list(W.GetAllContents(), typecacheof(/obj/item/storage/backpack/holding)) - matching -= A - if(istype(W, /obj/item/storage/backpack/holding) || matching.len) - var/safety = alert(user, "Doing this will have extremely dire consequences for the station and its crew. Be sure you know what you're doing.", "Put in [A.name]?", "Abort", "Proceed") - if(safety != "Proceed" || QDELETED(A) || QDELETED(W) || QDELETED(user) || !user.canUseTopic(A, BE_CLOSE, iscarbon(user))) - return - var/turf/loccheck = get_turf(A) - if(is_reebe(loccheck.z)) - user.visible_message("An unseen force knocks [user] to the ground!", "\"I think not!\"") - user.Knockdown(60) - return - if(istype(loccheck.loc, /area/fabric_of_reality)) - to_chat(user, "You can't do that here!") - to_chat(user, "The Bluespace interfaces of the two devices catastrophically malfunction!") - qdel(W) - playsound(loccheck,'sound/effects/supermatter.ogg', 200, 1) - user.gib(TRUE, TRUE, TRUE) - for(var/turf/T in range(6,loccheck)) - if(istype(T, /turf/open/space/transit)) - continue - for(var/mob/living/M in T) - if(M.movement_type & FLYING) - M.visible_message("The bluespace collapse crushes the air towards it, pulling [M] towards the ground...") - M.Knockdown(5, TRUE, TRUE) //Overrides stun absorbs. - T.TerraformTurf(/turf/open/chasm/magic, /turf/open/chasm/magic) - for (var/obj/structure/ladder/unbreakable/binary/ladder in GLOB.ladders) - ladder.ActivateAlmonds() - message_admins("[ADMIN_LOOKUPFLW(user)] detonated a bag of holding at [ADMIN_VERBOSEJMP(loccheck)].") - log_game("[key_name(user)] detonated a bag of holding at [loc_name(loccheck)].") - qdel(A) - return - . = ..() +/datum/component/storage/concrete/bluespace/bag_of_holding/handle_item_insertion(obj/item/W, prevent_warning = FALSE, mob/living/user) + var/atom/A = parent + if(A == W) //don't put yourself into yourself. + return + var/list/obj/item/storage/backpack/holding/matching = typecache_filter_list(W.GetAllContents(), typecacheof(/obj/item/storage/backpack/holding)) + matching -= A + if(istype(W, /obj/item/storage/backpack/holding) || matching.len) + var/safety = alert(user, "Doing this will have extremely dire consequences for the station and its crew. Be sure you know what you're doing.", "Put in [A.name]?", "Abort", "Proceed") + if(safety != "Proceed" || QDELETED(A) || QDELETED(W) || QDELETED(user) || !user.canUseTopic(A, BE_CLOSE, iscarbon(user))) + return + var/turf/loccheck = get_turf(A) + if(is_reebe(loccheck.z)) + user.visible_message("An unseen force knocks [user] to the ground!", "\"I think not!\"") + user.Knockdown(60) + return + if(istype(loccheck.loc, /area/fabric_of_reality)) + to_chat(user, "You can't do that here!") + to_chat(user, "The Bluespace interfaces of the two devices catastrophically malfunction!") + qdel(W) + playsound(loccheck,'sound/effects/supermatter.ogg', 200, 1) + user.gib(TRUE, TRUE, TRUE) + for(var/turf/T in range(6,loccheck)) + if(istype(T, /turf/open/space/transit)) + continue + for(var/mob/living/M in T) + if(M.movement_type & FLYING) + M.visible_message("The bluespace collapse crushes the air towards it, pulling [M] towards the ground...") + M.Knockdown(5, TRUE, TRUE) //Overrides stun absorbs. + T.TerraformTurf(/turf/open/chasm/magic, /turf/open/chasm/magic) + for (var/obj/structure/ladder/unbreakable/binary/ladder in GLOB.ladders) + ladder.ActivateAlmonds() + message_admins("[ADMIN_LOOKUPFLW(user)] detonated a bag of holding at [ADMIN_VERBOSEJMP(loccheck)].") + log_game("[key_name(user)] detonated a bag of holding at [loc_name(loccheck)].") + qdel(A) + return + . = ..() diff --git a/code/datums/components/storage/concrete/implant.dm b/code/datums/components/storage/concrete/implant.dm index 0348d340ae..5ee4c13c24 100644 --- a/code/datums/components/storage/concrete/implant.dm +++ b/code/datums/components/storage/concrete/implant.dm @@ -1,18 +1,18 @@ -/datum/component/storage/concrete/implant - max_w_class = WEIGHT_CLASS_NORMAL - max_combined_w_class = 6 - max_items = 2 - drop_all_on_destroy = TRUE - drop_all_on_deconstruct = TRUE - silent = TRUE - allow_big_nesting = TRUE - -/datum/component/storage/concrete/implant/Initialize() - . = ..() - cant_hold = typecacheof(list(/obj/item/disk/nuclear)) - -/datum/component/storage/concrete/implant/InheritComponent(datum/component/storage/concrete/implant/I, original) - if(!istype(I)) - return ..() - max_combined_w_class += I.max_combined_w_class - max_items += I.max_items +/datum/component/storage/concrete/implant + max_w_class = WEIGHT_CLASS_NORMAL + max_combined_w_class = 6 + max_items = 2 + drop_all_on_destroy = TRUE + drop_all_on_deconstruct = TRUE + silent = TRUE + allow_big_nesting = TRUE + +/datum/component/storage/concrete/implant/Initialize() + . = ..() + cant_hold = typecacheof(list(/obj/item/disk/nuclear)) + +/datum/component/storage/concrete/implant/InheritComponent(datum/component/storage/concrete/implant/I, original) + if(!istype(I)) + return ..() + max_combined_w_class += I.max_combined_w_class + max_items += I.max_items diff --git a/code/datums/components/storage/concrete/rped.dm b/code/datums/components/storage/concrete/rped.dm index e1cc4ff6ae..2f95466238 100644 --- a/code/datums/components/storage/concrete/rped.dm +++ b/code/datums/components/storage/concrete/rped.dm @@ -1,36 +1,36 @@ -/datum/component/storage/concrete/rped - collection_mode = COLLECT_EVERYTHING - allow_quick_gather = TRUE - allow_quick_empty = TRUE - click_gather = TRUE - max_w_class = WEIGHT_CLASS_NORMAL - max_combined_w_class = 100 - max_items = 100 - display_numerical_stacking = TRUE - -/datum/component/storage/concrete/rped/can_be_inserted(obj/item/I, stop_messages, mob/M) - . = ..() - if(!I.get_part_rating()) - if (!stop_messages) - to_chat(M, "[parent] only accepts machine parts!") - return FALSE - -/datum/component/storage/concrete/bluespace/rped - collection_mode = COLLECT_EVERYTHING - allow_quick_gather = TRUE - allow_quick_empty = TRUE - click_gather = TRUE - max_w_class = WEIGHT_CLASS_BULKY // can fit vending refills - max_combined_w_class = 800 - max_items = 350 - display_numerical_stacking = TRUE - -/datum/component/storage/concrete/bluespace/rped/can_be_inserted(obj/item/I, stop_messages, mob/M) - . = ..() - if(!I.get_part_rating()) - if (!stop_messages) - to_chat(M, "[parent] only accepts machine parts!") - return FALSE - -/datum/component/storage/concrete/cyborg/rped - max_items = 150 +/datum/component/storage/concrete/rped + collection_mode = COLLECT_EVERYTHING + allow_quick_gather = TRUE + allow_quick_empty = TRUE + click_gather = TRUE + max_w_class = WEIGHT_CLASS_NORMAL + max_combined_w_class = 100 + max_items = 100 + display_numerical_stacking = TRUE + +/datum/component/storage/concrete/rped/can_be_inserted(obj/item/I, stop_messages, mob/M) + . = ..() + if(!I.get_part_rating()) + if (!stop_messages) + to_chat(M, "[parent] only accepts machine parts!") + return FALSE + +/datum/component/storage/concrete/bluespace/rped + collection_mode = COLLECT_EVERYTHING + allow_quick_gather = TRUE + allow_quick_empty = TRUE + click_gather = TRUE + max_w_class = WEIGHT_CLASS_BULKY // can fit vending refills + max_combined_w_class = 800 + max_items = 350 + display_numerical_stacking = TRUE + +/datum/component/storage/concrete/bluespace/rped/can_be_inserted(obj/item/I, stop_messages, mob/M) + . = ..() + if(!I.get_part_rating()) + if (!stop_messages) + to_chat(M, "[parent] only accepts machine parts!") + return FALSE + +/datum/component/storage/concrete/cyborg/rped + max_items = 150 diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index 76a9b2e6aa..55e5c03c2b 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -1,800 +1,800 @@ -#define COLLECT_ONE 0 -#define COLLECT_EVERYTHING 1 -#define COLLECT_SAME 2 - -#define DROP_NOTHING 0 -#define DROP_AT_PARENT 1 -#define DROP_AT_LOCATION 2 - -// External storage-related logic: -// /mob/proc/ClickOn() in /_onclick/click.dm - clicking items in storages -// /mob/living/Move() in /modules/mob/living/living.dm - hiding storage boxes on mob movement - -/datum/component/storage - dupe_mode = COMPONENT_DUPE_UNIQUE - var/datum/component/storage/concrete/master //If not null, all actions act on master and this is just an access point. - - var/list/can_hold //if this is set, only things in this typecache will fit. - var/list/cant_hold //if this is set, anything in this typecache will not be able to fit. - - var/list/mob/is_using //lazy list of mobs looking at the contents of this storage. - - var/locked = FALSE //when locked nothing can see inside or use it. - - var/max_w_class = WEIGHT_CLASS_SMALL //max size of objects that will fit. - var/max_combined_w_class = 14 //max combined sizes of objects that will fit. - var/max_items = 7 //max number of objects that will fit. - - var/emp_shielded = FALSE - - var/silent = FALSE //whether this makes a message when things are put in. - var/click_gather = FALSE //whether this can be clicked on items to pick it up rather than the other way around. - var/rustle_sound = TRUE //play rustle sound on interact. - var/allow_quick_empty = FALSE //allow empty verb which allows dumping on the floor of everything inside quickly. - var/allow_quick_gather = FALSE //allow toggle mob verb which toggles collecting all items from a tile. - - var/collection_mode = COLLECT_EVERYTHING - - var/insert_preposition = "in" //you put things "in" a bag, but "on" a tray. - - var/display_numerical_stacking = FALSE //stack things of the same type and show as a single object with a number. - - var/obj/screen/storage/boxes //storage display object - var/obj/screen/close/closer //close button object - - var/allow_big_nesting = FALSE //allow storage objects of the same or greater size. - - var/attack_hand_interact = TRUE //interact on attack hand. - var/quickdraw = FALSE //altclick interact - - var/datum/action/item_action/storage_gather_mode/modeswitch_action - - //Screen variables: Do not mess with these vars unless you know what you're doing. They're not defines so storage that isn't in the same location can be supported in the future. - var/screen_max_columns = 7 //These two determine maximum screen sizes. - var/screen_max_rows = INFINITY - var/screen_pixel_x = 16 //These two are pixel values for screen loc of boxes and closer - var/screen_pixel_y = 16 - var/screen_start_x = 4 //These two are where the storage starts being rendered, screen_loc wise. - var/screen_start_y = 2 - //End - - var/limited_random_access = FALSE //Quick if statement in accessible_items to determine if we care at all about what people can access at once. - var/limited_random_access_stack_position = 0 //If >0, can only access top items - var/limited_random_access_stack_bottom_up = FALSE //If TRUE, above becomes bottom items - -/datum/component/storage/Initialize(datum/component/storage/concrete/master) - if(!isatom(parent)) - return COMPONENT_INCOMPATIBLE - if(master) - change_master(master) - boxes = new(null, src) - closer = new(null, src) - orient2hud() - - RegisterSignal(parent, COMSIG_CONTAINS_STORAGE, .proc/on_check) - RegisterSignal(parent, COMSIG_IS_STORAGE_LOCKED, .proc/check_locked) - RegisterSignal(parent, COMSIG_TRY_STORAGE_SHOW, .proc/signal_show_attempt) - RegisterSignal(parent, COMSIG_TRY_STORAGE_INSERT, .proc/signal_insertion_attempt) - RegisterSignal(parent, COMSIG_TRY_STORAGE_CAN_INSERT, .proc/signal_can_insert) - RegisterSignal(parent, COMSIG_TRY_STORAGE_TAKE_TYPE, .proc/signal_take_type) - RegisterSignal(parent, COMSIG_TRY_STORAGE_FILL_TYPE, .proc/signal_fill_type) - RegisterSignal(parent, COMSIG_TRY_STORAGE_SET_LOCKSTATE, .proc/set_locked) - RegisterSignal(parent, COMSIG_TRY_STORAGE_TAKE, .proc/signal_take_obj) - RegisterSignal(parent, COMSIG_TRY_STORAGE_QUICK_EMPTY, .proc/signal_quick_empty) - RegisterSignal(parent, COMSIG_TRY_STORAGE_HIDE_FROM, .proc/signal_hide_attempt) - RegisterSignal(parent, COMSIG_TRY_STORAGE_HIDE_ALL, .proc/close_all) - RegisterSignal(parent, COMSIG_TRY_STORAGE_RETURN_INVENTORY, .proc/signal_return_inv) - - RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/attackby) - - RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand) - RegisterSignal(parent, COMSIG_ATOM_ATTACK_PAW, .proc/on_attack_hand) - RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, .proc/emp_act) - RegisterSignal(parent, COMSIG_ATOM_ATTACK_GHOST, .proc/show_to_ghost) - RegisterSignal(parent, COMSIG_ATOM_ENTERED, .proc/refresh_mob_views) - RegisterSignal(parent, COMSIG_ATOM_EXITED, .proc/_remove_and_refresh) - RegisterSignal(parent, COMSIG_ATOM_CANREACH, .proc/canreach_react) - - RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, .proc/preattack_intercept) - RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/attack_self) - RegisterSignal(parent, COMSIG_ITEM_PICKUP, .proc/signal_on_pickup) - - RegisterSignal(parent, COMSIG_MOVABLE_POST_THROW, .proc/close_all) - RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/check_views) - - RegisterSignal(parent, COMSIG_CLICK_ALT, .proc/on_alt_click) - RegisterSignal(parent, COMSIG_MOUSEDROP_ONTO, .proc/mousedrop_onto) - RegisterSignal(parent, COMSIG_MOUSEDROPPED_ONTO, .proc/mousedrop_receive) - - update_actions() - -/datum/component/storage/Destroy() - close_all() - QDEL_NULL(boxes) - QDEL_NULL(closer) - LAZYCLEARLIST(is_using) - return ..() - -/datum/component/storage/PreTransfer() - update_actions() - -/datum/component/storage/proc/update_actions() - QDEL_NULL(modeswitch_action) - if(!isitem(parent) || !allow_quick_gather) - return - var/obj/item/I = parent - modeswitch_action = new(I) - RegisterSignal(modeswitch_action, COMSIG_ACTION_TRIGGER, .proc/action_trigger) - if(I.obj_flags & IN_INVENTORY) - var/mob/M = I.loc - if(!istype(M)) - return - modeswitch_action.Grant(M) - -/datum/component/storage/proc/change_master(datum/component/storage/concrete/new_master) - if(new_master == src || (!isnull(new_master) && !istype(new_master))) - return FALSE - if(master) - master.on_slave_unlink(src) - master = new_master - if(master) - master.on_slave_link(src) - return TRUE - -/datum/component/storage/proc/master() - if(master == src) - return //infinite loops yo. - return master - -/datum/component/storage/proc/real_location() - var/datum/component/storage/concrete/master = master() - return master? master.real_location() : null - -//What players can access -//this proc can probably eat a refactor at some point. -/datum/component/storage/proc/accessible_items(random_access = TRUE) - var/list/contents = contents() - if(contents) - if(limited_random_access && random_access) - if(limited_random_access_stack_position && (length(contents) > limited_random_access_stack_position)) - if(limited_random_access_stack_bottom_up) - contents.Cut(1, limited_random_access_stack_position + 1) - else - contents.Cut(1, length(contents) - limited_random_access_stack_position + 1) - return contents - -/datum/component/storage/proc/canreach_react(datum/source, list/next) - var/datum/component/storage/concrete/master = master() - if(!master) - return - . = COMPONENT_BLOCK_REACH - next += master.parent - for(var/i in master.slaves) - var/datum/component/storage/slave = i - next += slave.parent - -/datum/component/storage/proc/attack_self(datum/source, mob/M) - if(check_locked(source, M, TRUE)) - return FALSE - if((M.get_active_held_item() == parent) && allow_quick_empty) - quick_empty(M) - -/datum/component/storage/proc/preattack_intercept(datum/source, obj/O, mob/M, params) - if(!isitem(O) || !click_gather || SEND_SIGNAL(O, COMSIG_CONTAINS_STORAGE)) - return FALSE - . = COMPONENT_NO_ATTACK - if(check_locked(source, M, TRUE)) - return FALSE - var/atom/A = parent - var/obj/item/I = O - if(collection_mode == COLLECT_ONE) - if(can_be_inserted(I, null, M)) - handle_item_insertion(I, null, M) - A.do_squish() - return - if(!isturf(I.loc)) - return - var/list/things = I.loc.contents.Copy() - if(collection_mode == COLLECT_SAME) - things = typecache_filter_list(things, typecacheof(I.type)) - var/len = length(things) - if(!len) - to_chat(M, "You failed to pick up anything with [parent].") - return - var/datum/progressbar/progress = new(M, len, I.loc) - var/list/rejections = list() - while(do_after(M, 10, TRUE, parent, FALSE, CALLBACK(src, .proc/handle_mass_pickup, things, I.loc, rejections, progress))) - stoplag(1) - qdel(progress) - to_chat(M, "You put everything you could [insert_preposition] [parent].") - A.do_squish(1.4, 0.4) - -/datum/component/storage/proc/handle_mass_item_insertion(list/things, datum/component/storage/src_object, mob/user, datum/progressbar/progress) - var/atom/source_real_location = src_object.real_location() - for(var/obj/item/I in things) - things -= I - if(I.loc != source_real_location) - continue - if(user.active_storage != src_object) - if(I.on_found(user)) - break - if(can_be_inserted(I,FALSE,user)) - handle_item_insertion(I, TRUE, user) - if (TICK_CHECK) - progress.update(progress.goal - things.len) - return TRUE - - progress.update(progress.goal - things.len) - return FALSE - -/datum/component/storage/proc/handle_mass_pickup(list/things, atom/thing_loc, list/rejections, datum/progressbar/progress) - var/atom/real_location = real_location() - 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(!can_be_inserted(I, stop_messages = TRUE)) // Note can_be_inserted still makes noise when the answer is no - if(real_location.contents.len >= max_items) - break - rejections += I.type // therefore full bags are still a little spammy - continue - - handle_item_insertion(I, TRUE) //The TRUE stops the "You put the [parent] 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 - -/datum/component/storage/proc/quick_empty(mob/M) - var/atom/A = parent - if(!M.canUseStorage() || !A.Adjacent(M) || M.incapacitated()) - return - if(check_locked(null, M, TRUE)) - return FALSE - A.add_fingerprint(M) - to_chat(M, "You start dumping out [parent].") - var/turf/T = get_turf(A) - var/list/things = contents() - var/datum/progressbar/progress = new(M, length(things), T) - while (do_after(M, 10, TRUE, T, FALSE, CALLBACK(src, .proc/mass_remove_from_storage, T, things, progress))) - stoplag(1) - qdel(progress) - A.do_squish(0.8, 1.2) - -/datum/component/storage/proc/mass_remove_from_storage(atom/target, list/things, datum/progressbar/progress, trigger_on_found = TRUE) - var/atom/real_location = real_location() - for(var/obj/item/I in things) - things -= I - if(I.loc != real_location) - continue - remove_from_storage(I, target) - if(trigger_on_found && I.on_found()) - return FALSE - if(TICK_CHECK) - progress.update(progress.goal - length(things)) - return TRUE - progress.update(progress.goal - length(things)) - return FALSE - -/datum/component/storage/proc/do_quick_empty(atom/_target) - if(!_target) - _target = get_turf(parent) - if(usr) - hide_from(usr) - var/list/contents = contents() - var/atom/real_location = real_location() - for(var/obj/item/I in contents) - if(I.loc != real_location) - continue - remove_from_storage(I, _target) - return TRUE - -/datum/component/storage/proc/set_locked(datum/source, new_state) - locked = new_state - if(check_locked()) - close_all() - -/datum/component/storage/proc/_process_numerical_display() - . = list() - for(var/obj/item/I in accessible_items()) - if(QDELETED(I)) - continue - if(!.[I.type]) - .[I.type] = new /datum/numbered_display(I, 1) - else - var/datum/numbered_display/ND = .[I.type] - ND.number++ - . = sortTim(., /proc/cmp_numbered_displays_name_asc, associative = TRUE) - -//This proc determines the size of the inventory to be displayed. Please touch it only if you know what you're doing. -/datum/component/storage/proc/orient2hud(mob/user, maxcolumns) - var/list/accessible_contents = accessible_items() - var/adjusted_contents = length(accessible_contents) - - //Numbered contents display - var/list/datum/numbered_display/numbered_contents - if(display_numerical_stacking) - numbered_contents = _process_numerical_display() - adjusted_contents = numbered_contents.len - - var/columns = CLAMP(max_items, 1, maxcolumns ? maxcolumns : screen_max_columns) - var/rows = CLAMP(CEILING(adjusted_contents / columns, 1), 1, screen_max_rows) - standard_orient_objs(rows, columns, numbered_contents) - -//This proc draws out the inventory and places the items on it. It uses the standard position. -/datum/component/storage/proc/standard_orient_objs(rows, cols, list/obj/item/numerical_display_contents) - boxes.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+cols-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]" - var/cx = screen_start_x - var/cy = screen_start_y - if(islist(numerical_display_contents)) - for(var/type in numerical_display_contents) - var/datum/numbered_display/ND = numerical_display_contents[type] - ND.sample_object.mouse_opacity = MOUSE_OPACITY_OPAQUE - ND.sample_object.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]" - ND.sample_object.maptext = "[(ND.number > 1)? "[ND.number]" : ""]" - ND.sample_object.layer = ABOVE_HUD_LAYER - ND.sample_object.plane = ABOVE_HUD_PLANE - cx++ - if(cx - screen_start_x >= cols) - cx = screen_start_x - cy++ - if(cy - screen_start_y >= rows) - break - else - for(var/obj/O in accessible_items()) - if(QDELETED(O)) - continue - O.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip" - O.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]" - O.maptext = "" - O.layer = ABOVE_HUD_LAYER - O.plane = ABOVE_HUD_PLANE - cx++ - if(cx - screen_start_x >= cols) - cx = screen_start_x - cy++ - if(cy - screen_start_y >= rows) - break - closer.screen_loc = "[screen_start_x + cols]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y]" - -/datum/component/storage/proc/show_to(mob/M) - if(!M.client) - return FALSE - var/list/cview = getviewsize(M.client.view) - var/maxallowedscreensize = cview[1]-8 - if(M.active_storage != src && (M.stat == CONSCIOUS)) - for(var/obj/item/I in accessible_items()) - if(I.on_found(M)) - return FALSE - if(M.active_storage) - M.active_storage.hide_from(M) - orient2hud(M, (isliving(M) ? maxallowedscreensize : 7)) - M.client.screen |= boxes - M.client.screen |= closer - M.client.screen |= accessible_items() - M.active_storage = src - LAZYOR(is_using, M) - return TRUE - -/datum/component/storage/proc/hide_from(mob/M) - if(!M.client) - return TRUE - var/atom/real_location = real_location() - M.client.screen -= boxes - M.client.screen -= closer - M.client.screen -= real_location.contents - if(M.active_storage == src) - M.active_storage = null - LAZYREMOVE(is_using, M) - return TRUE - -/datum/component/storage/proc/close(mob/M) - hide_from(M) - -/datum/component/storage/proc/close_all() - . = FALSE - for(var/mob/M in can_see_contents()) - close(M) - . = TRUE //returns TRUE if any mobs actually got a close(M) call - -/datum/component/storage/proc/check_views() - for(var/mob/M in can_see_contents()) - if(!isobserver(M) && !M.CanReach(src, view_only = TRUE)) - close(M) - -/datum/component/storage/proc/emp_act(datum/source, severity) - if(emp_shielded) - return - var/datum/component/storage/concrete/master = master() - master.emp_act(source, severity) - -//This proc draws out the inventory and places the items on it. tx and ty are the upper left tile and mx, my are the bottm right. -//The numbers are calculated from the bottom-left The bottom-left slot being 1,1. -/datum/component/storage/proc/orient_objs(tx, ty, mx, my) - var/atom/real_location = real_location() - var/cx = tx - var/cy = ty - boxes.screen_loc = "[tx]:,[ty] to [mx],[my]" - for(var/obj/O in real_location) - if(QDELETED(O)) - continue - O.screen_loc = "[cx],[cy]" - O.layer = ABOVE_HUD_LAYER - O.plane = ABOVE_HUD_PLANE - cx++ - if(cx > mx) - cx = tx - cy-- - closer.screen_loc = "[mx+1],[my]" - -//Resets something that is being removed from storage. -/datum/component/storage/proc/_removal_reset(atom/movable/thing) - if(!istype(thing)) - return FALSE - var/datum/component/storage/concrete/master = master() - if(!istype(master)) - return FALSE - return master._removal_reset(thing) - -/datum/component/storage/proc/_remove_and_refresh(datum/source, atom/movable/thing) - _removal_reset(thing) - refresh_mob_views() - -//Call this proc to handle the removal of an item from the storage item. The item will be moved to the new_location target, if that is null it's being deleted -/datum/component/storage/proc/remove_from_storage(atom/movable/AM, atom/new_location) - if(!istype(AM)) - return FALSE - var/datum/component/storage/concrete/master = master() - if(!istype(master)) - return FALSE - return master.remove_from_storage(AM, new_location) - -/datum/component/storage/proc/refresh_mob_views() - var/list/seeing = can_see_contents() - for(var/i in seeing) - show_to(i) - return TRUE - -/datum/component/storage/proc/can_see_contents() - var/list/cansee = list() - for(var/mob/M in is_using) - if(M.active_storage == src && M.client) - cansee |= M - else - LAZYREMOVE(is_using, M) - return cansee - -//Tries to dump content -/datum/component/storage/proc/dump_content_at(atom/dest_object, mob/M) - var/atom/A = parent - var/atom/dump_destination = dest_object.get_dumping_location() - if(A.Adjacent(M) && dump_destination && M.Adjacent(dump_destination)) - if(check_locked(null, M, TRUE)) - return FALSE - if(dump_destination.storage_contents_dump_act(src, M)) - playsound(A, "rustle", 50, 1, -5) - A.do_squish(0.8, 1.2) - return TRUE - return FALSE - -//This proc is called when you want to place an item into the storage item. -/datum/component/storage/proc/attackby(datum/source, obj/item/I, mob/M, params) - if(istype(I, /obj/item/hand_labeler)) - var/obj/item/hand_labeler/labeler = I - if(labeler.mode) - return FALSE - . = TRUE //no afterattack - if(iscyborg(M)) - return - if(!can_be_inserted(I, FALSE, M)) - var/atom/real_location = real_location() - if(real_location.contents.len >= max_items) //don't use items on the backpack if they don't fit - return TRUE - return FALSE - handle_item_insertion(I, FALSE, M) - var/atom/A = parent - A.do_squish() - -/datum/component/storage/proc/return_inv(recursive) - var/list/ret = list() - ret |= contents() - if(recursive) - for(var/i in ret.Copy()) - var/atom/A = i - SEND_SIGNAL(A, COMSIG_TRY_STORAGE_RETURN_INVENTORY, ret, TRUE) - return ret - -/datum/component/storage/proc/contents() //ONLY USE IF YOU NEED TO COPY CONTENTS OF REAL LOCATION, COPYING IS NOT AS FAST AS DIRECT ACCESS! - var/atom/real_location = real_location() - return real_location.contents.Copy() - -//Abuses the fact that lists are just references, or something like that. -/datum/component/storage/proc/signal_return_inv(datum/source, list/interface, recursive = TRUE) - if(!islist(interface)) - return FALSE - interface |= return_inv(recursive) - return TRUE - -/datum/component/storage/proc/mousedrop_onto(datum/source, atom/over_object, mob/M) - set waitfor = FALSE - . = COMPONENT_NO_MOUSEDROP - var/atom/A = parent - if(ismob(M)) //all the check for item manipulation are in other places, you can safely open any storages as anything and its not buggy, i checked - A.add_fingerprint(M) - if(!over_object) - return FALSE - if(ismecha(M.loc)) // stops inventory actions in a mech - return FALSE - // this must come before the screen objects only block, dunno why it wasn't before - if(over_object == M) - user_show_to_mob(M) - if(!M.incapacitated()) - if(!istype(over_object, /obj/screen)) - dump_content_at(over_object, M) - return - if(A.loc != M) - return - playsound(A, "rustle", 50, 1, -5) - A.do_jiggle() - if(istype(over_object, /obj/screen/inventory/hand)) - var/obj/screen/inventory/hand/H = over_object - M.putItemFromInventoryInHandIfPossible(A, H.held_index) - return - A.add_fingerprint(M) - -/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE) - var/atom/A = parent - if(!istype(M)) - return FALSE - A.add_fingerprint(M) - if(!force && (check_locked(null, M) || !M.CanReach(parent, view_only = TRUE))) - return FALSE - show_to(M) - -/datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M) - if(isitem(O)) - var/obj/item/I = O - if(iscarbon(M) || isdrone(M)) - var/mob/living/L = M - if(!L.incapacitated() && I == L.get_active_held_item()) - if(!SEND_SIGNAL(I, COMSIG_CONTAINS_STORAGE) && can_be_inserted(I, FALSE)) //If it has storage it should be trying to dump, not insert. - handle_item_insertion(I, FALSE, L) - var/atom/A = parent - A.do_squish() - -//This proc return 1 if the item can be picked up and 0 if it can't. -//Set the stop_messages to stop it from printing messages -/datum/component/storage/proc/can_be_inserted(obj/item/I, stop_messages = FALSE, mob/M) - if(!istype(I) || (I.item_flags & ABSTRACT)) - return FALSE //Not an item - if(I == parent) - return FALSE //no paradoxes for you - var/atom/real_location = real_location() - var/atom/host = parent - if(real_location == I.loc) - return FALSE //Means the item is already in the storage item - if(check_locked(null, M, !stop_messages)) - if(M && !stop_messages) - host.add_fingerprint(M) - return FALSE - if(real_location.contents.len >= max_items) - if(!stop_messages) - to_chat(M, "[host] is full, make some space!") - return FALSE //Storage item is full - if(length(can_hold)) - if(!is_type_in_typecache(I, can_hold)) - if(!stop_messages) - to_chat(M, "[host] cannot hold [I]!") - return FALSE - if(is_type_in_typecache(I, cant_hold)) //Check for specific items which this container can't hold. - if(!stop_messages) - to_chat(M, "[host] cannot hold [I]!") - return FALSE - if(I.w_class > max_w_class) - if(!stop_messages) - to_chat(M, "[I] is too big for [host]!") - return FALSE - var/sum_w_class = I.w_class - for(var/obj/item/_I in real_location) - sum_w_class += _I.w_class //Adds up the combined w_classes which will be in the storage item if the item is added to it. - if(sum_w_class > max_combined_w_class) - if(!stop_messages) - to_chat(M, "[I] won't fit in [host], make some space!") - return FALSE - if(isitem(host)) - var/obj/item/IP = host - var/datum/component/storage/STR_I = I.GetComponent(/datum/component/storage) - if((I.w_class >= IP.w_class) && STR_I && !allow_big_nesting) - if(!stop_messages) - to_chat(M, "[IP] cannot hold [I] as it's a storage item of the same size!") - return FALSE //To prevent the stacking of same sized storage items. - if(HAS_TRAIT(I, TRAIT_NODROP)) //SHOULD be handled in unEquip, but better safe than sorry. - to_chat(M, "\the [I] is stuck to your hand, you can't put it in \the [host]!") - return FALSE - var/datum/component/storage/concrete/master = master() - if(!istype(master)) - return FALSE - return master.slave_can_insert_object(src, I, stop_messages, M) - -/datum/component/storage/proc/_insert_physical_item(obj/item/I, override = FALSE) - return FALSE - -//This proc handles items being inserted. It does not perform any checks of whether an item can or can't be inserted. That's done by can_be_inserted() -//The stop_warning parameter will stop the insertion message from being displayed. It is intended for cases where you are inserting multiple items at once, -//such as when picking up all the items on a tile with one click. -/datum/component/storage/proc/handle_item_insertion(obj/item/I, prevent_warning = FALSE, mob/M, datum/component/storage/remote) - var/atom/parent = src.parent - var/datum/component/storage/concrete/master = master() - if(!istype(master)) - return FALSE - if(silent) - prevent_warning = TRUE - if(M) - parent.add_fingerprint(M) - . = master.handle_item_insertion_from_slave(src, I, prevent_warning, M) - -/datum/component/storage/proc/mob_item_insertion_feedback(mob/user, mob/M, obj/item/I, override = FALSE) - if(silent && !override) - return - if(rustle_sound) - playsound(parent, "rustle", 50, 1, -5) - for(var/mob/viewing in viewers(user, null)) - if(M == viewing) - to_chat(usr, "You put [I] [insert_preposition]to [parent].") - else if(in_range(M, viewing)) //If someone is standing close enough, they can tell what it is... - viewing.show_message("[M] puts [I] [insert_preposition]to [parent].", MSG_VISUAL) - else if(I && I.w_class >= 3) //Otherwise they can only see large or normal items from a distance... - viewing.show_message("[M] puts [I] [insert_preposition]to [parent].", MSG_VISUAL) - -/datum/component/storage/proc/update_icon() - if(isobj(parent)) - var/obj/O = parent - O.update_icon() - -/datum/component/storage/proc/signal_insertion_attempt(datum/source, obj/item/I, mob/M, silent = FALSE, force = FALSE) - if((!force && !can_be_inserted(I, TRUE, M)) || (I == parent)) - return FALSE - return handle_item_insertion(I, silent, M) - -/datum/component/storage/proc/signal_can_insert(datum/source, obj/item/I, mob/M, silent = FALSE) - return can_be_inserted(I, silent, M) - -/datum/component/storage/proc/show_to_ghost(datum/source, mob/dead/observer/M) - return user_show_to_mob(M, TRUE) - -/datum/component/storage/proc/signal_show_attempt(datum/source, mob/showto, force = FALSE) - return user_show_to_mob(showto, force) - -/datum/component/storage/proc/on_check() - return TRUE - -/datum/component/storage/proc/check_locked(datum/source, mob/user, message = FALSE) - . = locked - if(message && . && user) - to_chat(user, "[parent] seems to be locked!") - -/datum/component/storage/proc/signal_take_type(datum/source, type, atom/destination, amount = INFINITY, check_adjacent = FALSE, force = FALSE, mob/user, list/inserted) - if(!force) - if(check_adjacent) - if(!user || !user.CanReach(destination) || !user.CanReach(parent)) - return FALSE - var/list/taking = typecache_filter_list(contents(), typecacheof(type)) - if(taking.len > amount) - taking.len = amount - if(inserted) //duplicated code for performance, don't bother checking retval/checking for list every item. - for(var/i in taking) - if(remove_from_storage(i, destination)) - inserted |= i - else - for(var/i in taking) - remove_from_storage(i, destination) - return TRUE - -/datum/component/storage/proc/remaining_space_items() - var/atom/real_location = real_location() - return max(0, max_items - real_location.contents.len) - -/datum/component/storage/proc/signal_fill_type(datum/source, type, amount = 20, force = FALSE) - var/atom/real_location = real_location() - if(!force) - amount = min(remaining_space_items(), amount) - for(var/i in 1 to amount) - handle_item_insertion(new type(real_location), TRUE) - CHECK_TICK - return TRUE - -/datum/component/storage/proc/on_attack_hand(datum/source, mob/user) - var/atom/A = parent - if(!attack_hand_interact) - return - if(user.active_storage == src && A.loc == user) //if you're already looking inside the storage item - user.active_storage.close(user) - close(user) - . = COMPONENT_NO_ATTACK_HAND - return - - if(rustle_sound) - playsound(A, "rustle", 50, 1, -5) - - if(ishuman(user)) - var/mob/living/carbon/human/H = user - if(H.l_store == A && !H.get_active_held_item()) //Prevents opening if it's in a pocket. - . = COMPONENT_NO_ATTACK_HAND - H.put_in_hands(A) - H.l_store = null - return - if(H.r_store == A && !H.get_active_held_item()) - . = COMPONENT_NO_ATTACK_HAND - H.put_in_hands(A) - H.r_store = null - return - - if(A.loc == user) - . = COMPONENT_NO_ATTACK_HAND - if(!check_locked(source, user, TRUE)) - show_to(user) - A.do_jiggle() - -/datum/component/storage/proc/signal_on_pickup(datum/source, mob/user) - var/atom/A = parent - update_actions() - for(var/mob/M in range(1, A)) - if(M.active_storage == src) - close(M) - -/datum/component/storage/proc/signal_take_obj(datum/source, atom/movable/AM, new_loc, force = FALSE) - if(!(AM in real_location())) - return FALSE - return remove_from_storage(AM, new_loc) - -/datum/component/storage/proc/signal_quick_empty(datum/source, atom/loctarget) - return do_quick_empty(loctarget) - -/datum/component/storage/proc/signal_hide_attempt(datum/source, mob/target) - return hide_from(target) - -/datum/component/storage/proc/on_alt_click(datum/source, mob/user) - if(!isliving(user) || !user.CanReach(parent)) - return - if(check_locked(source, user, TRUE)) - return TRUE - - var/atom/A = parent - if(!quickdraw) - A.add_fingerprint(user) - user_show_to_mob(user) - if(rustle_sound) - playsound(A, "rustle", 50, 1, -5) - return TRUE - - if(user.can_hold_items() && !user.incapacitated()) - var/obj/item/I = locate() in real_location() - if(!I) - return - A.add_fingerprint(user) - remove_from_storage(I, get_turf(user)) - if(!user.put_in_hands(I)) - user.visible_message("[user] fumbles with the [parent], letting [I] fall on the floor.", \ - "You fumble with [parent], letting [I] fall on the floor.") - return TRUE - user.visible_message("[user] draws [I] from [parent]!", "You draw [I] from [parent].") - return TRUE - -/datum/component/storage/proc/action_trigger(datum/signal_source, datum/action/source) - gather_mode_switch(source.owner) - return COMPONENT_ACTION_BLOCK_TRIGGER - -/datum/component/storage/proc/gather_mode_switch(mob/user) - collection_mode = (collection_mode+1)%3 - switch(collection_mode) - if(COLLECT_SAME) - to_chat(user, "[parent] now picks up all items of a single type at once.") - if(COLLECT_EVERYTHING) - to_chat(user, "[parent] now picks up all items in a tile at once.") - if(COLLECT_ONE) - to_chat(user, "[parent] now picks up one item at a time.") +#define COLLECT_ONE 0 +#define COLLECT_EVERYTHING 1 +#define COLLECT_SAME 2 + +#define DROP_NOTHING 0 +#define DROP_AT_PARENT 1 +#define DROP_AT_LOCATION 2 + +// External storage-related logic: +// /mob/proc/ClickOn() in /_onclick/click.dm - clicking items in storages +// /mob/living/Move() in /modules/mob/living/living.dm - hiding storage boxes on mob movement + +/datum/component/storage + dupe_mode = COMPONENT_DUPE_UNIQUE + var/datum/component/storage/concrete/master //If not null, all actions act on master and this is just an access point. + + var/list/can_hold //if this is set, only things in this typecache will fit. + var/list/cant_hold //if this is set, anything in this typecache will not be able to fit. + + var/list/mob/is_using //lazy list of mobs looking at the contents of this storage. + + var/locked = FALSE //when locked nothing can see inside or use it. + + var/max_w_class = WEIGHT_CLASS_SMALL //max size of objects that will fit. + var/max_combined_w_class = 14 //max combined sizes of objects that will fit. + var/max_items = 7 //max number of objects that will fit. + + var/emp_shielded = FALSE + + var/silent = FALSE //whether this makes a message when things are put in. + var/click_gather = FALSE //whether this can be clicked on items to pick it up rather than the other way around. + var/rustle_sound = TRUE //play rustle sound on interact. + var/allow_quick_empty = FALSE //allow empty verb which allows dumping on the floor of everything inside quickly. + var/allow_quick_gather = FALSE //allow toggle mob verb which toggles collecting all items from a tile. + + var/collection_mode = COLLECT_EVERYTHING + + var/insert_preposition = "in" //you put things "in" a bag, but "on" a tray. + + var/display_numerical_stacking = FALSE //stack things of the same type and show as a single object with a number. + + var/obj/screen/storage/boxes //storage display object + var/obj/screen/close/closer //close button object + + var/allow_big_nesting = FALSE //allow storage objects of the same or greater size. + + var/attack_hand_interact = TRUE //interact on attack hand. + var/quickdraw = FALSE //altclick interact + + var/datum/action/item_action/storage_gather_mode/modeswitch_action + + //Screen variables: Do not mess with these vars unless you know what you're doing. They're not defines so storage that isn't in the same location can be supported in the future. + var/screen_max_columns = 7 //These two determine maximum screen sizes. + var/screen_max_rows = INFINITY + var/screen_pixel_x = 16 //These two are pixel values for screen loc of boxes and closer + var/screen_pixel_y = 16 + var/screen_start_x = 4 //These two are where the storage starts being rendered, screen_loc wise. + var/screen_start_y = 2 + //End + + var/limited_random_access = FALSE //Quick if statement in accessible_items to determine if we care at all about what people can access at once. + var/limited_random_access_stack_position = 0 //If >0, can only access top items + var/limited_random_access_stack_bottom_up = FALSE //If TRUE, above becomes bottom items + +/datum/component/storage/Initialize(datum/component/storage/concrete/master) + if(!isatom(parent)) + return COMPONENT_INCOMPATIBLE + if(master) + change_master(master) + boxes = new(null, src) + closer = new(null, src) + orient2hud() + + RegisterSignal(parent, COMSIG_CONTAINS_STORAGE, .proc/on_check) + RegisterSignal(parent, COMSIG_IS_STORAGE_LOCKED, .proc/check_locked) + RegisterSignal(parent, COMSIG_TRY_STORAGE_SHOW, .proc/signal_show_attempt) + RegisterSignal(parent, COMSIG_TRY_STORAGE_INSERT, .proc/signal_insertion_attempt) + RegisterSignal(parent, COMSIG_TRY_STORAGE_CAN_INSERT, .proc/signal_can_insert) + RegisterSignal(parent, COMSIG_TRY_STORAGE_TAKE_TYPE, .proc/signal_take_type) + RegisterSignal(parent, COMSIG_TRY_STORAGE_FILL_TYPE, .proc/signal_fill_type) + RegisterSignal(parent, COMSIG_TRY_STORAGE_SET_LOCKSTATE, .proc/set_locked) + RegisterSignal(parent, COMSIG_TRY_STORAGE_TAKE, .proc/signal_take_obj) + RegisterSignal(parent, COMSIG_TRY_STORAGE_QUICK_EMPTY, .proc/signal_quick_empty) + RegisterSignal(parent, COMSIG_TRY_STORAGE_HIDE_FROM, .proc/signal_hide_attempt) + RegisterSignal(parent, COMSIG_TRY_STORAGE_HIDE_ALL, .proc/close_all) + RegisterSignal(parent, COMSIG_TRY_STORAGE_RETURN_INVENTORY, .proc/signal_return_inv) + + RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/attackby) + + RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, .proc/on_attack_hand) + RegisterSignal(parent, COMSIG_ATOM_ATTACK_PAW, .proc/on_attack_hand) + RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, .proc/emp_act) + RegisterSignal(parent, COMSIG_ATOM_ATTACK_GHOST, .proc/show_to_ghost) + RegisterSignal(parent, COMSIG_ATOM_ENTERED, .proc/refresh_mob_views) + RegisterSignal(parent, COMSIG_ATOM_EXITED, .proc/_remove_and_refresh) + RegisterSignal(parent, COMSIG_ATOM_CANREACH, .proc/canreach_react) + + RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, .proc/preattack_intercept) + RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, .proc/attack_self) + RegisterSignal(parent, COMSIG_ITEM_PICKUP, .proc/signal_on_pickup) + + RegisterSignal(parent, COMSIG_MOVABLE_POST_THROW, .proc/close_all) + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/check_views) + + RegisterSignal(parent, COMSIG_CLICK_ALT, .proc/on_alt_click) + RegisterSignal(parent, COMSIG_MOUSEDROP_ONTO, .proc/mousedrop_onto) + RegisterSignal(parent, COMSIG_MOUSEDROPPED_ONTO, .proc/mousedrop_receive) + + update_actions() + +/datum/component/storage/Destroy() + close_all() + QDEL_NULL(boxes) + QDEL_NULL(closer) + LAZYCLEARLIST(is_using) + return ..() + +/datum/component/storage/PreTransfer() + update_actions() + +/datum/component/storage/proc/update_actions() + QDEL_NULL(modeswitch_action) + if(!isitem(parent) || !allow_quick_gather) + return + var/obj/item/I = parent + modeswitch_action = new(I) + RegisterSignal(modeswitch_action, COMSIG_ACTION_TRIGGER, .proc/action_trigger) + if(I.obj_flags & IN_INVENTORY) + var/mob/M = I.loc + if(!istype(M)) + return + modeswitch_action.Grant(M) + +/datum/component/storage/proc/change_master(datum/component/storage/concrete/new_master) + if(new_master == src || (!isnull(new_master) && !istype(new_master))) + return FALSE + if(master) + master.on_slave_unlink(src) + master = new_master + if(master) + master.on_slave_link(src) + return TRUE + +/datum/component/storage/proc/master() + if(master == src) + return //infinite loops yo. + return master + +/datum/component/storage/proc/real_location() + var/datum/component/storage/concrete/master = master() + return master? master.real_location() : null + +//What players can access +//this proc can probably eat a refactor at some point. +/datum/component/storage/proc/accessible_items(random_access = TRUE) + var/list/contents = contents() + if(contents) + if(limited_random_access && random_access) + if(limited_random_access_stack_position && (length(contents) > limited_random_access_stack_position)) + if(limited_random_access_stack_bottom_up) + contents.Cut(1, limited_random_access_stack_position + 1) + else + contents.Cut(1, length(contents) - limited_random_access_stack_position + 1) + return contents + +/datum/component/storage/proc/canreach_react(datum/source, list/next) + var/datum/component/storage/concrete/master = master() + if(!master) + return + . = COMPONENT_BLOCK_REACH + next += master.parent + for(var/i in master.slaves) + var/datum/component/storage/slave = i + next += slave.parent + +/datum/component/storage/proc/attack_self(datum/source, mob/M) + if(check_locked(source, M, TRUE)) + return FALSE + if((M.get_active_held_item() == parent) && allow_quick_empty) + quick_empty(M) + +/datum/component/storage/proc/preattack_intercept(datum/source, obj/O, mob/M, params) + if(!isitem(O) || !click_gather || SEND_SIGNAL(O, COMSIG_CONTAINS_STORAGE)) + return FALSE + . = COMPONENT_NO_ATTACK + if(check_locked(source, M, TRUE)) + return FALSE + var/atom/A = parent + var/obj/item/I = O + if(collection_mode == COLLECT_ONE) + if(can_be_inserted(I, null, M)) + handle_item_insertion(I, null, M) + A.do_squish() + return + if(!isturf(I.loc)) + return + var/list/things = I.loc.contents.Copy() + if(collection_mode == COLLECT_SAME) + things = typecache_filter_list(things, typecacheof(I.type)) + var/len = length(things) + if(!len) + to_chat(M, "You failed to pick up anything with [parent].") + return + var/datum/progressbar/progress = new(M, len, I.loc) + var/list/rejections = list() + while(do_after(M, 10, TRUE, parent, FALSE, CALLBACK(src, .proc/handle_mass_pickup, things, I.loc, rejections, progress))) + stoplag(1) + qdel(progress) + to_chat(M, "You put everything you could [insert_preposition] [parent].") + A.do_squish(1.4, 0.4) + +/datum/component/storage/proc/handle_mass_item_insertion(list/things, datum/component/storage/src_object, mob/user, datum/progressbar/progress) + var/atom/source_real_location = src_object.real_location() + for(var/obj/item/I in things) + things -= I + if(I.loc != source_real_location) + continue + if(user.active_storage != src_object) + if(I.on_found(user)) + break + if(can_be_inserted(I,FALSE,user)) + handle_item_insertion(I, TRUE, user) + if (TICK_CHECK) + progress.update(progress.goal - things.len) + return TRUE + + progress.update(progress.goal - things.len) + return FALSE + +/datum/component/storage/proc/handle_mass_pickup(list/things, atom/thing_loc, list/rejections, datum/progressbar/progress) + var/atom/real_location = real_location() + 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(!can_be_inserted(I, stop_messages = TRUE)) // Note can_be_inserted still makes noise when the answer is no + if(real_location.contents.len >= max_items) + break + rejections += I.type // therefore full bags are still a little spammy + continue + + handle_item_insertion(I, TRUE) //The TRUE stops the "You put the [parent] 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 + +/datum/component/storage/proc/quick_empty(mob/M) + var/atom/A = parent + if(!M.canUseStorage() || !A.Adjacent(M) || M.incapacitated()) + return + if(check_locked(null, M, TRUE)) + return FALSE + A.add_fingerprint(M) + to_chat(M, "You start dumping out [parent].") + var/turf/T = get_turf(A) + var/list/things = contents() + var/datum/progressbar/progress = new(M, length(things), T) + while (do_after(M, 10, TRUE, T, FALSE, CALLBACK(src, .proc/mass_remove_from_storage, T, things, progress))) + stoplag(1) + qdel(progress) + A.do_squish(0.8, 1.2) + +/datum/component/storage/proc/mass_remove_from_storage(atom/target, list/things, datum/progressbar/progress, trigger_on_found = TRUE) + var/atom/real_location = real_location() + for(var/obj/item/I in things) + things -= I + if(I.loc != real_location) + continue + remove_from_storage(I, target) + if(trigger_on_found && I.on_found()) + return FALSE + if(TICK_CHECK) + progress.update(progress.goal - length(things)) + return TRUE + progress.update(progress.goal - length(things)) + return FALSE + +/datum/component/storage/proc/do_quick_empty(atom/_target) + if(!_target) + _target = get_turf(parent) + if(usr) + hide_from(usr) + var/list/contents = contents() + var/atom/real_location = real_location() + for(var/obj/item/I in contents) + if(I.loc != real_location) + continue + remove_from_storage(I, _target) + return TRUE + +/datum/component/storage/proc/set_locked(datum/source, new_state) + locked = new_state + if(check_locked()) + close_all() + +/datum/component/storage/proc/_process_numerical_display() + . = list() + for(var/obj/item/I in accessible_items()) + if(QDELETED(I)) + continue + if(!.[I.type]) + .[I.type] = new /datum/numbered_display(I, 1) + else + var/datum/numbered_display/ND = .[I.type] + ND.number++ + . = sortTim(., /proc/cmp_numbered_displays_name_asc, associative = TRUE) + +//This proc determines the size of the inventory to be displayed. Please touch it only if you know what you're doing. +/datum/component/storage/proc/orient2hud(mob/user, maxcolumns) + var/list/accessible_contents = accessible_items() + var/adjusted_contents = length(accessible_contents) + + //Numbered contents display + var/list/datum/numbered_display/numbered_contents + if(display_numerical_stacking) + numbered_contents = _process_numerical_display() + adjusted_contents = numbered_contents.len + + var/columns = CLAMP(max_items, 1, maxcolumns ? maxcolumns : screen_max_columns) + var/rows = CLAMP(CEILING(adjusted_contents / columns, 1), 1, screen_max_rows) + standard_orient_objs(rows, columns, numbered_contents) + +//This proc draws out the inventory and places the items on it. It uses the standard position. +/datum/component/storage/proc/standard_orient_objs(rows, cols, list/obj/item/numerical_display_contents) + boxes.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+cols-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]" + var/cx = screen_start_x + var/cy = screen_start_y + if(islist(numerical_display_contents)) + for(var/type in numerical_display_contents) + var/datum/numbered_display/ND = numerical_display_contents[type] + ND.sample_object.mouse_opacity = MOUSE_OPACITY_OPAQUE + ND.sample_object.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]" + ND.sample_object.maptext = "[(ND.number > 1)? "[ND.number]" : ""]" + ND.sample_object.layer = ABOVE_HUD_LAYER + ND.sample_object.plane = ABOVE_HUD_PLANE + cx++ + if(cx - screen_start_x >= cols) + cx = screen_start_x + cy++ + if(cy - screen_start_y >= rows) + break + else + for(var/obj/O in accessible_items()) + if(QDELETED(O)) + continue + O.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip" + O.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]" + O.maptext = "" + O.layer = ABOVE_HUD_LAYER + O.plane = ABOVE_HUD_PLANE + cx++ + if(cx - screen_start_x >= cols) + cx = screen_start_x + cy++ + if(cy - screen_start_y >= rows) + break + closer.screen_loc = "[screen_start_x + cols]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y]" + +/datum/component/storage/proc/show_to(mob/M) + if(!M.client) + return FALSE + var/list/cview = getviewsize(M.client.view) + var/maxallowedscreensize = cview[1]-8 + if(M.active_storage != src && (M.stat == CONSCIOUS)) + for(var/obj/item/I in accessible_items()) + if(I.on_found(M)) + return FALSE + if(M.active_storage) + M.active_storage.hide_from(M) + orient2hud(M, (isliving(M) ? maxallowedscreensize : 7)) + M.client.screen |= boxes + M.client.screen |= closer + M.client.screen |= accessible_items() + M.active_storage = src + LAZYOR(is_using, M) + return TRUE + +/datum/component/storage/proc/hide_from(mob/M) + if(!M.client) + return TRUE + var/atom/real_location = real_location() + M.client.screen -= boxes + M.client.screen -= closer + M.client.screen -= real_location.contents + if(M.active_storage == src) + M.active_storage = null + LAZYREMOVE(is_using, M) + return TRUE + +/datum/component/storage/proc/close(mob/M) + hide_from(M) + +/datum/component/storage/proc/close_all() + . = FALSE + for(var/mob/M in can_see_contents()) + close(M) + . = TRUE //returns TRUE if any mobs actually got a close(M) call + +/datum/component/storage/proc/check_views() + for(var/mob/M in can_see_contents()) + if(!isobserver(M) && !M.CanReach(src, view_only = TRUE)) + close(M) + +/datum/component/storage/proc/emp_act(datum/source, severity) + if(emp_shielded) + return + var/datum/component/storage/concrete/master = master() + master.emp_act(source, severity) + +//This proc draws out the inventory and places the items on it. tx and ty are the upper left tile and mx, my are the bottm right. +//The numbers are calculated from the bottom-left The bottom-left slot being 1,1. +/datum/component/storage/proc/orient_objs(tx, ty, mx, my) + var/atom/real_location = real_location() + var/cx = tx + var/cy = ty + boxes.screen_loc = "[tx]:,[ty] to [mx],[my]" + for(var/obj/O in real_location) + if(QDELETED(O)) + continue + O.screen_loc = "[cx],[cy]" + O.layer = ABOVE_HUD_LAYER + O.plane = ABOVE_HUD_PLANE + cx++ + if(cx > mx) + cx = tx + cy-- + closer.screen_loc = "[mx+1],[my]" + +//Resets something that is being removed from storage. +/datum/component/storage/proc/_removal_reset(atom/movable/thing) + if(!istype(thing)) + return FALSE + var/datum/component/storage/concrete/master = master() + if(!istype(master)) + return FALSE + return master._removal_reset(thing) + +/datum/component/storage/proc/_remove_and_refresh(datum/source, atom/movable/thing) + _removal_reset(thing) + refresh_mob_views() + +//Call this proc to handle the removal of an item from the storage item. The item will be moved to the new_location target, if that is null it's being deleted +/datum/component/storage/proc/remove_from_storage(atom/movable/AM, atom/new_location) + if(!istype(AM)) + return FALSE + var/datum/component/storage/concrete/master = master() + if(!istype(master)) + return FALSE + return master.remove_from_storage(AM, new_location) + +/datum/component/storage/proc/refresh_mob_views() + var/list/seeing = can_see_contents() + for(var/i in seeing) + show_to(i) + return TRUE + +/datum/component/storage/proc/can_see_contents() + var/list/cansee = list() + for(var/mob/M in is_using) + if(M.active_storage == src && M.client) + cansee |= M + else + LAZYREMOVE(is_using, M) + return cansee + +//Tries to dump content +/datum/component/storage/proc/dump_content_at(atom/dest_object, mob/M) + var/atom/A = parent + var/atom/dump_destination = dest_object.get_dumping_location() + if(A.Adjacent(M) && dump_destination && M.Adjacent(dump_destination)) + if(check_locked(null, M, TRUE)) + return FALSE + if(dump_destination.storage_contents_dump_act(src, M)) + playsound(A, "rustle", 50, 1, -5) + A.do_squish(0.8, 1.2) + return TRUE + return FALSE + +//This proc is called when you want to place an item into the storage item. +/datum/component/storage/proc/attackby(datum/source, obj/item/I, mob/M, params) + if(istype(I, /obj/item/hand_labeler)) + var/obj/item/hand_labeler/labeler = I + if(labeler.mode) + return FALSE + . = TRUE //no afterattack + if(iscyborg(M)) + return + if(!can_be_inserted(I, FALSE, M)) + var/atom/real_location = real_location() + if(real_location.contents.len >= max_items) //don't use items on the backpack if they don't fit + return TRUE + return FALSE + handle_item_insertion(I, FALSE, M) + var/atom/A = parent + A.do_squish() + +/datum/component/storage/proc/return_inv(recursive) + var/list/ret = list() + ret |= contents() + if(recursive) + for(var/i in ret.Copy()) + var/atom/A = i + SEND_SIGNAL(A, COMSIG_TRY_STORAGE_RETURN_INVENTORY, ret, TRUE) + return ret + +/datum/component/storage/proc/contents() //ONLY USE IF YOU NEED TO COPY CONTENTS OF REAL LOCATION, COPYING IS NOT AS FAST AS DIRECT ACCESS! + var/atom/real_location = real_location() + return real_location.contents.Copy() + +//Abuses the fact that lists are just references, or something like that. +/datum/component/storage/proc/signal_return_inv(datum/source, list/interface, recursive = TRUE) + if(!islist(interface)) + return FALSE + interface |= return_inv(recursive) + return TRUE + +/datum/component/storage/proc/mousedrop_onto(datum/source, atom/over_object, mob/M) + set waitfor = FALSE + . = COMPONENT_NO_MOUSEDROP + var/atom/A = parent + if(ismob(M)) //all the check for item manipulation are in other places, you can safely open any storages as anything and its not buggy, i checked + A.add_fingerprint(M) + if(!over_object) + return FALSE + if(ismecha(M.loc)) // stops inventory actions in a mech + return FALSE + // this must come before the screen objects only block, dunno why it wasn't before + if(over_object == M) + user_show_to_mob(M) + if(!M.incapacitated()) + if(!istype(over_object, /obj/screen)) + dump_content_at(over_object, M) + return + if(A.loc != M) + return + playsound(A, "rustle", 50, 1, -5) + A.do_jiggle() + if(istype(over_object, /obj/screen/inventory/hand)) + var/obj/screen/inventory/hand/H = over_object + M.putItemFromInventoryInHandIfPossible(A, H.held_index) + return + A.add_fingerprint(M) + +/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE) + var/atom/A = parent + if(!istype(M)) + return FALSE + A.add_fingerprint(M) + if(!force && (check_locked(null, M) || !M.CanReach(parent, view_only = TRUE))) + return FALSE + show_to(M) + +/datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M) + if(isitem(O)) + var/obj/item/I = O + if(iscarbon(M) || isdrone(M)) + var/mob/living/L = M + if(!L.incapacitated() && I == L.get_active_held_item()) + if(!SEND_SIGNAL(I, COMSIG_CONTAINS_STORAGE) && can_be_inserted(I, FALSE)) //If it has storage it should be trying to dump, not insert. + handle_item_insertion(I, FALSE, L) + var/atom/A = parent + A.do_squish() + +//This proc return 1 if the item can be picked up and 0 if it can't. +//Set the stop_messages to stop it from printing messages +/datum/component/storage/proc/can_be_inserted(obj/item/I, stop_messages = FALSE, mob/M) + if(!istype(I) || (I.item_flags & ABSTRACT)) + return FALSE //Not an item + if(I == parent) + return FALSE //no paradoxes for you + var/atom/real_location = real_location() + var/atom/host = parent + if(real_location == I.loc) + return FALSE //Means the item is already in the storage item + if(check_locked(null, M, !stop_messages)) + if(M && !stop_messages) + host.add_fingerprint(M) + return FALSE + if(real_location.contents.len >= max_items) + if(!stop_messages) + to_chat(M, "[host] is full, make some space!") + return FALSE //Storage item is full + if(length(can_hold)) + if(!is_type_in_typecache(I, can_hold)) + if(!stop_messages) + to_chat(M, "[host] cannot hold [I]!") + return FALSE + if(is_type_in_typecache(I, cant_hold)) //Check for specific items which this container can't hold. + if(!stop_messages) + to_chat(M, "[host] cannot hold [I]!") + return FALSE + if(I.w_class > max_w_class) + if(!stop_messages) + to_chat(M, "[I] is too big for [host]!") + return FALSE + var/sum_w_class = I.w_class + for(var/obj/item/_I in real_location) + sum_w_class += _I.w_class //Adds up the combined w_classes which will be in the storage item if the item is added to it. + if(sum_w_class > max_combined_w_class) + if(!stop_messages) + to_chat(M, "[I] won't fit in [host], make some space!") + return FALSE + if(isitem(host)) + var/obj/item/IP = host + var/datum/component/storage/STR_I = I.GetComponent(/datum/component/storage) + if((I.w_class >= IP.w_class) && STR_I && !allow_big_nesting) + if(!stop_messages) + to_chat(M, "[IP] cannot hold [I] as it's a storage item of the same size!") + return FALSE //To prevent the stacking of same sized storage items. + if(HAS_TRAIT(I, TRAIT_NODROP)) //SHOULD be handled in unEquip, but better safe than sorry. + to_chat(M, "\the [I] is stuck to your hand, you can't put it in \the [host]!") + return FALSE + var/datum/component/storage/concrete/master = master() + if(!istype(master)) + return FALSE + return master.slave_can_insert_object(src, I, stop_messages, M) + +/datum/component/storage/proc/_insert_physical_item(obj/item/I, override = FALSE) + return FALSE + +//This proc handles items being inserted. It does not perform any checks of whether an item can or can't be inserted. That's done by can_be_inserted() +//The stop_warning parameter will stop the insertion message from being displayed. It is intended for cases where you are inserting multiple items at once, +//such as when picking up all the items on a tile with one click. +/datum/component/storage/proc/handle_item_insertion(obj/item/I, prevent_warning = FALSE, mob/M, datum/component/storage/remote) + var/atom/parent = src.parent + var/datum/component/storage/concrete/master = master() + if(!istype(master)) + return FALSE + if(silent) + prevent_warning = TRUE + if(M) + parent.add_fingerprint(M) + . = master.handle_item_insertion_from_slave(src, I, prevent_warning, M) + +/datum/component/storage/proc/mob_item_insertion_feedback(mob/user, mob/M, obj/item/I, override = FALSE) + if(silent && !override) + return + if(rustle_sound) + playsound(parent, "rustle", 50, 1, -5) + for(var/mob/viewing in viewers(user, null)) + if(M == viewing) + to_chat(usr, "You put [I] [insert_preposition]to [parent].") + else if(in_range(M, viewing)) //If someone is standing close enough, they can tell what it is... + viewing.show_message("[M] puts [I] [insert_preposition]to [parent].", MSG_VISUAL) + else if(I && I.w_class >= 3) //Otherwise they can only see large or normal items from a distance... + viewing.show_message("[M] puts [I] [insert_preposition]to [parent].", MSG_VISUAL) + +/datum/component/storage/proc/update_icon() + if(isobj(parent)) + var/obj/O = parent + O.update_icon() + +/datum/component/storage/proc/signal_insertion_attempt(datum/source, obj/item/I, mob/M, silent = FALSE, force = FALSE) + if((!force && !can_be_inserted(I, TRUE, M)) || (I == parent)) + return FALSE + return handle_item_insertion(I, silent, M) + +/datum/component/storage/proc/signal_can_insert(datum/source, obj/item/I, mob/M, silent = FALSE) + return can_be_inserted(I, silent, M) + +/datum/component/storage/proc/show_to_ghost(datum/source, mob/dead/observer/M) + return user_show_to_mob(M, TRUE) + +/datum/component/storage/proc/signal_show_attempt(datum/source, mob/showto, force = FALSE) + return user_show_to_mob(showto, force) + +/datum/component/storage/proc/on_check() + return TRUE + +/datum/component/storage/proc/check_locked(datum/source, mob/user, message = FALSE) + . = locked + if(message && . && user) + to_chat(user, "[parent] seems to be locked!") + +/datum/component/storage/proc/signal_take_type(datum/source, type, atom/destination, amount = INFINITY, check_adjacent = FALSE, force = FALSE, mob/user, list/inserted) + if(!force) + if(check_adjacent) + if(!user || !user.CanReach(destination) || !user.CanReach(parent)) + return FALSE + var/list/taking = typecache_filter_list(contents(), typecacheof(type)) + if(taking.len > amount) + taking.len = amount + if(inserted) //duplicated code for performance, don't bother checking retval/checking for list every item. + for(var/i in taking) + if(remove_from_storage(i, destination)) + inserted |= i + else + for(var/i in taking) + remove_from_storage(i, destination) + return TRUE + +/datum/component/storage/proc/remaining_space_items() + var/atom/real_location = real_location() + return max(0, max_items - real_location.contents.len) + +/datum/component/storage/proc/signal_fill_type(datum/source, type, amount = 20, force = FALSE) + var/atom/real_location = real_location() + if(!force) + amount = min(remaining_space_items(), amount) + for(var/i in 1 to amount) + handle_item_insertion(new type(real_location), TRUE) + CHECK_TICK + return TRUE + +/datum/component/storage/proc/on_attack_hand(datum/source, mob/user) + var/atom/A = parent + if(!attack_hand_interact) + return + if(user.active_storage == src && A.loc == user) //if you're already looking inside the storage item + user.active_storage.close(user) + close(user) + . = COMPONENT_NO_ATTACK_HAND + return + + if(rustle_sound) + playsound(A, "rustle", 50, 1, -5) + + if(ishuman(user)) + var/mob/living/carbon/human/H = user + if(H.l_store == A && !H.get_active_held_item()) //Prevents opening if it's in a pocket. + . = COMPONENT_NO_ATTACK_HAND + H.put_in_hands(A) + H.l_store = null + return + if(H.r_store == A && !H.get_active_held_item()) + . = COMPONENT_NO_ATTACK_HAND + H.put_in_hands(A) + H.r_store = null + return + + if(A.loc == user) + . = COMPONENT_NO_ATTACK_HAND + if(!check_locked(source, user, TRUE)) + show_to(user) + A.do_jiggle() + +/datum/component/storage/proc/signal_on_pickup(datum/source, mob/user) + var/atom/A = parent + update_actions() + for(var/mob/M in range(1, A)) + if(M.active_storage == src) + close(M) + +/datum/component/storage/proc/signal_take_obj(datum/source, atom/movable/AM, new_loc, force = FALSE) + if(!(AM in real_location())) + return FALSE + return remove_from_storage(AM, new_loc) + +/datum/component/storage/proc/signal_quick_empty(datum/source, atom/loctarget) + return do_quick_empty(loctarget) + +/datum/component/storage/proc/signal_hide_attempt(datum/source, mob/target) + return hide_from(target) + +/datum/component/storage/proc/on_alt_click(datum/source, mob/user) + if(!isliving(user) || !user.CanReach(parent)) + return + if(check_locked(source, user, TRUE)) + return TRUE + + var/atom/A = parent + if(!quickdraw) + A.add_fingerprint(user) + user_show_to_mob(user) + if(rustle_sound) + playsound(A, "rustle", 50, 1, -5) + return TRUE + + if(user.can_hold_items() && !user.incapacitated()) + var/obj/item/I = locate() in real_location() + if(!I) + return + A.add_fingerprint(user) + remove_from_storage(I, get_turf(user)) + if(!user.put_in_hands(I)) + user.visible_message("[user] fumbles with the [parent], letting [I] fall on the floor.", \ + "You fumble with [parent], letting [I] fall on the floor.") + return TRUE + user.visible_message("[user] draws [I] from [parent]!", "You draw [I] from [parent].") + return TRUE + +/datum/component/storage/proc/action_trigger(datum/signal_source, datum/action/source) + gather_mode_switch(source.owner) + return COMPONENT_ACTION_BLOCK_TRIGGER + +/datum/component/storage/proc/gather_mode_switch(mob/user) + collection_mode = (collection_mode+1)%3 + switch(collection_mode) + if(COLLECT_SAME) + to_chat(user, "[parent] now picks up all items of a single type at once.") + if(COLLECT_EVERYTHING) + to_chat(user, "[parent] now picks up all items in a tile at once.") + if(COLLECT_ONE) + to_chat(user, "[parent] now picks up one item at a time.") diff --git a/code/datums/components/wet_floor.dm b/code/datums/components/wet_floor.dm index d6c5c0bf83..550ff95324 100644 --- a/code/datums/components/wet_floor.dm +++ b/code/datums/components/wet_floor.dm @@ -1,211 +1,211 @@ -/datum/component/wet_floor - dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS - can_transfer = TRUE - var/highest_strength = TURF_DRY - var/lube_flags = NONE //why do we have this? - var/list/time_left_list //In deciseconds. - var/static/mutable_appearance/permafrost_overlay = mutable_appearance('icons/effects/water.dmi', "ice_floor") - var/static/mutable_appearance/ice_overlay = mutable_appearance('icons/turf/overlays.dmi', "snowfloor") - var/static/mutable_appearance/water_overlay = mutable_appearance('icons/effects/water.dmi', "wet_floor_static") - var/static/mutable_appearance/generic_turf_overlay = mutable_appearance('icons/effects/water.dmi', "wet_static") - var/current_overlay - var/permanent = FALSE - var/last_process = 0 - -/datum/component/wet_floor/InheritComponent(datum/newcomp, orig, argslist) - if(!newcomp) //We are getting passed the arguments of a would-be new component, but not a new component - add_wet(arglist(argslist)) - else //We are being passed in a full blown component - var/datum/component/wet_floor/WF = newcomp //Lets make an assumption - if(WF.gc()) //See if it's even valid, still. Also does LAZYLEN and stuff for us. - CRASH("Wet floor component tried to inherit another, but the other was able to garbage collect while being inherited! What a waste of time!") - return - for(var/i in WF.time_left_list) - add_wet(text2num(i), WF.time_left_list[i]) - -/datum/component/wet_floor/Initialize(strength, duration_minimum, duration_add, duration_maximum, _permanent = FALSE) - if(!isopenturf(parent)) - return COMPONENT_INCOMPATIBLE - add_wet(strength, duration_minimum, duration_add, duration_maximum) - permanent = _permanent - if(!permanent) - START_PROCESSING(SSwet_floors, src) - addtimer(CALLBACK(src, .proc/gc, TRUE), 1) //GC after initialization. - last_process = world.time - -/datum/component/wet_floor/RegisterWithParent() - . = ..() - RegisterSignal(parent, COMSIG_TURF_IS_WET, .proc/is_wet) - RegisterSignal(parent, COMSIG_TURF_MAKE_DRY, .proc/dry) - -/datum/component/wet_floor/UnregisterFromParent() - . = ..() - UnregisterSignal(parent, list(COMSIG_TURF_IS_WET, COMSIG_TURF_MAKE_DRY)) - -/datum/component/wet_floor/Destroy() - STOP_PROCESSING(SSwet_floors, src) - var/turf/T = parent - qdel(T.GetComponent(/datum/component/slippery)) - if(istype(T)) //If this is false there is so many things wrong with it. - T.cut_overlay(current_overlay) - else - stack_trace("Warning: Wet floor component wasn't on a turf when being destroyed! This is really bad!") - return ..() - -/datum/component/wet_floor/proc/update_overlay() - var/intended - if(!istype(parent, /turf/open/floor)) - intended = generic_turf_overlay - else - switch(highest_strength) - if(TURF_WET_PERMAFROST) - intended = permafrost_overlay - if(TURF_WET_ICE) - intended = ice_overlay - else - intended = water_overlay - if(current_overlay != intended) - var/turf/T = parent - T.cut_overlay(current_overlay) - T.add_overlay(intended) - current_overlay = intended - -/datum/component/wet_floor/proc/AfterSlip(mob/living/L) - if(highest_strength == TURF_WET_LUBE) - L.confused = max(L.confused, 8) - -/datum/component/wet_floor/proc/update_flags() - var/intensity - lube_flags = NONE - switch(highest_strength) - if(TURF_WET_WATER) - intensity = 60 - lube_flags = NO_SLIP_WHEN_WALKING - if(TURF_WET_LUBE) - intensity = 80 - lube_flags = SLIDE | GALOSHES_DONT_HELP - if(TURF_WET_ICE) - intensity = 120 - lube_flags = SLIDE | GALOSHES_DONT_HELP - if(TURF_WET_PERMAFROST) - intensity = 120 - lube_flags = SLIDE_ICE | GALOSHES_DONT_HELP - if(TURF_WET_SUPERLUBE) - intensity = 120 - lube_flags = SLIDE | GALOSHES_DONT_HELP | SLIP_WHEN_CRAWLING - else - qdel(parent.GetComponent(/datum/component/slippery)) - return - - var/datum/component/slippery/S = parent.LoadComponent(/datum/component/slippery, NONE, CALLBACK(src, .proc/AfterSlip)) - S.intensity = intensity - S.lube_flags = lube_flags - -/datum/component/wet_floor/proc/dry(datum/source, strength = TURF_WET_WATER, immediate = FALSE, duration_decrease = INFINITY) - for(var/i in time_left_list) - if(text2num(i) <= strength) - time_left_list[i] = max(0, time_left_list[i] - duration_decrease) - if(immediate) - check() - -/datum/component/wet_floor/proc/max_time_left() - . = 0 - for(var/i in time_left_list) - . = max(., time_left_list[i]) - -/datum/component/wet_floor/process() - var/turf/open/T = parent - var/diff = world.time - last_process - var/decrease = 0 - var/t = T.GetTemperature() - switch(t) - if(-INFINITY to T0C) - add_wet(TURF_WET_ICE, max_time_left()) //Water freezes into ice! - if(T0C to T0C + 100) - decrease = ((T.air.temperature - T0C) / SSwet_floors.temperature_coeff) * (diff / SSwet_floors.time_ratio) - if(T0C + 100 to INFINITY) - decrease = INFINITY - decrease = max(0, decrease) - if((is_wet() & TURF_WET_ICE) && t > T0C) //Ice melts into water! - for(var/obj/O in T.contents) - if(O.obj_flags & FROZEN) - O.make_unfrozen() - add_wet(TURF_WET_WATER, max_time_left()) - dry(null, TURF_WET_ICE) - dry(null, ALL, FALSE, decrease) - check() - last_process = world.time - -/datum/component/wet_floor/proc/update_strength() - highest_strength = 0 //Not bitflag. - for(var/i in time_left_list) - highest_strength = max(highest_strength, text2num(i)) - -/datum/component/wet_floor/proc/is_wet() - . = 0 - for(var/i in time_left_list) - . |= text2num(i) - -/datum/component/wet_floor/PreTransfer() - var/turf/O = parent - O.cut_overlay(current_overlay) - //That turf is no longer slippery, we're out of here - //Slippery components don't transfer due to callbacks - qdel(O.GetComponent(/datum/component/slippery)) - -/datum/component/wet_floor/PostTransfer() - if(!isopenturf(parent)) - return COMPONENT_INCOMPATIBLE - var/turf/T = parent - T.add_overlay(current_overlay) - //Make sure to add/update any slippery component on the new turf (update_flags calls LoadComponent) - update_flags() - - //NB it's possible we get deleted after this, due to inherit - -/datum/component/wet_floor/proc/add_wet(type, duration_minimum = 0, duration_add = 0, duration_maximum = MAXIMUM_WET_TIME, _permanent = FALSE) - var/static/list/allowed_types = list(TURF_WET_WATER, TURF_WET_LUBE, TURF_WET_ICE, TURF_WET_PERMAFROST, TURF_WET_SUPERLUBE) - if(duration_minimum <= 0 || !type) - return FALSE - if(type in allowed_types) - return _do_add_wet(type, duration_minimum, duration_add, duration_maximum) - else - . = NONE - for(var/i in allowed_types) - if(!(type & i)) - continue - . |= _do_add_wet(i, duration_minimum, duration_add, duration_maximum) - if(_permanent) - permanent = TRUE - STOP_PROCESSING(SSwet_floors, src) - -/datum/component/wet_floor/proc/_do_add_wet(type, duration_minimum, duration_add, duration_maximum) - var/time = 0 - if(LAZYACCESS(time_left_list, "[type]")) - time = CLAMP(LAZYACCESS(time_left_list, "[type]") + duration_add, duration_minimum, duration_maximum) - else - time = min(duration_minimum, duration_maximum) - LAZYSET(time_left_list, "[type]", time) - check(TRUE) - return TRUE - -/datum/component/wet_floor/proc/gc(on_init = FALSE) - if(!LAZYLEN(time_left_list)) - if(on_init) - var/turf/T = parent - stack_trace("Warning: Wet floor component gc'd right after initialization! What a waste of time and CPU! Type = [T? T.type : "ERROR - NO PARENT"], Location = [istype(T)? AREACOORD(T) : "ERROR - INVALID PARENT"].") - qdel(src) - return TRUE - return FALSE - -/datum/component/wet_floor/proc/check(force_update = FALSE) - var/changed = FALSE - for(var/i in time_left_list) - if(time_left_list[i] <= 0) - time_left_list -= i - changed = TRUE - if(changed || force_update) - update_strength() - update_overlay() - update_flags() - gc() +/datum/component/wet_floor + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS + can_transfer = TRUE + var/highest_strength = TURF_DRY + var/lube_flags = NONE //why do we have this? + var/list/time_left_list //In deciseconds. + var/static/mutable_appearance/permafrost_overlay = mutable_appearance('icons/effects/water.dmi', "ice_floor") + var/static/mutable_appearance/ice_overlay = mutable_appearance('icons/turf/overlays.dmi', "snowfloor") + var/static/mutable_appearance/water_overlay = mutable_appearance('icons/effects/water.dmi', "wet_floor_static") + var/static/mutable_appearance/generic_turf_overlay = mutable_appearance('icons/effects/water.dmi', "wet_static") + var/current_overlay + var/permanent = FALSE + var/last_process = 0 + +/datum/component/wet_floor/InheritComponent(datum/newcomp, orig, argslist) + if(!newcomp) //We are getting passed the arguments of a would-be new component, but not a new component + add_wet(arglist(argslist)) + else //We are being passed in a full blown component + var/datum/component/wet_floor/WF = newcomp //Lets make an assumption + if(WF.gc()) //See if it's even valid, still. Also does LAZYLEN and stuff for us. + CRASH("Wet floor component tried to inherit another, but the other was able to garbage collect while being inherited! What a waste of time!") + return + for(var/i in WF.time_left_list) + add_wet(text2num(i), WF.time_left_list[i]) + +/datum/component/wet_floor/Initialize(strength, duration_minimum, duration_add, duration_maximum, _permanent = FALSE) + if(!isopenturf(parent)) + return COMPONENT_INCOMPATIBLE + add_wet(strength, duration_minimum, duration_add, duration_maximum) + permanent = _permanent + if(!permanent) + START_PROCESSING(SSwet_floors, src) + addtimer(CALLBACK(src, .proc/gc, TRUE), 1) //GC after initialization. + last_process = world.time + +/datum/component/wet_floor/RegisterWithParent() + . = ..() + RegisterSignal(parent, COMSIG_TURF_IS_WET, .proc/is_wet) + RegisterSignal(parent, COMSIG_TURF_MAKE_DRY, .proc/dry) + +/datum/component/wet_floor/UnregisterFromParent() + . = ..() + UnregisterSignal(parent, list(COMSIG_TURF_IS_WET, COMSIG_TURF_MAKE_DRY)) + +/datum/component/wet_floor/Destroy() + STOP_PROCESSING(SSwet_floors, src) + var/turf/T = parent + qdel(T.GetComponent(/datum/component/slippery)) + if(istype(T)) //If this is false there is so many things wrong with it. + T.cut_overlay(current_overlay) + else + stack_trace("Warning: Wet floor component wasn't on a turf when being destroyed! This is really bad!") + return ..() + +/datum/component/wet_floor/proc/update_overlay() + var/intended + if(!istype(parent, /turf/open/floor)) + intended = generic_turf_overlay + else + switch(highest_strength) + if(TURF_WET_PERMAFROST) + intended = permafrost_overlay + if(TURF_WET_ICE) + intended = ice_overlay + else + intended = water_overlay + if(current_overlay != intended) + var/turf/T = parent + T.cut_overlay(current_overlay) + T.add_overlay(intended) + current_overlay = intended + +/datum/component/wet_floor/proc/AfterSlip(mob/living/L) + if(highest_strength == TURF_WET_LUBE) + L.confused = max(L.confused, 8) + +/datum/component/wet_floor/proc/update_flags() + var/intensity + lube_flags = NONE + switch(highest_strength) + if(TURF_WET_WATER) + intensity = 60 + lube_flags = NO_SLIP_WHEN_WALKING + if(TURF_WET_LUBE) + intensity = 80 + lube_flags = SLIDE | GALOSHES_DONT_HELP + if(TURF_WET_ICE) + intensity = 120 + lube_flags = SLIDE | GALOSHES_DONT_HELP + if(TURF_WET_PERMAFROST) + intensity = 120 + lube_flags = SLIDE_ICE | GALOSHES_DONT_HELP + if(TURF_WET_SUPERLUBE) + intensity = 120 + lube_flags = SLIDE | GALOSHES_DONT_HELP | SLIP_WHEN_CRAWLING + else + qdel(parent.GetComponent(/datum/component/slippery)) + return + + var/datum/component/slippery/S = parent.LoadComponent(/datum/component/slippery, NONE, CALLBACK(src, .proc/AfterSlip)) + S.intensity = intensity + S.lube_flags = lube_flags + +/datum/component/wet_floor/proc/dry(datum/source, strength = TURF_WET_WATER, immediate = FALSE, duration_decrease = INFINITY) + for(var/i in time_left_list) + if(text2num(i) <= strength) + time_left_list[i] = max(0, time_left_list[i] - duration_decrease) + if(immediate) + check() + +/datum/component/wet_floor/proc/max_time_left() + . = 0 + for(var/i in time_left_list) + . = max(., time_left_list[i]) + +/datum/component/wet_floor/process() + var/turf/open/T = parent + var/diff = world.time - last_process + var/decrease = 0 + var/t = T.GetTemperature() + switch(t) + if(-INFINITY to T0C) + add_wet(TURF_WET_ICE, max_time_left()) //Water freezes into ice! + if(T0C to T0C + 100) + decrease = ((T.air.temperature - T0C) / SSwet_floors.temperature_coeff) * (diff / SSwet_floors.time_ratio) + if(T0C + 100 to INFINITY) + decrease = INFINITY + decrease = max(0, decrease) + if((is_wet() & TURF_WET_ICE) && t > T0C) //Ice melts into water! + for(var/obj/O in T.contents) + if(O.obj_flags & FROZEN) + O.make_unfrozen() + add_wet(TURF_WET_WATER, max_time_left()) + dry(null, TURF_WET_ICE) + dry(null, ALL, FALSE, decrease) + check() + last_process = world.time + +/datum/component/wet_floor/proc/update_strength() + highest_strength = 0 //Not bitflag. + for(var/i in time_left_list) + highest_strength = max(highest_strength, text2num(i)) + +/datum/component/wet_floor/proc/is_wet() + . = 0 + for(var/i in time_left_list) + . |= text2num(i) + +/datum/component/wet_floor/PreTransfer() + var/turf/O = parent + O.cut_overlay(current_overlay) + //That turf is no longer slippery, we're out of here + //Slippery components don't transfer due to callbacks + qdel(O.GetComponent(/datum/component/slippery)) + +/datum/component/wet_floor/PostTransfer() + if(!isopenturf(parent)) + return COMPONENT_INCOMPATIBLE + var/turf/T = parent + T.add_overlay(current_overlay) + //Make sure to add/update any slippery component on the new turf (update_flags calls LoadComponent) + update_flags() + + //NB it's possible we get deleted after this, due to inherit + +/datum/component/wet_floor/proc/add_wet(type, duration_minimum = 0, duration_add = 0, duration_maximum = MAXIMUM_WET_TIME, _permanent = FALSE) + var/static/list/allowed_types = list(TURF_WET_WATER, TURF_WET_LUBE, TURF_WET_ICE, TURF_WET_PERMAFROST, TURF_WET_SUPERLUBE) + if(duration_minimum <= 0 || !type) + return FALSE + if(type in allowed_types) + return _do_add_wet(type, duration_minimum, duration_add, duration_maximum) + else + . = NONE + for(var/i in allowed_types) + if(!(type & i)) + continue + . |= _do_add_wet(i, duration_minimum, duration_add, duration_maximum) + if(_permanent) + permanent = TRUE + STOP_PROCESSING(SSwet_floors, src) + +/datum/component/wet_floor/proc/_do_add_wet(type, duration_minimum, duration_add, duration_maximum) + var/time = 0 + if(LAZYACCESS(time_left_list, "[type]")) + time = CLAMP(LAZYACCESS(time_left_list, "[type]") + duration_add, duration_minimum, duration_maximum) + else + time = min(duration_minimum, duration_maximum) + LAZYSET(time_left_list, "[type]", time) + check(TRUE) + return TRUE + +/datum/component/wet_floor/proc/gc(on_init = FALSE) + if(!LAZYLEN(time_left_list)) + if(on_init) + var/turf/T = parent + stack_trace("Warning: Wet floor component gc'd right after initialization! What a waste of time and CPU! Type = [T? T.type : "ERROR - NO PARENT"], Location = [istype(T)? AREACOORD(T) : "ERROR - INVALID PARENT"].") + qdel(src) + return TRUE + return FALSE + +/datum/component/wet_floor/proc/check(force_update = FALSE) + var/changed = FALSE + for(var/i in time_left_list) + if(time_left_list[i] <= 0) + time_left_list -= i + changed = TRUE + if(changed || force_update) + update_strength() + update_overlay() + update_flags() + gc() diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index cf33fa3633..ebfba43852 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -1,296 +1,296 @@ - -/datum/datacore - var/medical[] = list() - var/medicalPrintCount = 0 - var/general[] = list() - var/security[] = list() - var/securityPrintCount = 0 - var/securityCrimeCounter = 0 - //This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character(). - var/locked[] = list() - -/datum/data - var/name = "data" - -/datum/data/record - name = "record" - var/list/fields = list() - -/datum/data/record/Destroy() - if(src in GLOB.data_core.medical) - GLOB.data_core.medical -= src - if(src in GLOB.data_core.security) - GLOB.data_core.security -= src - if(src in GLOB.data_core.general) - GLOB.data_core.general -= src - if(src in GLOB.data_core.locked) - GLOB.data_core.locked -= src - . = ..() - -/datum/data/crime - name = "crime" - var/crimeName = "" - var/crimeDetails = "" - var/author = "" - var/time = "" - var/dataId = 0 - -/datum/datacore/proc/createCrimeEntry(cname = "", cdetails = "", author = "", time = "") - var/datum/data/crime/c = new /datum/data/crime - c.crimeName = cname - c.crimeDetails = cdetails - c.author = author - c.time = time - c.dataId = ++securityCrimeCounter - return c - -/datum/datacore/proc/addMinorCrime(id = "", datum/data/crime/crime) - for(var/datum/data/record/R in security) - if(R.fields["id"] == id) - var/list/crimes = R.fields["mi_crim"] - crimes |= crime - return - -/datum/datacore/proc/removeMinorCrime(id, cDataId) - for(var/datum/data/record/R in security) - if(R.fields["id"] == id) - var/list/crimes = R.fields["mi_crim"] - for(var/datum/data/crime/crime in crimes) - if(crime.dataId == text2num(cDataId)) - crimes -= crime - return - -/datum/datacore/proc/removeMajorCrime(id, cDataId) - for(var/datum/data/record/R in security) - if(R.fields["id"] == id) - var/list/crimes = R.fields["ma_crim"] - for(var/datum/data/crime/crime in crimes) - if(crime.dataId == text2num(cDataId)) - crimes -= crime - return - -/datum/datacore/proc/addMajorCrime(id = "", datum/data/crime/crime) - for(var/datum/data/record/R in security) - if(R.fields["id"] == id) - var/list/crimes = R.fields["ma_crim"] - crimes |= crime - return - -/datum/datacore/proc/manifest() - for(var/mob/dead/new_player/N in GLOB.player_list) - if(N.new_character) - log_manifest(N.ckey,N.new_character.mind,N.new_character) - if(ishuman(N.new_character)) - manifest_inject(N.new_character, N.client) - CHECK_TICK - -/datum/datacore/proc/manifest_modify(name, assignment) - var/datum/data/record/foundrecord = find_record("name", name, GLOB.data_core.general) - if(foundrecord) - foundrecord.fields["rank"] = assignment - -/datum/datacore/proc/get_manifest(monochrome, OOC) - var/list/heads = list() - var/list/sec = list() - var/list/eng = list() - var/list/med = list() - var/list/sci = list() - var/list/sup = list() - var/list/civ = list() - var/list/bot = list() - var/list/misc = list() - var/dat = {" - - - - "} - var/even = 0 - // sort mobs - for(var/datum/data/record/t in GLOB.data_core.general) - var/name = t.fields["name"] - var/rank = t.fields["rank"] - var/department = 0 - if(rank in GLOB.command_positions) - heads[name] = rank - department = 1 - if(rank in GLOB.security_positions) - sec[name] = rank - department = 1 - if(rank in GLOB.engineering_positions) - eng[name] = rank - department = 1 - if(rank in GLOB.medical_positions) - med[name] = rank - department = 1 - if(rank in GLOB.science_positions) - sci[name] = rank - department = 1 - if(rank in GLOB.supply_positions) - sup[name] = rank - department = 1 - if(rank in GLOB.civilian_positions) - civ[name] = rank - department = 1 - if(rank in GLOB.nonhuman_positions) - bot[name] = rank - department = 1 - if(!department && !(name in heads)) - misc[name] = rank - if(heads.len > 0) - dat += "" - for(var/name in heads) - dat += "" - even = !even - if(sec.len > 0) - dat += "" - for(var/name in sec) - dat += "" - even = !even - if(eng.len > 0) - dat += "" - for(var/name in eng) - dat += "" - even = !even - if(med.len > 0) - dat += "" - for(var/name in med) - dat += "" - even = !even - if(sci.len > 0) - dat += "" - for(var/name in sci) - dat += "" - even = !even - if(sup.len > 0) - dat += "" - for(var/name in sup) - dat += "" - even = !even - if(civ.len > 0) - dat += "" - for(var/name in civ) - dat += "" - even = !even - // in case somebody is insane and added them to the manifest, why not - if(bot.len > 0) - dat += "" - for(var/name in bot) - dat += "" - even = !even - // misc guys - if(misc.len > 0) - dat += "" - for(var/name in misc) - dat += "" - even = !even - - dat += "
      NameRank
      Heads
      [name][heads[name]]
      Security
      [name][sec[name]]
      Engineering
      [name][eng[name]]
      Medical
      [name][med[name]]
      Science
      [name][sci[name]]
      Supply
      [name][sup[name]]
      Civilian
      [name][civ[name]]
      Silicon
      [name][bot[name]]
      Miscellaneous
      [name][misc[name]]
      " - dat = replacetext(dat, "\n", "") - dat = replacetext(dat, "\t", "") - return dat - - -/datum/datacore/proc/manifest_inject(mob/living/carbon/human/H, client/C) - set waitfor = FALSE - var/static/list/show_directions = list(SOUTH, WEST) - if(H.mind && (H.mind.assigned_role != H.mind.special_role)) - var/assignment - if(H.mind.assigned_role) - assignment = H.mind.assigned_role - else if(H.job) - assignment = H.job - else - assignment = "Unassigned" - - var/static/record_id_num = 1001 - var/id = num2hex(record_id_num++,6) - if(!C) - C = H.client - var/image = get_id_photo(H, C, show_directions) - var/datum/picture/pf = new - var/datum/picture/ps = new - pf.picture_name = "[H]" - ps.picture_name = "[H]" - pf.picture_desc = "This is [H]." - ps.picture_desc = "This is [H]." - pf.picture_image = icon(image, dir = SOUTH) - ps.picture_image = icon(image, dir = WEST) - var/obj/item/photo/photo_front = new(null, pf) - var/obj/item/photo/photo_side = new(null, ps) - - //These records should ~really~ be merged or something - //General Record - var/datum/data/record/G = new() - G.fields["id"] = id - G.fields["name"] = H.real_name - G.fields["rank"] = assignment - G.fields["age"] = H.age - G.fields["species"] = H.dna.species.name - G.fields["fingerprint"] = md5(H.dna.uni_identity) - G.fields["p_stat"] = "Active" - G.fields["m_stat"] = "Stable" - G.fields["sex"] = H.gender - G.fields["photo_front"] = photo_front - G.fields["photo_side"] = photo_side - general += G - - //Medical Record - var/datum/data/record/M = new() - M.fields["id"] = id - M.fields["name"] = H.real_name - M.fields["blood_type"] = H.dna.blood_type - M.fields["b_dna"] = H.dna.unique_enzymes - M.fields["mi_dis"] = "None" - M.fields["mi_dis_d"] = "No minor disabilities have been declared." - M.fields["ma_dis"] = "None" - M.fields["ma_dis_d"] = "No major disabilities have been diagnosed." - M.fields["alg"] = "None" - M.fields["alg_d"] = "No allergies have been detected in this patient." - M.fields["cdi"] = "None" - M.fields["cdi_d"] = "No diseases have been diagnosed at the moment." - M.fields["notes"] = H.get_trait_string(medical) - medical += M - - //Security Record - var/datum/data/record/S = new() - S.fields["id"] = id - S.fields["name"] = H.real_name - S.fields["criminal"] = "None" - S.fields["mi_crim"] = list() - S.fields["ma_crim"] = list() - S.fields["notes"] = "No notes." - security += S - - //Locked Record - var/datum/data/record/L = new() - L.fields["id"] = md5("[H.real_name][H.mind.assigned_role]") //surely this should just be id, like the others? - L.fields["name"] = H.real_name - L.fields["rank"] = H.mind.assigned_role - L.fields["age"] = H.age - L.fields["sex"] = H.gender - L.fields["blood_type"] = H.dna.blood_type - L.fields["b_dna"] = H.dna.unique_enzymes - L.fields["enzymes"] = H.dna.struc_enzymes - L.fields["identity"] = H.dna.uni_identity - L.fields["species"] = H.dna.species.type - L.fields["features"] = H.dna.features - L.fields["image"] = image - L.fields["mindref"] = H.mind - locked += L - return - -/datum/datacore/proc/get_id_photo(mob/living/carbon/human/H, client/C, show_directions = list(SOUTH)) - var/datum/job/J = SSjob.GetJob(H.mind.assigned_role) - var/datum/preferences/P - if(!C) - C = H.client - if(C) - P = C.prefs - return get_flat_human_icon(null, J, P, DUMMY_HUMAN_SLOT_MANIFEST, show_directions) + +/datum/datacore + var/medical[] = list() + var/medicalPrintCount = 0 + var/general[] = list() + var/security[] = list() + var/securityPrintCount = 0 + var/securityCrimeCounter = 0 + //This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character(). + var/locked[] = list() + +/datum/data + var/name = "data" + +/datum/data/record + name = "record" + var/list/fields = list() + +/datum/data/record/Destroy() + if(src in GLOB.data_core.medical) + GLOB.data_core.medical -= src + if(src in GLOB.data_core.security) + GLOB.data_core.security -= src + if(src in GLOB.data_core.general) + GLOB.data_core.general -= src + if(src in GLOB.data_core.locked) + GLOB.data_core.locked -= src + . = ..() + +/datum/data/crime + name = "crime" + var/crimeName = "" + var/crimeDetails = "" + var/author = "" + var/time = "" + var/dataId = 0 + +/datum/datacore/proc/createCrimeEntry(cname = "", cdetails = "", author = "", time = "") + var/datum/data/crime/c = new /datum/data/crime + c.crimeName = cname + c.crimeDetails = cdetails + c.author = author + c.time = time + c.dataId = ++securityCrimeCounter + return c + +/datum/datacore/proc/addMinorCrime(id = "", datum/data/crime/crime) + for(var/datum/data/record/R in security) + if(R.fields["id"] == id) + var/list/crimes = R.fields["mi_crim"] + crimes |= crime + return + +/datum/datacore/proc/removeMinorCrime(id, cDataId) + for(var/datum/data/record/R in security) + if(R.fields["id"] == id) + var/list/crimes = R.fields["mi_crim"] + for(var/datum/data/crime/crime in crimes) + if(crime.dataId == text2num(cDataId)) + crimes -= crime + return + +/datum/datacore/proc/removeMajorCrime(id, cDataId) + for(var/datum/data/record/R in security) + if(R.fields["id"] == id) + var/list/crimes = R.fields["ma_crim"] + for(var/datum/data/crime/crime in crimes) + if(crime.dataId == text2num(cDataId)) + crimes -= crime + return + +/datum/datacore/proc/addMajorCrime(id = "", datum/data/crime/crime) + for(var/datum/data/record/R in security) + if(R.fields["id"] == id) + var/list/crimes = R.fields["ma_crim"] + crimes |= crime + return + +/datum/datacore/proc/manifest() + for(var/mob/dead/new_player/N in GLOB.player_list) + if(N.new_character) + log_manifest(N.ckey,N.new_character.mind,N.new_character) + if(ishuman(N.new_character)) + manifest_inject(N.new_character, N.client) + CHECK_TICK + +/datum/datacore/proc/manifest_modify(name, assignment) + var/datum/data/record/foundrecord = find_record("name", name, GLOB.data_core.general) + if(foundrecord) + foundrecord.fields["rank"] = assignment + +/datum/datacore/proc/get_manifest(monochrome, OOC) + var/list/heads = list() + var/list/sec = list() + var/list/eng = list() + var/list/med = list() + var/list/sci = list() + var/list/sup = list() + var/list/civ = list() + var/list/bot = list() + var/list/misc = list() + var/dat = {" + + + + "} + var/even = 0 + // sort mobs + for(var/datum/data/record/t in GLOB.data_core.general) + var/name = t.fields["name"] + var/rank = t.fields["rank"] + var/department = 0 + if(rank in GLOB.command_positions) + heads[name] = rank + department = 1 + if(rank in GLOB.security_positions) + sec[name] = rank + department = 1 + if(rank in GLOB.engineering_positions) + eng[name] = rank + department = 1 + if(rank in GLOB.medical_positions) + med[name] = rank + department = 1 + if(rank in GLOB.science_positions) + sci[name] = rank + department = 1 + if(rank in GLOB.supply_positions) + sup[name] = rank + department = 1 + if(rank in GLOB.civilian_positions) + civ[name] = rank + department = 1 + if(rank in GLOB.nonhuman_positions) + bot[name] = rank + department = 1 + if(!department && !(name in heads)) + misc[name] = rank + if(heads.len > 0) + dat += "" + for(var/name in heads) + dat += "" + even = !even + if(sec.len > 0) + dat += "" + for(var/name in sec) + dat += "" + even = !even + if(eng.len > 0) + dat += "" + for(var/name in eng) + dat += "" + even = !even + if(med.len > 0) + dat += "" + for(var/name in med) + dat += "" + even = !even + if(sci.len > 0) + dat += "" + for(var/name in sci) + dat += "" + even = !even + if(sup.len > 0) + dat += "" + for(var/name in sup) + dat += "" + even = !even + if(civ.len > 0) + dat += "" + for(var/name in civ) + dat += "" + even = !even + // in case somebody is insane and added them to the manifest, why not + if(bot.len > 0) + dat += "" + for(var/name in bot) + dat += "" + even = !even + // misc guys + if(misc.len > 0) + dat += "" + for(var/name in misc) + dat += "" + even = !even + + dat += "
      NameRank
      Heads
      [name][heads[name]]
      Security
      [name][sec[name]]
      Engineering
      [name][eng[name]]
      Medical
      [name][med[name]]
      Science
      [name][sci[name]]
      Supply
      [name][sup[name]]
      Civilian
      [name][civ[name]]
      Silicon
      [name][bot[name]]
      Miscellaneous
      [name][misc[name]]
      " + dat = replacetext(dat, "\n", "") + dat = replacetext(dat, "\t", "") + return dat + + +/datum/datacore/proc/manifest_inject(mob/living/carbon/human/H, client/C) + set waitfor = FALSE + var/static/list/show_directions = list(SOUTH, WEST) + if(H.mind && (H.mind.assigned_role != H.mind.special_role)) + var/assignment + if(H.mind.assigned_role) + assignment = H.mind.assigned_role + else if(H.job) + assignment = H.job + else + assignment = "Unassigned" + + var/static/record_id_num = 1001 + var/id = num2hex(record_id_num++,6) + if(!C) + C = H.client + var/image = get_id_photo(H, C, show_directions) + var/datum/picture/pf = new + var/datum/picture/ps = new + pf.picture_name = "[H]" + ps.picture_name = "[H]" + pf.picture_desc = "This is [H]." + ps.picture_desc = "This is [H]." + pf.picture_image = icon(image, dir = SOUTH) + ps.picture_image = icon(image, dir = WEST) + var/obj/item/photo/photo_front = new(null, pf) + var/obj/item/photo/photo_side = new(null, ps) + + //These records should ~really~ be merged or something + //General Record + var/datum/data/record/G = new() + G.fields["id"] = id + G.fields["name"] = H.real_name + G.fields["rank"] = assignment + G.fields["age"] = H.age + G.fields["species"] = H.dna.species.name + G.fields["fingerprint"] = md5(H.dna.uni_identity) + G.fields["p_stat"] = "Active" + G.fields["m_stat"] = "Stable" + G.fields["sex"] = H.gender + G.fields["photo_front"] = photo_front + G.fields["photo_side"] = photo_side + general += G + + //Medical Record + var/datum/data/record/M = new() + M.fields["id"] = id + M.fields["name"] = H.real_name + M.fields["blood_type"] = H.dna.blood_type + M.fields["b_dna"] = H.dna.unique_enzymes + M.fields["mi_dis"] = "None" + M.fields["mi_dis_d"] = "No minor disabilities have been declared." + M.fields["ma_dis"] = "None" + M.fields["ma_dis_d"] = "No major disabilities have been diagnosed." + M.fields["alg"] = "None" + M.fields["alg_d"] = "No allergies have been detected in this patient." + M.fields["cdi"] = "None" + M.fields["cdi_d"] = "No diseases have been diagnosed at the moment." + M.fields["notes"] = H.get_trait_string(medical) + medical += M + + //Security Record + var/datum/data/record/S = new() + S.fields["id"] = id + S.fields["name"] = H.real_name + S.fields["criminal"] = "None" + S.fields["mi_crim"] = list() + S.fields["ma_crim"] = list() + S.fields["notes"] = "No notes." + security += S + + //Locked Record + var/datum/data/record/L = new() + L.fields["id"] = md5("[H.real_name][H.mind.assigned_role]") //surely this should just be id, like the others? + L.fields["name"] = H.real_name + L.fields["rank"] = H.mind.assigned_role + L.fields["age"] = H.age + L.fields["sex"] = H.gender + L.fields["blood_type"] = H.dna.blood_type + L.fields["b_dna"] = H.dna.unique_enzymes + L.fields["enzymes"] = H.dna.struc_enzymes + L.fields["identity"] = H.dna.uni_identity + L.fields["species"] = H.dna.species.type + L.fields["features"] = H.dna.features + L.fields["image"] = image + L.fields["mindref"] = H.mind + locked += L + return + +/datum/datacore/proc/get_id_photo(mob/living/carbon/human/H, client/C, show_directions = list(SOUTH)) + var/datum/job/J = SSjob.GetJob(H.mind.assigned_role) + var/datum/preferences/P + if(!C) + C = H.client + if(C) + P = C.prefs + return get_flat_human_icon(null, J, P, DUMMY_HUMAN_SLOT_MANIFEST, show_directions) diff --git a/code/datums/datum.dm b/code/datums/datum.dm index 8737cd8feb..34e4e7ac14 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -1,160 +1,160 @@ -/datum - var/gc_destroyed //Time when this object was destroyed. - var/list/active_timers //for SStimer - var/list/datum_components //for /datum/components - var/list/status_traits - var/list/comp_lookup //it used to be for looking up components which had registered a signal but now anything can register - var/list/list/datum/callback/signal_procs - var/signal_enabled = FALSE - var/datum_flags = NONE - var/datum/weakref/weak_reference - -#ifdef TESTING - var/running_find_references - var/last_find_references = 0 -#endif - -#ifdef DATUMVAR_DEBUGGING_MODE - var/list/cached_vars -#endif - -// Default implementation of clean-up code. -// This should be overridden to remove all references pointing to the object being destroyed. -// Return the appropriate QDEL_HINT; in most cases this is QDEL_HINT_QUEUE. -/datum/proc/Destroy(force=FALSE, ...) - tag = null - datum_flags &= ~DF_USE_TAG //In case something tries to REF us - weak_reference = null //ensure prompt GCing of weakref. - - var/list/timers = active_timers - active_timers = null - for(var/thing in timers) - var/datum/timedevent/timer = thing - if (timer.spent) - continue - qdel(timer) - - //BEGIN: ECS SHIT - signal_enabled = FALSE - - var/list/dc = datum_components - if(dc) - var/all_components = dc[/datum/component] - if(length(all_components)) - for(var/I in all_components) - var/datum/component/C = I - qdel(C, FALSE, TRUE) - else - var/datum/component/C = all_components - qdel(C, FALSE, TRUE) - dc.Cut() - - var/list/lookup = comp_lookup - if(lookup) - for(var/sig in lookup) - var/list/comps = lookup[sig] - if(length(comps)) - for(var/i in comps) - var/datum/component/comp = i - comp.UnregisterSignal(src, sig) - else - var/datum/component/comp = comps - comp.UnregisterSignal(src, sig) - comp_lookup = lookup = null - - for(var/target in signal_procs) - UnregisterSignal(target, signal_procs[target]) - //END: ECS SHIT - - return QDEL_HINT_QUEUE - -#ifdef DATUMVAR_DEBUGGING_MODE -/datum/proc/save_vars() - cached_vars = list() - for(var/i in vars) - if(i == "cached_vars") - continue - cached_vars[i] = vars[i] - -/datum/proc/check_changed_vars() - . = list() - for(var/i in vars) - if(i == "cached_vars") - continue - if(cached_vars[i] != vars[i]) - .[i] = list(cached_vars[i], vars[i]) - -/datum/proc/txt_changed_vars() - var/list/l = check_changed_vars() - var/t = "[src]([REF(src)]) changed vars:" - for(var/i in l) - t += "\"[i]\" \[[l[i][1]]\] --> \[[l[i][2]]\] " - t += "." - -/datum/proc/to_chat_check_changed_vars(target = world) - to_chat(target, txt_changed_vars()) -#endif - -//Return a LIST for serialize_datum to encode! Not the actual json! -/datum/proc/serialize_list(list/options) - CRASH("Attempted to serialize datum [src] of type [type] without serialize_list being implemented!") - -//Accepts a LIST from deserialize_datum. Should return src or another datum. -/datum/proc/deserialize_list(json, list/options) - CRASH("Attempted to deserialize datum [src] of type [type] without deserialize_list being implemented!") - -//Serializes into JSON. Does not encode type. -/datum/proc/serialize_json(list/options) - . = serialize_list(options) - if(!islist(.)) - . = null - else - . = json_encode(.) - -//Deserializes from JSON. Does not parse type. -/datum/proc/deserialize_json(list/input, list/options) - var/list/jsonlist = json_decode(input) - . = deserialize_list(jsonlist) - if(!istype(., /datum)) - . = null - -/proc/json_serialize_datum(datum/D, list/options) - if(!istype(D)) - return - var/list/jsonlist = D.serialize_list(options) - if(islist(jsonlist)) - jsonlist["DATUM_TYPE"] = D.type - return json_encode(jsonlist) - -/proc/json_deserialize_datum(list/jsonlist, list/options, target_type, strict_target_type = FALSE) - if(!islist(jsonlist)) - if(!istext(jsonlist)) - CRASH("Invalid JSON") - return - jsonlist = json_decode(jsonlist) - if(!islist(jsonlist)) - CRASH("Invalid JSON") - return - if(!jsonlist["DATUM_TYPE"]) - return - if(!ispath(jsonlist["DATUM_TYPE"])) - if(!istext(jsonlist["DATUM_TYPE"])) - return - jsonlist["DATUM_TYPE"] = text2path(jsonlist["DATUM_TYPE"]) - if(!ispath(jsonlist["DATUM_TYPE"])) - return - if(target_type) - if(!ispath(target_type)) - return - if(strict_target_type) - if(target_type != jsonlist["DATUM_TYPE"]) - return - else if(!ispath(jsonlist["DATUM_TYPE"], target_type)) - return - var/typeofdatum = jsonlist["DATUM_TYPE"] //BYOND won't directly read if this is just put in the line below, and will instead runtime because it thinks you're trying to make a new list? - var/datum/D = new typeofdatum - var/datum/returned = D.deserialize_list(jsonlist, options) - if(!istype(returned, /datum)) - qdel(D) - else - return returned +/datum + var/gc_destroyed //Time when this object was destroyed. + var/list/active_timers //for SStimer + var/list/datum_components //for /datum/components + var/list/status_traits + var/list/comp_lookup //it used to be for looking up components which had registered a signal but now anything can register + var/list/list/datum/callback/signal_procs + var/signal_enabled = FALSE + var/datum_flags = NONE + var/datum/weakref/weak_reference + +#ifdef TESTING + var/running_find_references + var/last_find_references = 0 +#endif + +#ifdef DATUMVAR_DEBUGGING_MODE + var/list/cached_vars +#endif + +// Default implementation of clean-up code. +// This should be overridden to remove all references pointing to the object being destroyed. +// Return the appropriate QDEL_HINT; in most cases this is QDEL_HINT_QUEUE. +/datum/proc/Destroy(force=FALSE, ...) + tag = null + datum_flags &= ~DF_USE_TAG //In case something tries to REF us + weak_reference = null //ensure prompt GCing of weakref. + + var/list/timers = active_timers + active_timers = null + for(var/thing in timers) + var/datum/timedevent/timer = thing + if (timer.spent) + continue + qdel(timer) + + //BEGIN: ECS SHIT + signal_enabled = FALSE + + var/list/dc = datum_components + if(dc) + var/all_components = dc[/datum/component] + if(length(all_components)) + for(var/I in all_components) + var/datum/component/C = I + qdel(C, FALSE, TRUE) + else + var/datum/component/C = all_components + qdel(C, FALSE, TRUE) + dc.Cut() + + var/list/lookup = comp_lookup + if(lookup) + for(var/sig in lookup) + var/list/comps = lookup[sig] + if(length(comps)) + for(var/i in comps) + var/datum/component/comp = i + comp.UnregisterSignal(src, sig) + else + var/datum/component/comp = comps + comp.UnregisterSignal(src, sig) + comp_lookup = lookup = null + + for(var/target in signal_procs) + UnregisterSignal(target, signal_procs[target]) + //END: ECS SHIT + + return QDEL_HINT_QUEUE + +#ifdef DATUMVAR_DEBUGGING_MODE +/datum/proc/save_vars() + cached_vars = list() + for(var/i in vars) + if(i == "cached_vars") + continue + cached_vars[i] = vars[i] + +/datum/proc/check_changed_vars() + . = list() + for(var/i in vars) + if(i == "cached_vars") + continue + if(cached_vars[i] != vars[i]) + .[i] = list(cached_vars[i], vars[i]) + +/datum/proc/txt_changed_vars() + var/list/l = check_changed_vars() + var/t = "[src]([REF(src)]) changed vars:" + for(var/i in l) + t += "\"[i]\" \[[l[i][1]]\] --> \[[l[i][2]]\] " + t += "." + +/datum/proc/to_chat_check_changed_vars(target = world) + to_chat(target, txt_changed_vars()) +#endif + +//Return a LIST for serialize_datum to encode! Not the actual json! +/datum/proc/serialize_list(list/options) + CRASH("Attempted to serialize datum [src] of type [type] without serialize_list being implemented!") + +//Accepts a LIST from deserialize_datum. Should return src or another datum. +/datum/proc/deserialize_list(json, list/options) + CRASH("Attempted to deserialize datum [src] of type [type] without deserialize_list being implemented!") + +//Serializes into JSON. Does not encode type. +/datum/proc/serialize_json(list/options) + . = serialize_list(options) + if(!islist(.)) + . = null + else + . = json_encode(.) + +//Deserializes from JSON. Does not parse type. +/datum/proc/deserialize_json(list/input, list/options) + var/list/jsonlist = json_decode(input) + . = deserialize_list(jsonlist) + if(!istype(., /datum)) + . = null + +/proc/json_serialize_datum(datum/D, list/options) + if(!istype(D)) + return + var/list/jsonlist = D.serialize_list(options) + if(islist(jsonlist)) + jsonlist["DATUM_TYPE"] = D.type + return json_encode(jsonlist) + +/proc/json_deserialize_datum(list/jsonlist, list/options, target_type, strict_target_type = FALSE) + if(!islist(jsonlist)) + if(!istext(jsonlist)) + CRASH("Invalid JSON") + return + jsonlist = json_decode(jsonlist) + if(!islist(jsonlist)) + CRASH("Invalid JSON") + return + if(!jsonlist["DATUM_TYPE"]) + return + if(!ispath(jsonlist["DATUM_TYPE"])) + if(!istext(jsonlist["DATUM_TYPE"])) + return + jsonlist["DATUM_TYPE"] = text2path(jsonlist["DATUM_TYPE"]) + if(!ispath(jsonlist["DATUM_TYPE"])) + return + if(target_type) + if(!ispath(target_type)) + return + if(strict_target_type) + if(target_type != jsonlist["DATUM_TYPE"]) + return + else if(!ispath(jsonlist["DATUM_TYPE"], target_type)) + return + var/typeofdatum = jsonlist["DATUM_TYPE"] //BYOND won't directly read if this is just put in the line below, and will instead runtime because it thinks you're trying to make a new list? + var/datum/D = new typeofdatum + var/datum/returned = D.deserialize_list(jsonlist, options) + if(!istype(returned, /datum)) + qdel(D) + else + return returned diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index dfaa6f061d..5caa491e4c 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -1,1430 +1,1430 @@ -#define VV_MSG_MARKED "
      Marked Object" -#define VV_MSG_EDITED "
      Var Edited" -#define VV_MSG_DELETED "
      Deleted" - -/datum/proc/CanProcCall(procname) - return TRUE - -/datum/proc/can_vv_get(var_name) - return TRUE - -/datum/proc/vv_edit_var(var_name, var_value) //called whenever a var is edited - if(var_name == NAMEOF(src, vars)) - return FALSE - vars[var_name] = var_value - datum_flags |= DF_VAR_EDITED - return TRUE - -/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 . += "---" -/datum/proc/vv_get_dropdown() - . = list() - . += "---" - .["Call Proc"] = "?_src_=vars;[HrefToken()];proc_call=[REF(src)]" - .["Mark Object"] = "?_src_=vars;[HrefToken()];mark_object=[REF(src)]" - .["Delete"] = "?_src_=vars;[HrefToken()];delete=[REF(src)]" - .["Show VV To Player"] = "?_src_=vars;[HrefToken(TRUE)];expose=[REF(src)]" - - -/datum/proc/on_reagent_change(changetype) - 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) //The usr vs src abuse in this proc is intentional and must not be changed - 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) - src << browse_rsc(sprite, "vv[hash].png") - - title = "[D] ([REF(D)]) = [type]" - var/formatted_type = replacetext("[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]" - atomsnowflake += "
      << [dir2text(A.dir) || A.dir] >>" - var/mob/living/M = A - atomsnowflake += {" -
      [M.ckey || "No ckey"] / [M.real_name || "No real name"] -
      - BRUTE:[M.getBruteLoss()] - FIRE:[M.getFireLoss()] - TOXIN:[M.getToxLoss()] - OXY:[M.getOxyLoss()] - CLONE:[M.getCloneLoss()] - BRAIN:[M.getOrganLoss(ORGAN_SLOT_BRAIN)] - STAMINA:[M.getStaminaLoss()] - AROUSAL:[M.getArousalLoss()] - "} - if(GLOB.Debug2) - atomsnowflake += {" - HEART:[M.getOrganLoss(ORGAN_SLOT_HEART)] - LIVER:[M.getOrganLoss(ORGAN_SLOT_LIVER)] - LUNGS:[M.getOrganLoss(ORGAN_SLOT_LUNGS)] - EYES:[M.getOrganLoss(ORGAN_SLOT_EYES)] - EARS:[M.getOrganLoss(ORGAN_SLOT_EARS)] - STOMACH:[M.getOrganLoss(ORGAN_SLOT_STOMACH)] - TONGUE:[M.getOrganLoss(ORGAN_SLOT_TONGUE)] - APPENDIX:[M.getOrganLoss(ORGAN_SLOT_APPENDIX)] - "} - atomsnowflake += {" - - "} - else - atomsnowflake += "[D]" - atomsnowflake += "
      << [dir2text(A.dir) || A.dir] >>" - else if("name" in D.vars) - atomsnowflake += "[D]" - else - atomsnowflake += "[formatted_type]" - formatted_type = null - - var/marked - if(holder && holder.marked_datum && holder.marked_datum == D) - marked = VV_MSG_MARKED - var/varedited_line = "" - if(!islist && (D.datum_flags & DF_VAR_EDITED)) - varedited_line = VV_MSG_EDITED - var/deleted_line - if(!islist && D.gc_destroyed) - deleted_line = VV_MSG_DELETED - - var/list/dropdownoptions = list() - if (islist) - dropdownoptions = list( - "---", - "Add Item" = "?_src_=vars;[HrefToken()];listadd=[refid]", - "Remove Nulls" = "?_src_=vars;[HrefToken()];listnulls=[refid]", - "Remove Dupes" = "?_src_=vars;[HrefToken()];listdupes=[refid]", - "Set len" = "?_src_=vars;[HrefToken()];listlen=[refid]", - "Shuffle" = "?_src_=vars;[HrefToken()];listshuffle=[refid]", - "Show VV To Player" = "?_src_=vars;[HrefToken()];expose=[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] - [deleted_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()] -
      - - - -"} - src << browse(html, "window=variables[refid];size=475x650") - - -/client/proc/vv_update_display(datum/D, span, content) - src << output("[span]:[content]", "variables[REF(D)].browser:replace_span") - - -#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 = "
    22. (E) (C) (-) " - else - header = "
    23. (E) (C) (M) " - else - header = "
    24. " - - 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 (isfile(value)) - item = "[VV_HTML_ENCODE(name)] = '[value]'" - - 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 (isnull(val)) // we still want to display non-null false values, such as 0 or "" - 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 if (name in GLOB.bitfields) - var/list/flags = list() - for (var/i in GLOB.bitfields[name]) - if (value & GLOB.bitfields[name][i]) - flags += i - item = "[VV_HTML_ENCODE(name)] = [VV_HTML_ENCODE(jointext(flags, ", "))]" - else - item = "[VV_HTML_ENCODE(name)] = [VV_HTML_ENCODE(value)]" - - return "[header][item]
    25. " - -#undef VV_HTML_ENCODE - -/client/proc/view_var_Topic(href, href_list, hsrc) - if( (usr.client != src) || !src.holder || !holder.CheckAdminHref(href, href_list)) - 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(NONE)) - return - - 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) - - 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) - - else if(href_list["mark_object"]) - if(!check_rights(NONE)) - 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 - - if(holder.marked_datum) - vv_update_display(holder.marked_datum, "marked", "") - holder.marked_datum = D - vv_update_display(D, "marked", VV_MSG_MARKED) - - else if(href_list["proc_call"]) - if(!check_rights(NONE)) - 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(!istype(D)) - to_chat(usr, "Unable to locate item!") - admin_delete(D) - if (isturf(D)) // show the turf that took its place - debug_variables(D) - - else if(href_list["osay"]) - if(!check_rights(R_FUN, 0)) - return - usr.client.object_say(locate(href_list["osay"])) - - else if(href_list["regenerateicons"]) - if(!check_rights(NONE)) - return - - var/mob/M = locate(href_list["regenerateicons"]) in GLOB.mob_list - 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(NONE)) - return - - 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) - vv_update_display(M, "name", new_name) - vv_update_display(M, "real_name", M.real_name || "No real name") - - else if(href_list["varnameedit"] && href_list["datumedit"]) - if(!check_rights(NONE)) - return - - var/datum/D = locate(href_list["datumedit"]) - if(!istype(D, /datum)) - to_chat(usr, "This can only be used on datums") - return - - if (!modify_variables(D, href_list["varnameedit"], 1)) - return - switch(href_list["varnameedit"]) - if("name") - vv_update_display(D, "name", "[D]") - if("dir") - if(isatom(D)) - var/dir = D.vars["dir"] - vv_update_display(D, "dir", dir2text(dir) || dir) - if("ckey") - if(isliving(D)) - vv_update_display(D, "ckey", D.vars["ckey"] || "No ckey") - if("real_name") - if(isliving(D)) - vv_update_display(D, "real_name", D.vars["real_name"] || "No real name") - - else if(href_list["varnamechange"] && href_list["datumchange"]) - if(!check_rights(NONE)) - 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(NONE)) - 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(NONE)) - 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) - - else if(href_list["remove_spell"]) - if(!check_rights(NONE)) - 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) - - else if(href_list["give_disease"]) - if(!check_rights(NONE)) - 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) - - 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 - - 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) - - else if(href_list["drop_everything"]) - if(!check_rights(NONE)) - 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(NONE)) - 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(NONE)) - 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["modarmor"]) - if(!check_rights(NONE)) - return - - var/obj/O = locate(href_list["modarmor"]) - if(!istype(O)) - to_chat(usr, "This can only be used on instances of type /obj") - return - - var/list/pickerlist = list() - var/list/armorlist = O.armor.getList() - - for (var/i in armorlist) - pickerlist += list(list("value" = armorlist[i], "name" = i)) - - var/list/result = presentpicker(usr, "Modify armor", "Modify armor: [O]", Button1="Save", Button2 = "Cancel", Timeout=FALSE, inputtype = "text", values = pickerlist) - - if (islist(result)) - if (result["button"] == 2) // If the user pressed the cancel button - return - // text2num conveniently returns a null on invalid values - O.armor = O.armor.setRating(melee = text2num(result["values"]["melee"]),\ - bullet = text2num(result["values"]["bullet"]),\ - laser = text2num(result["values"]["laser"]),\ - energy = text2num(result["values"]["energy"]),\ - bomb = text2num(result["values"]["bomb"]),\ - bio = text2num(result["values"]["bio"]),\ - rad = text2num(result["values"]["rad"]),\ - fire = text2num(result["values"]["fire"]),\ - acid = text2num(result["values"]["acid"])) - log_admin("[key_name(usr)] modified the armor on [O] ([O.type]) to melee: [O.armor.melee], bullet: [O.armor.bullet], laser: [O.armor.laser], energy: [O.armor.energy], bomb: [O.armor.bomb], bio: [O.armor.bio], rad: [O.armor.rad], fire: [O.armor.fire], acid: [O.armor.acid]") - message_admins("[key_name_admin(usr)] modified the armor on [O] ([O.type]) to melee: [O.armor.melee], bullet: [O.armor.bullet], laser: [O.armor.laser], energy: [O.armor.energy], bomb: [O.armor.bomb], bio: [O.armor.bio], rad: [O.armor.rad], fire: [O.armor.fire], acid: [O.armor.acid]") - else - return - - 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(NONE)) - 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 - switch(alert(usr, "Choose a method.", "Add Reagents", "Search", "Choose from a list", "I'm feeling lucky")) - if("Search") - var/valid_id - while(!valid_id) - chosen_id = input(usr, "Enter the ID of the reagent you want to add.", "Search reagents") as null|text - if(isnull(chosen_id)) //Get me out of here! - break - if(!ispath(text2path(chosen_id))) - chosen_id = pick_closest_path(chosen_id, make_types_fancy(subtypesof(/datum/reagent))) - if(ispath(chosen_id)) - valid_id = TRUE - else - valid_id = TRUE - if(!valid_id) - to_chat(usr, "A reagent with that ID doesn't exist!") - if("Choose from a list") - chosen_id = input(usr, "Choose a reagent to add.", "Choose a reagent.") as null|anything in subtypesof(/datum/reagent) - if("I'm feeling lucky") - chosen_id = pick(subtypesof(/datum/reagent)) - 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]") - - 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) - - 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) - - else if(href_list["modtransform"]) - if(!check_rights(R_DEBUG)) - return - - var/atom/A = locate(href_list["modtransform"]) - if(!istype(A)) - to_chat(usr, "This can only be done to atoms.") - return - - var/result = input(usr, "Choose the transformation to apply","Transform Mod") as null|anything in list("Scale","Translate","Rotate") - var/matrix/M = A.transform - switch(result) - if("Scale") - var/x = input(usr, "Choose x mod","Transform Mod") as null|num - var/y = input(usr, "Choose y mod","Transform Mod") as null|num - if(!isnull(x) && !isnull(y)) - A.transform = M.Scale(x,y) - if("Translate") - var/x = input(usr, "Choose x mod","Transform Mod") as null|num - var/y = input(usr, "Choose y mod","Transform Mod") as null|num - if(!isnull(x) && !isnull(y)) - A.transform = M.Translate(x,y) - if("Rotate") - var/angle = input(usr, "Choose angle to rotate","Transform Mod") as null|num - if(!isnull(angle)) - A.transform = M.Turn(angle) - - else if(href_list["rotatedatum"]) - if(!check_rights(NONE)) - 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)) - vv_update_display(A, "dir", dir2text(A.dir)) - - else if(href_list["editorgans"]) - if(!check_rights(NONE)) - 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) - - else if(href_list["givemartialart"]) - if(!check_rights(NONE)) - return - - var/mob/living/carbon/C = locate(href_list["givemartialart"]) in GLOB.carbon_list - if(!istype(C)) - to_chat(usr, "This can only be done to instances of type /mob/living/carbon") - return - - var/list/artpaths = subtypesof(/datum/martial_art) - var/list/artnames = list() - for(var/i in artpaths) - var/datum/martial_art/M = i - artnames[initial(M.name)] = M - - var/result = input(usr, "Choose the martial art to teach","JUDO CHOP") as null|anything in artnames - if(!usr) - return - if(QDELETED(C)) - to_chat(usr, "Mob doesn't exist anymore") - return - - if(result) - var/chosenart = artnames[result] - var/datum/martial_art/MA = new chosenart - MA.teach(C) - - else if(href_list["givetrauma"]) - if(!check_rights(NONE)) - return - - var/mob/living/carbon/C = locate(href_list["givetrauma"]) in GLOB.mob_list - if(!istype(C)) - to_chat(usr, "This can only be done to instances of type /mob/living/carbon") - return - - var/list/traumas = subtypesof(/datum/brain_trauma) - var/result = input(usr, "Choose the brain trauma to apply","Traumatize") as null|anything in traumas - if(!usr) - return - if(QDELETED(C)) - to_chat(usr, "Mob doesn't exist anymore") - return - - if(result) - C.gain_trauma(result) - - else if(href_list["curetraumas"]) - if(!check_rights(NONE)) - return - - var/mob/living/carbon/C = locate(href_list["curetraumas"]) in GLOB.mob_list - if(!istype(C)) - to_chat(usr, "This can only be done to instances of type /mob/living/carbon") - return - - C.cure_all_traumas(TRAUMA_RESILIENCE_ABSOLUTE) - - else if(href_list["hallucinate"]) - if(!check_rights(NONE)) - return - - var/mob/living/carbon/C = locate(href_list["hallucinate"]) in GLOB.mob_list - if(!istype(C)) - to_chat(usr, "This can only be done to instances of type /mob/living/carbon") - return - - var/list/hallucinations = subtypesof(/datum/hallucination) - var/result = input(usr, "Choose the hallucination to apply","Send Hallucination") as null|anything in hallucinations - if(!usr) - return - if(QDELETED(C)) - to_chat(usr, "Mob doesn't exist anymore") - return - - if(result) - new result(C, TRUE) - - 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 - - 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 - - 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 - - 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 - - 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 - - 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 - - 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 - - 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(BODY_ZONE_HEAD, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) - if(edit_action == "augment") - limb_list += BODY_ZONE_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(NONE)) - 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 - - var/newamt - switch(Text) - if("brute") - L.adjustBruteLoss(amount) - newamt = L.getBruteLoss() - if("fire") - L.adjustFireLoss(amount) - newamt = L.getFireLoss() - if("toxin") - L.adjustToxLoss(amount) - newamt = L.getToxLoss() - if("oxygen") - L.adjustOxyLoss(amount) - newamt = L.getOxyLoss() - if("brain") - L.adjustOrganLoss(ORGAN_SLOT_BRAIN, amount) - newamt = L.getOrganLoss(ORGAN_SLOT_BRAIN) - if("clone") - L.adjustCloneLoss(amount) - newamt = L.getCloneLoss() - if("stamina") - L.adjustStaminaLoss(amount) - newamt = L.getStaminaLoss() - if("arousal") - L.adjustArousalLoss(amount) - newamt = L.getArousalLoss() - if("heart") - L.adjustOrganLoss(ORGAN_SLOT_HEART, amount) - newamt = L.getOrganLoss(ORGAN_SLOT_HEART) - if("liver") - L.adjustOrganLoss(ORGAN_SLOT_LIVER, amount) - newamt = L.getOrganLoss(ORGAN_SLOT_LIVER) - if("lungs") - L.adjustOrganLoss(ORGAN_SLOT_LUNGS, amount) - newamt = L.getOrganLoss(ORGAN_SLOT_LUNGS) - if("eye_sight") - L.adjustOrganLoss(ORGAN_SLOT_EYES, amount) - newamt = L.getOrganLoss(ORGAN_SLOT_EYES) - if("ears") - L.adjustOrganLoss(ORGAN_SLOT_EARS, amount) - newamt = L.getOrganLoss(ORGAN_SLOT_EARS) - if("stomach") - L.adjustOrganLoss(ORGAN_SLOT_STOMACH, amount) - newamt = L.getOrganLoss(ORGAN_SLOT_STOMACH) - if("tongue") - L.adjustOrganLoss(ORGAN_SLOT_TONGUE, amount) - newamt = L.getOrganLoss(ORGAN_SLOT_TONGUE) - if("appendix") - L.adjustOrganLoss(ORGAN_SLOT_APPENDIX, amount) - newamt = L.getOrganLoss(ORGAN_SLOT_APPENDIX) - 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) - vv_update_display(L, Text, "[newamt]") - else if(href_list["copyoutfit"]) - if(!check_rights(R_SPAWN)) - return - var/mob/living/carbon/human/H = locate(href_list["copyoutfit"]) in GLOB.carbon_list - if(istype(H)) - H.copy_outfit() - else if(href_list["modquirks"]) - if(!check_rights(R_SPAWN)) - return - - var/mob/living/carbon/human/H = locate(href_list["modquirks"]) 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/list/options = list("Clear"="Clear") - for(var/x in subtypesof(/datum/quirk)) - var/datum/quirk/T = x - var/qname = initial(T.name) - options[H.has_quirk(T) ? "[qname] (Remove)" : "[qname] (Add)"] = T - - var/result = input(usr, "Choose quirk to add/remove","Quirk Mod") as null|anything in options - if(result) - if(result == "Clear") - for(var/datum/quirk/q in H.roundstart_quirks) - H.remove_quirk(q.type) - else - var/T = options[result] - if(H.has_quirk(T)) - H.remove_quirk(T) - else - H.add_quirk(T,TRUE) +#define VV_MSG_MARKED "
      Marked Object" +#define VV_MSG_EDITED "
      Var Edited" +#define VV_MSG_DELETED "
      Deleted" + +/datum/proc/CanProcCall(procname) + return TRUE + +/datum/proc/can_vv_get(var_name) + return TRUE + +/datum/proc/vv_edit_var(var_name, var_value) //called whenever a var is edited + if(var_name == NAMEOF(src, vars)) + return FALSE + vars[var_name] = var_value + datum_flags |= DF_VAR_EDITED + return TRUE + +/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 . += "---" +/datum/proc/vv_get_dropdown() + . = list() + . += "---" + .["Call Proc"] = "?_src_=vars;[HrefToken()];proc_call=[REF(src)]" + .["Mark Object"] = "?_src_=vars;[HrefToken()];mark_object=[REF(src)]" + .["Delete"] = "?_src_=vars;[HrefToken()];delete=[REF(src)]" + .["Show VV To Player"] = "?_src_=vars;[HrefToken(TRUE)];expose=[REF(src)]" + + +/datum/proc/on_reagent_change(changetype) + 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) //The usr vs src abuse in this proc is intentional and must not be changed + 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) + src << browse_rsc(sprite, "vv[hash].png") + + title = "[D] ([REF(D)]) = [type]" + var/formatted_type = replacetext("[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]" + atomsnowflake += "
      << [dir2text(A.dir) || A.dir] >>" + var/mob/living/M = A + atomsnowflake += {" +
      [M.ckey || "No ckey"] / [M.real_name || "No real name"] +
      + BRUTE:[M.getBruteLoss()] + FIRE:[M.getFireLoss()] + TOXIN:[M.getToxLoss()] + OXY:[M.getOxyLoss()] + CLONE:[M.getCloneLoss()] + BRAIN:[M.getOrganLoss(ORGAN_SLOT_BRAIN)] + STAMINA:[M.getStaminaLoss()] + AROUSAL:[M.getArousalLoss()] + "} + if(GLOB.Debug2) + atomsnowflake += {" + HEART:[M.getOrganLoss(ORGAN_SLOT_HEART)] + LIVER:[M.getOrganLoss(ORGAN_SLOT_LIVER)] + LUNGS:[M.getOrganLoss(ORGAN_SLOT_LUNGS)] + EYES:[M.getOrganLoss(ORGAN_SLOT_EYES)] + EARS:[M.getOrganLoss(ORGAN_SLOT_EARS)] + STOMACH:[M.getOrganLoss(ORGAN_SLOT_STOMACH)] + TONGUE:[M.getOrganLoss(ORGAN_SLOT_TONGUE)] + APPENDIX:[M.getOrganLoss(ORGAN_SLOT_APPENDIX)] + "} + atomsnowflake += {" + + "} + else + atomsnowflake += "[D]" + atomsnowflake += "
      << [dir2text(A.dir) || A.dir] >>" + else if("name" in D.vars) + atomsnowflake += "[D]" + else + atomsnowflake += "[formatted_type]" + formatted_type = null + + var/marked + if(holder && holder.marked_datum && holder.marked_datum == D) + marked = VV_MSG_MARKED + var/varedited_line = "" + if(!islist && (D.datum_flags & DF_VAR_EDITED)) + varedited_line = VV_MSG_EDITED + var/deleted_line + if(!islist && D.gc_destroyed) + deleted_line = VV_MSG_DELETED + + var/list/dropdownoptions = list() + if (islist) + dropdownoptions = list( + "---", + "Add Item" = "?_src_=vars;[HrefToken()];listadd=[refid]", + "Remove Nulls" = "?_src_=vars;[HrefToken()];listnulls=[refid]", + "Remove Dupes" = "?_src_=vars;[HrefToken()];listdupes=[refid]", + "Set len" = "?_src_=vars;[HrefToken()];listlen=[refid]", + "Shuffle" = "?_src_=vars;[HrefToken()];listshuffle=[refid]", + "Show VV To Player" = "?_src_=vars;[HrefToken()];expose=[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] + [deleted_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()] +
      + + + +"} + src << browse(html, "window=variables[refid];size=475x650") + + +/client/proc/vv_update_display(datum/D, span, content) + src << output("[span]:[content]", "variables[REF(D)].browser:replace_span") + + +#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 = "
    26. (E) (C) (-) " + else + header = "
    27. (E) (C) (M) " + else + header = "
    28. " + + 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 (isfile(value)) + item = "[VV_HTML_ENCODE(name)] = '[value]'" + + 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 (isnull(val)) // we still want to display non-null false values, such as 0 or "" + 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 if (name in GLOB.bitfields) + var/list/flags = list() + for (var/i in GLOB.bitfields[name]) + if (value & GLOB.bitfields[name][i]) + flags += i + item = "[VV_HTML_ENCODE(name)] = [VV_HTML_ENCODE(jointext(flags, ", "))]" + else + item = "[VV_HTML_ENCODE(name)] = [VV_HTML_ENCODE(value)]" + + return "[header][item]
    29. " + +#undef VV_HTML_ENCODE + +/client/proc/view_var_Topic(href, href_list, hsrc) + if( (usr.client != src) || !src.holder || !holder.CheckAdminHref(href, href_list)) + 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(NONE)) + return + + 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) + + 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) + + else if(href_list["mark_object"]) + if(!check_rights(NONE)) + 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 + + if(holder.marked_datum) + vv_update_display(holder.marked_datum, "marked", "") + holder.marked_datum = D + vv_update_display(D, "marked", VV_MSG_MARKED) + + else if(href_list["proc_call"]) + if(!check_rights(NONE)) + 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(!istype(D)) + to_chat(usr, "Unable to locate item!") + admin_delete(D) + if (isturf(D)) // show the turf that took its place + debug_variables(D) + + else if(href_list["osay"]) + if(!check_rights(R_FUN, 0)) + return + usr.client.object_say(locate(href_list["osay"])) + + else if(href_list["regenerateicons"]) + if(!check_rights(NONE)) + return + + var/mob/M = locate(href_list["regenerateicons"]) in GLOB.mob_list + 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(NONE)) + return + + 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) + vv_update_display(M, "name", new_name) + vv_update_display(M, "real_name", M.real_name || "No real name") + + else if(href_list["varnameedit"] && href_list["datumedit"]) + if(!check_rights(NONE)) + return + + var/datum/D = locate(href_list["datumedit"]) + if(!istype(D, /datum)) + to_chat(usr, "This can only be used on datums") + return + + if (!modify_variables(D, href_list["varnameedit"], 1)) + return + switch(href_list["varnameedit"]) + if("name") + vv_update_display(D, "name", "[D]") + if("dir") + if(isatom(D)) + var/dir = D.vars["dir"] + vv_update_display(D, "dir", dir2text(dir) || dir) + if("ckey") + if(isliving(D)) + vv_update_display(D, "ckey", D.vars["ckey"] || "No ckey") + if("real_name") + if(isliving(D)) + vv_update_display(D, "real_name", D.vars["real_name"] || "No real name") + + else if(href_list["varnamechange"] && href_list["datumchange"]) + if(!check_rights(NONE)) + 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(NONE)) + 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(NONE)) + 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) + + else if(href_list["remove_spell"]) + if(!check_rights(NONE)) + 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) + + else if(href_list["give_disease"]) + if(!check_rights(NONE)) + 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) + + 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 + + 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) + + else if(href_list["drop_everything"]) + if(!check_rights(NONE)) + 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(NONE)) + 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(NONE)) + 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["modarmor"]) + if(!check_rights(NONE)) + return + + var/obj/O = locate(href_list["modarmor"]) + if(!istype(O)) + to_chat(usr, "This can only be used on instances of type /obj") + return + + var/list/pickerlist = list() + var/list/armorlist = O.armor.getList() + + for (var/i in armorlist) + pickerlist += list(list("value" = armorlist[i], "name" = i)) + + var/list/result = presentpicker(usr, "Modify armor", "Modify armor: [O]", Button1="Save", Button2 = "Cancel", Timeout=FALSE, inputtype = "text", values = pickerlist) + + if (islist(result)) + if (result["button"] == 2) // If the user pressed the cancel button + return + // text2num conveniently returns a null on invalid values + O.armor = O.armor.setRating(melee = text2num(result["values"]["melee"]),\ + bullet = text2num(result["values"]["bullet"]),\ + laser = text2num(result["values"]["laser"]),\ + energy = text2num(result["values"]["energy"]),\ + bomb = text2num(result["values"]["bomb"]),\ + bio = text2num(result["values"]["bio"]),\ + rad = text2num(result["values"]["rad"]),\ + fire = text2num(result["values"]["fire"]),\ + acid = text2num(result["values"]["acid"])) + log_admin("[key_name(usr)] modified the armor on [O] ([O.type]) to melee: [O.armor.melee], bullet: [O.armor.bullet], laser: [O.armor.laser], energy: [O.armor.energy], bomb: [O.armor.bomb], bio: [O.armor.bio], rad: [O.armor.rad], fire: [O.armor.fire], acid: [O.armor.acid]") + message_admins("[key_name_admin(usr)] modified the armor on [O] ([O.type]) to melee: [O.armor.melee], bullet: [O.armor.bullet], laser: [O.armor.laser], energy: [O.armor.energy], bomb: [O.armor.bomb], bio: [O.armor.bio], rad: [O.armor.rad], fire: [O.armor.fire], acid: [O.armor.acid]") + else + return + + 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(NONE)) + 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 + switch(alert(usr, "Choose a method.", "Add Reagents", "Search", "Choose from a list", "I'm feeling lucky")) + if("Search") + var/valid_id + while(!valid_id) + chosen_id = input(usr, "Enter the ID of the reagent you want to add.", "Search reagents") as null|text + if(isnull(chosen_id)) //Get me out of here! + break + if(!ispath(text2path(chosen_id))) + chosen_id = pick_closest_path(chosen_id, make_types_fancy(subtypesof(/datum/reagent))) + if(ispath(chosen_id)) + valid_id = TRUE + else + valid_id = TRUE + if(!valid_id) + to_chat(usr, "A reagent with that ID doesn't exist!") + if("Choose from a list") + chosen_id = input(usr, "Choose a reagent to add.", "Choose a reagent.") as null|anything in subtypesof(/datum/reagent) + if("I'm feeling lucky") + chosen_id = pick(subtypesof(/datum/reagent)) + 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]") + + 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) + + 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) + + else if(href_list["modtransform"]) + if(!check_rights(R_DEBUG)) + return + + var/atom/A = locate(href_list["modtransform"]) + if(!istype(A)) + to_chat(usr, "This can only be done to atoms.") + return + + var/result = input(usr, "Choose the transformation to apply","Transform Mod") as null|anything in list("Scale","Translate","Rotate") + var/matrix/M = A.transform + switch(result) + if("Scale") + var/x = input(usr, "Choose x mod","Transform Mod") as null|num + var/y = input(usr, "Choose y mod","Transform Mod") as null|num + if(!isnull(x) && !isnull(y)) + A.transform = M.Scale(x,y) + if("Translate") + var/x = input(usr, "Choose x mod","Transform Mod") as null|num + var/y = input(usr, "Choose y mod","Transform Mod") as null|num + if(!isnull(x) && !isnull(y)) + A.transform = M.Translate(x,y) + if("Rotate") + var/angle = input(usr, "Choose angle to rotate","Transform Mod") as null|num + if(!isnull(angle)) + A.transform = M.Turn(angle) + + else if(href_list["rotatedatum"]) + if(!check_rights(NONE)) + 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)) + vv_update_display(A, "dir", dir2text(A.dir)) + + else if(href_list["editorgans"]) + if(!check_rights(NONE)) + 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) + + else if(href_list["givemartialart"]) + if(!check_rights(NONE)) + return + + var/mob/living/carbon/C = locate(href_list["givemartialart"]) in GLOB.carbon_list + if(!istype(C)) + to_chat(usr, "This can only be done to instances of type /mob/living/carbon") + return + + var/list/artpaths = subtypesof(/datum/martial_art) + var/list/artnames = list() + for(var/i in artpaths) + var/datum/martial_art/M = i + artnames[initial(M.name)] = M + + var/result = input(usr, "Choose the martial art to teach","JUDO CHOP") as null|anything in artnames + if(!usr) + return + if(QDELETED(C)) + to_chat(usr, "Mob doesn't exist anymore") + return + + if(result) + var/chosenart = artnames[result] + var/datum/martial_art/MA = new chosenart + MA.teach(C) + + else if(href_list["givetrauma"]) + if(!check_rights(NONE)) + return + + var/mob/living/carbon/C = locate(href_list["givetrauma"]) in GLOB.mob_list + if(!istype(C)) + to_chat(usr, "This can only be done to instances of type /mob/living/carbon") + return + + var/list/traumas = subtypesof(/datum/brain_trauma) + var/result = input(usr, "Choose the brain trauma to apply","Traumatize") as null|anything in traumas + if(!usr) + return + if(QDELETED(C)) + to_chat(usr, "Mob doesn't exist anymore") + return + + if(result) + C.gain_trauma(result) + + else if(href_list["curetraumas"]) + if(!check_rights(NONE)) + return + + var/mob/living/carbon/C = locate(href_list["curetraumas"]) in GLOB.mob_list + if(!istype(C)) + to_chat(usr, "This can only be done to instances of type /mob/living/carbon") + return + + C.cure_all_traumas(TRAUMA_RESILIENCE_ABSOLUTE) + + else if(href_list["hallucinate"]) + if(!check_rights(NONE)) + return + + var/mob/living/carbon/C = locate(href_list["hallucinate"]) in GLOB.mob_list + if(!istype(C)) + to_chat(usr, "This can only be done to instances of type /mob/living/carbon") + return + + var/list/hallucinations = subtypesof(/datum/hallucination) + var/result = input(usr, "Choose the hallucination to apply","Send Hallucination") as null|anything in hallucinations + if(!usr) + return + if(QDELETED(C)) + to_chat(usr, "Mob doesn't exist anymore") + return + + if(result) + new result(C, TRUE) + + 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 + + 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 + + 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 + + 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 + + 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 + + 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 + + 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 + + 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(BODY_ZONE_HEAD, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) + if(edit_action == "augment") + limb_list += BODY_ZONE_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(NONE)) + 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 + + var/newamt + switch(Text) + if("brute") + L.adjustBruteLoss(amount) + newamt = L.getBruteLoss() + if("fire") + L.adjustFireLoss(amount) + newamt = L.getFireLoss() + if("toxin") + L.adjustToxLoss(amount) + newamt = L.getToxLoss() + if("oxygen") + L.adjustOxyLoss(amount) + newamt = L.getOxyLoss() + if("brain") + L.adjustOrganLoss(ORGAN_SLOT_BRAIN, amount) + newamt = L.getOrganLoss(ORGAN_SLOT_BRAIN) + if("clone") + L.adjustCloneLoss(amount) + newamt = L.getCloneLoss() + if("stamina") + L.adjustStaminaLoss(amount) + newamt = L.getStaminaLoss() + if("arousal") + L.adjustArousalLoss(amount) + newamt = L.getArousalLoss() + if("heart") + L.adjustOrganLoss(ORGAN_SLOT_HEART, amount) + newamt = L.getOrganLoss(ORGAN_SLOT_HEART) + if("liver") + L.adjustOrganLoss(ORGAN_SLOT_LIVER, amount) + newamt = L.getOrganLoss(ORGAN_SLOT_LIVER) + if("lungs") + L.adjustOrganLoss(ORGAN_SLOT_LUNGS, amount) + newamt = L.getOrganLoss(ORGAN_SLOT_LUNGS) + if("eye_sight") + L.adjustOrganLoss(ORGAN_SLOT_EYES, amount) + newamt = L.getOrganLoss(ORGAN_SLOT_EYES) + if("ears") + L.adjustOrganLoss(ORGAN_SLOT_EARS, amount) + newamt = L.getOrganLoss(ORGAN_SLOT_EARS) + if("stomach") + L.adjustOrganLoss(ORGAN_SLOT_STOMACH, amount) + newamt = L.getOrganLoss(ORGAN_SLOT_STOMACH) + if("tongue") + L.adjustOrganLoss(ORGAN_SLOT_TONGUE, amount) + newamt = L.getOrganLoss(ORGAN_SLOT_TONGUE) + if("appendix") + L.adjustOrganLoss(ORGAN_SLOT_APPENDIX, amount) + newamt = L.getOrganLoss(ORGAN_SLOT_APPENDIX) + 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) + vv_update_display(L, Text, "[newamt]") + else if(href_list["copyoutfit"]) + if(!check_rights(R_SPAWN)) + return + var/mob/living/carbon/human/H = locate(href_list["copyoutfit"]) in GLOB.carbon_list + if(istype(H)) + H.copy_outfit() + else if(href_list["modquirks"]) + if(!check_rights(R_SPAWN)) + return + + var/mob/living/carbon/human/H = locate(href_list["modquirks"]) 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/list/options = list("Clear"="Clear") + for(var/x in subtypesof(/datum/quirk)) + var/datum/quirk/T = x + var/qname = initial(T.name) + options[H.has_quirk(T) ? "[qname] (Remove)" : "[qname] (Add)"] = T + + var/result = input(usr, "Choose quirk to add/remove","Quirk Mod") as null|anything in options + if(result) + if(result == "Clear") + for(var/datum/quirk/q in H.roundstart_quirks) + H.remove_quirk(q.type) + else + var/T = options[result] + if(H.has_quirk(T)) + H.remove_quirk(T) + else + H.add_quirk(T,TRUE) diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index a844254ef9..6b72f2fdfc 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -1,495 +1,495 @@ -/* - - Advance Disease is a system for Virologist to Engineer their own disease with symptoms that have effects and properties - which add onto the overall disease. - - If you need help with creating new symptoms or expanding the advance disease, ask for Giacom on #coderbus. - -*/ - - - - -/* - - PROPERTIES - - */ - -/datum/disease/advance - name = "Unknown" // We will always let our Virologist name our disease. - desc = "An engineered disease which can contain a multitude of symptoms." - form = "Advance Disease" // Will let med-scanners know that this disease was engineered. - agent = "advance microbes" - max_stages = 5 - spread_text = "Unknown" - viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - - // NEW VARS - var/list/properties = list() - var/list/symptoms = list() // The symptoms of the disease. - var/id = "" - var/processing = FALSE - var/mutable = TRUE //set to FALSE to prevent most in-game methods of altering the disease via virology - var/oldres //To prevent setting new cures unless resistance changes. - - // The order goes from easy to cure to hard to cure. Keep in mind that sentient diseases pick two cures from tier 6 and up, ensure they wont react away in bodies. - var/static/list/advance_cures = list( - list( // level 1 - /datum/reagent/copper, /datum/reagent/silver, /datum/reagent/iodine, /datum/reagent/iron, /datum/reagent/carbon - ), - list( // level 2 - /datum/reagent/potassium, /datum/reagent/consumable/ethanol, /datum/reagent/lithium, - /datum/reagent/silicon, /datum/reagent/bromine - ), - list( // level 3 - /datum/reagent/consumable/sodiumchloride, /datum/reagent/consumable/sugar, /datum/reagent/consumable/orangejuice, - /datum/reagent/consumable/tomatojuice, /datum/reagent/consumable/milk - ), - list( //level 4 - /datum/reagent/medicine/spaceacillin, /datum/reagent/medicine/salglu_solution, - /datum/reagent/medicine/epinephrine, /datum/reagent/medicine/charcoal - ), - list( //level 5 - /datum/reagent/oil, /datum/reagent/medicine/synaptizine, /datum/reagent/medicine/mannitol, - /datum/reagent/drug/space_drugs, /datum/reagent/cryptobiolin - ), - list( // level 6 - /datum/reagent/phenol, /datum/reagent/medicine/inacusiate, /datum/reagent/medicine/oculine, /datum/reagent/medicine/antihol - ), - list( // level 7 - /datum/reagent/medicine/leporazine, /datum/reagent/toxin/mindbreaker, /datum/reagent/medicine/corazone - ), - list( // level 8 - /datum/reagent/pax, /datum/reagent/drug/happiness, /datum/reagent/medicine/ephedrine - ), - list( // level 9 - /datum/reagent/toxin/lipolicide, /datum/reagent/medicine/sal_acid - ), - list( // level 10 - /datum/reagent/medicine/haloperidol, /datum/reagent/drug/aranesp, /datum/reagent/medicine/diphenhydramine - ), - list( //level 11 - /datum/reagent/medicine/modafinil, /datum/reagent/toxin/anacea - ) - ) - -/* - - OLD PROCS - - */ - -/datum/disease/advance/New() - Refresh() - -/datum/disease/advance/Destroy() - if(processing) - for(var/datum/symptom/S in symptoms) - S.End(src) - return ..() - -/datum/disease/advance/try_infect(var/mob/living/infectee, make_copy = TRUE) - //see if we are more transmittable than enough diseases to replace them - //diseases replaced in this way do not confer immunity - var/list/advance_diseases = list() - for(var/datum/disease/advance/P in infectee.diseases) - advance_diseases += P - var/replace_num = advance_diseases.len + 1 - DISEASE_LIMIT //amount of diseases that need to be removed to fit this one - if(replace_num > 0) - sortTim(advance_diseases, /proc/cmp_advdisease_resistance_asc) - for(var/i in 1 to replace_num) - var/datum/disease/advance/competition = advance_diseases[i] - if(totalTransmittable() > competition.totalResistance()) - competition.cure(FALSE) - else - return FALSE //we are not strong enough to bully our way in - infect(infectee, make_copy) - return TRUE - -// Randomly pick a symptom to activate. -/datum/disease/advance/stage_act() - ..() - if(carrier) - return - - if(symptoms && symptoms.len) - if(!processing) - processing = TRUE - for(var/datum/symptom/S in symptoms) - if(S.Start(src)) //this will return FALSE if the symptom is neutered - S.next_activation = world.time + rand(S.symptom_delay_min * 10, S.symptom_delay_max * 10) - S.on_stage_change(src) - - for(var/datum/symptom/S in symptoms) - S.Activate(src) - -// Tell symptoms stage changed -/datum/disease/advance/update_stage(new_stage) - ..() - for(var/datum/symptom/S in symptoms) - S.on_stage_change(src) - -// Compares type then ID. -/datum/disease/advance/IsSame(datum/disease/advance/D) - - if(!(istype(D, /datum/disease/advance))) - return 0 - - if(GetDiseaseID() != D.GetDiseaseID()) - return 0 - return 1 - -// Returns the advance disease with a different reference memory. -/datum/disease/advance/Copy() - var/datum/disease/advance/A = ..() - QDEL_LIST(A.symptoms) - for(var/datum/symptom/S in symptoms) - A.symptoms += S.Copy() - A.properties = properties.Copy() - A.id = id - A.mutable = mutable - A.oldres = oldres - //this is a new disease starting over at stage 1, so processing is not copied - return A - -//Describe this disease to an admin in detail (for logging) -/datum/disease/advance/admin_details() - var/list/name_symptoms = list() - for(var/datum/symptom/S in symptoms) - name_symptoms += S.name - return "[name] sym:[english_list(name_symptoms)] r:[totalResistance()] s:[totalStealth()] ss:[totalStageSpeed()] t:[totalTransmittable()]" - - -/* - - NEW PROCS - - */ - -// Mix the symptoms of two diseases (the src and the argument) -/datum/disease/advance/proc/Mix(datum/disease/advance/D) - if(!(IsSame(D))) - var/list/possible_symptoms = shuffle(D.symptoms) - for(var/datum/symptom/S in possible_symptoms) - AddSymptom(S.Copy()) - -/datum/disease/advance/proc/HasSymptom(datum/symptom/S) - for(var/datum/symptom/symp in symptoms) - if(symp.type == S.type) - return 1 - return 0 - -// Will generate new unique symptoms, use this if there are none. Returns a list of symptoms that were generated. -/datum/disease/advance/proc/GenerateSymptoms(level_min, level_max, amount_get = 0) - - var/list/generated = list() // Symptoms we generated. - - // Generate symptoms. By default, we only choose non-deadly symptoms. - var/list/possible_symptoms = list() - for(var/symp in SSdisease.list_symptoms) - var/datum/symptom/S = new symp - if(S.naturally_occuring && S.level >= level_min && S.level <= level_max) - if(!HasSymptom(S)) - possible_symptoms += S - - if(!possible_symptoms.len) - return generated - - // Random chance to get more than one symptom - var/number_of = amount_get - if(!amount_get) - number_of = 1 - while(prob(20)) - number_of += 1 - - for(var/i = 1; number_of >= i && possible_symptoms.len; i++) - generated += pick_n_take(possible_symptoms) - - return generated - -/datum/disease/advance/proc/Refresh(new_name = FALSE) - GenerateProperties() - AssignProperties() - if(processing && symptoms && symptoms.len) - for(var/datum/symptom/S in symptoms) - S.Start(src) - S.on_stage_change(src) - id = null - - var/the_id = GetDiseaseID() - if(!SSdisease.archive_diseases[the_id]) - SSdisease.archive_diseases[the_id] = src // So we don't infinite loop - SSdisease.archive_diseases[the_id] = Copy() - if(new_name) - AssignName() - -//Generate disease properties based on the effects. Returns an associated list. -/datum/disease/advance/proc/GenerateProperties() - properties = list("resistance" = 0, "stealth" = 0, "stage_rate" = 0, "transmittable" = 0, "severity" = 0) - - for(var/datum/symptom/S in symptoms) - properties["resistance"] += S.resistance - properties["stealth"] += S.stealth - properties["stage_rate"] += S.stage_speed - properties["transmittable"] += S.transmittable - if(!S.neutered) - properties["severity"] = max(properties["severity"], S.severity) // severity is based on the highest severity non-neutered symptom - -// Assign the properties that are in the list. -/datum/disease/advance/proc/AssignProperties() - - if(properties && properties.len) - if(properties["stealth"] >= 2) - visibility_flags |= HIDDEN_SCANNER - else - visibility_flags &= ~HIDDEN_SCANNER - - SetSpread(CLAMP(2 ** (properties["transmittable"] - symptoms.len), DISEASE_SPREAD_BLOOD, DISEASE_SPREAD_AIRBORNE)) - - permeability_mod = max(CEILING(0.4 * properties["transmittable"], 1), 1) - cure_chance = 15 - CLAMP(properties["resistance"], -5, 5) // can be between 10 and 20 - stage_prob = max(properties["stage_rate"], 2) - SetSeverity(properties["severity"]) - GenerateCure(properties) - else - CRASH("Our properties were empty or null!") - - -// Assign the spread type and give it the correct description. -/datum/disease/advance/proc/SetSpread(spread_id) - switch(spread_id) - if(DISEASE_SPREAD_NON_CONTAGIOUS) - spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS - spread_text = "None" - if(DISEASE_SPREAD_SPECIAL) - spread_flags = DISEASE_SPREAD_SPECIAL - spread_text = "None" - if(DISEASE_SPREAD_BLOOD) - spread_flags = DISEASE_SPREAD_BLOOD - spread_text = "Blood" - if(DISEASE_SPREAD_CONTACT_FLUIDS) - spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS - spread_text = "Fluids" - if(DISEASE_SPREAD_CONTACT_SKIN) - spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS | DISEASE_SPREAD_CONTACT_SKIN - spread_text = "On contact" - if(DISEASE_SPREAD_AIRBORNE) - spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_AIRBORNE - spread_text = "Airborne" - -/datum/disease/advance/proc/SetSeverity(level_sev) - - switch(level_sev) - - if(-INFINITY to 0) - severity = DISEASE_SEVERITY_POSITIVE - if(1) - severity = DISEASE_SEVERITY_NONTHREAT - if(2) - severity = DISEASE_SEVERITY_MINOR - if(3) - severity = DISEASE_SEVERITY_MEDIUM - if(4) - severity = DISEASE_SEVERITY_HARMFUL - if(5) - severity = DISEASE_SEVERITY_DANGEROUS - if(6 to INFINITY) - severity = DISEASE_SEVERITY_BIOHAZARD - else - severity = "Unknown" - - -// Will generate a random cure, the less resistance the symptoms have, the harder the cure. -/datum/disease/advance/proc/GenerateCure() - if(properties && properties.len) - var/res = CLAMP(properties["resistance"] - (symptoms.len / 2), 1, advance_cures.len) - if(res == oldres) - return - cures = list(pick(advance_cures[res])) - oldres = res - - // Get the cure name from the cure_id - var/datum/reagent/D = GLOB.chemical_reagents_list[cures[1]] - cure_text = D.name - -// Randomly generate a symptom, has a chance to lose or gain a symptom. -/datum/disease/advance/proc/Evolve(min_level, max_level, ignore_mutable = FALSE) - if(!mutable && !ignore_mutable) - return - var/s = safepick(GenerateSymptoms(min_level, max_level, 1)) - if(s) - AddSymptom(s) - Refresh(TRUE) - return - -// Randomly remove a symptom. -/datum/disease/advance/proc/Devolve(ignore_mutable = FALSE) - if(!mutable && !ignore_mutable) - return - if(symptoms.len > 1) - var/s = safepick(symptoms) - if(s) - RemoveSymptom(s) - Refresh(TRUE) - -// Randomly neuter a symptom. -/datum/disease/advance/proc/Neuter(ignore_mutable = FALSE) - if(!mutable && !ignore_mutable) - return - if(symptoms.len) - var/s = safepick(symptoms) - if(s) - NeuterSymptom(s) - Refresh(TRUE) - -// Name the disease. -/datum/disease/advance/proc/AssignName(name = "Unknown") - Refresh() - var/datum/disease/advance/A = SSdisease.archive_diseases[GetDiseaseID()] - A.name = name - for(var/datum/disease/advance/AD in SSdisease.active_diseases) - AD.Refresh() - -// Return a unique ID of the disease. -/datum/disease/advance/GetDiseaseID() - if(!id) - var/list/L = list() - for(var/datum/symptom/S in symptoms) - if(S.neutered) - L += "[S.id]N" - else - L += S.id - L = sortList(L) // Sort the list so it doesn't matter which order the symptoms are in. - var/result = jointext(L, ":") - id = result - return id - - -// Add a symptom, if it is over the limit we take a random symptom away and add the new one. -/datum/disease/advance/proc/AddSymptom(datum/symptom/S) - - if(HasSymptom(S)) - return - - if(!(symptoms.len < (VIRUS_SYMPTOM_LIMIT - 1) + rand(-1, 1))) - RemoveSymptom(pick(symptoms)) - symptoms += S - S.OnAdd(src) - -// Simply removes the symptom. -/datum/disease/advance/proc/RemoveSymptom(datum/symptom/S) - symptoms -= S - S.OnRemove(src) - -// Neuter a symptom, so it will only affect stats -/datum/disease/advance/proc/NeuterSymptom(datum/symptom/S) - if(!S.neutered) - S.neutered = TRUE - S.name += " (neutered)" - S.OnRemove(src) - -/* - - Static Procs - -*/ - -// Mix a list of advance diseases and return the mixed result. -/proc/Advance_Mix(var/list/D_list) - var/list/diseases = list() - - for(var/datum/disease/advance/A in D_list) - diseases += A.Copy() - - if(!diseases.len) - return null - if(diseases.len <= 1) - return pick(diseases) // Just return the only entry. - - var/i = 0 - // Mix our diseases until we are left with only one result. - while(i < 20 && diseases.len > 1) - - i++ - - var/datum/disease/advance/D1 = pick(diseases) - diseases -= D1 - - var/datum/disease/advance/D2 = pick(diseases) - D2.Mix(D1) - - // Should be only 1 entry left, but if not let's only return a single entry - var/datum/disease/advance/to_return = pick(diseases) - to_return.Refresh(1) - return to_return - -/proc/SetViruses(datum/reagent/R, list/data) - if(data) - var/list/preserve = list() - if(istype(data) && data["viruses"]) - for(var/datum/disease/A in data["viruses"]) - preserve += A.Copy() - R.data = data.Copy() - if(preserve.len) - R.data["viruses"] = preserve - -/proc/AdminCreateVirus(client/user) - - if(!user) - return - - var/i = VIRUS_SYMPTOM_LIMIT - - var/datum/disease/advance/D = new() - D.symptoms = list() - - var/list/symptoms = list() - symptoms += "Done" - symptoms += SSdisease.list_symptoms.Copy() - do - if(user) - var/symptom = input(user, "Choose a symptom to add ([i] remaining)", "Choose a Symptom") in symptoms - if(isnull(symptom)) - return - else if(istext(symptom)) - i = 0 - else if(ispath(symptom)) - var/datum/symptom/S = new symptom - if(!D.HasSymptom(S)) - D.symptoms += S - i -= 1 - while(i > 0) - - if(D.symptoms.len > 0) - - var/new_name = stripped_input(user, "Name your new disease.", "New Name") - if(!new_name) - return - D.AssignName(new_name) - D.Refresh() - - for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list)) - if(!is_station_level(H.z)) - continue - if(!H.HasDisease(D)) - H.ForceContractDisease(D) - break - - var/list/name_symptoms = list() - for(var/datum/symptom/S in D.symptoms) - name_symptoms += S.name - message_admins("[key_name_admin(user)] has triggered a custom virus outbreak of [D.admin_details()]") - log_virus("[key_name(user)] has triggered a custom virus outbreak of [D.admin_details()]!") - -/datum/disease/advance/proc/totalStageSpeed() - return properties["stage_rate"] - -/datum/disease/advance/proc/totalStealth() - return properties["stealth"] - -/datum/disease/advance/proc/totalResistance() - return properties["resistance"] - -/datum/disease/advance/proc/totalTransmittable() - return properties["transmittable"] +/* + + Advance Disease is a system for Virologist to Engineer their own disease with symptoms that have effects and properties + which add onto the overall disease. + + If you need help with creating new symptoms or expanding the advance disease, ask for Giacom on #coderbus. + +*/ + + + + +/* + + PROPERTIES + + */ + +/datum/disease/advance + name = "Unknown" // We will always let our Virologist name our disease. + desc = "An engineered disease which can contain a multitude of symptoms." + form = "Advance Disease" // Will let med-scanners know that this disease was engineered. + agent = "advance microbes" + max_stages = 5 + spread_text = "Unknown" + viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) + + // NEW VARS + var/list/properties = list() + var/list/symptoms = list() // The symptoms of the disease. + var/id = "" + var/processing = FALSE + var/mutable = TRUE //set to FALSE to prevent most in-game methods of altering the disease via virology + var/oldres //To prevent setting new cures unless resistance changes. + + // The order goes from easy to cure to hard to cure. Keep in mind that sentient diseases pick two cures from tier 6 and up, ensure they wont react away in bodies. + var/static/list/advance_cures = list( + list( // level 1 + /datum/reagent/copper, /datum/reagent/silver, /datum/reagent/iodine, /datum/reagent/iron, /datum/reagent/carbon + ), + list( // level 2 + /datum/reagent/potassium, /datum/reagent/consumable/ethanol, /datum/reagent/lithium, + /datum/reagent/silicon, /datum/reagent/bromine + ), + list( // level 3 + /datum/reagent/consumable/sodiumchloride, /datum/reagent/consumable/sugar, /datum/reagent/consumable/orangejuice, + /datum/reagent/consumable/tomatojuice, /datum/reagent/consumable/milk + ), + list( //level 4 + /datum/reagent/medicine/spaceacillin, /datum/reagent/medicine/salglu_solution, + /datum/reagent/medicine/epinephrine, /datum/reagent/medicine/charcoal + ), + list( //level 5 + /datum/reagent/oil, /datum/reagent/medicine/synaptizine, /datum/reagent/medicine/mannitol, + /datum/reagent/drug/space_drugs, /datum/reagent/cryptobiolin + ), + list( // level 6 + /datum/reagent/phenol, /datum/reagent/medicine/inacusiate, /datum/reagent/medicine/oculine, /datum/reagent/medicine/antihol + ), + list( // level 7 + /datum/reagent/medicine/leporazine, /datum/reagent/toxin/mindbreaker, /datum/reagent/medicine/corazone + ), + list( // level 8 + /datum/reagent/pax, /datum/reagent/drug/happiness, /datum/reagent/medicine/ephedrine + ), + list( // level 9 + /datum/reagent/toxin/lipolicide, /datum/reagent/medicine/sal_acid + ), + list( // level 10 + /datum/reagent/medicine/haloperidol, /datum/reagent/drug/aranesp, /datum/reagent/medicine/diphenhydramine + ), + list( //level 11 + /datum/reagent/medicine/modafinil, /datum/reagent/toxin/anacea + ) + ) + +/* + + OLD PROCS + + */ + +/datum/disease/advance/New() + Refresh() + +/datum/disease/advance/Destroy() + if(processing) + for(var/datum/symptom/S in symptoms) + S.End(src) + return ..() + +/datum/disease/advance/try_infect(var/mob/living/infectee, make_copy = TRUE) + //see if we are more transmittable than enough diseases to replace them + //diseases replaced in this way do not confer immunity + var/list/advance_diseases = list() + for(var/datum/disease/advance/P in infectee.diseases) + advance_diseases += P + var/replace_num = advance_diseases.len + 1 - DISEASE_LIMIT //amount of diseases that need to be removed to fit this one + if(replace_num > 0) + sortTim(advance_diseases, /proc/cmp_advdisease_resistance_asc) + for(var/i in 1 to replace_num) + var/datum/disease/advance/competition = advance_diseases[i] + if(totalTransmittable() > competition.totalResistance()) + competition.cure(FALSE) + else + return FALSE //we are not strong enough to bully our way in + infect(infectee, make_copy) + return TRUE + +// Randomly pick a symptom to activate. +/datum/disease/advance/stage_act() + ..() + if(carrier) + return + + if(symptoms && symptoms.len) + if(!processing) + processing = TRUE + for(var/datum/symptom/S in symptoms) + if(S.Start(src)) //this will return FALSE if the symptom is neutered + S.next_activation = world.time + rand(S.symptom_delay_min * 10, S.symptom_delay_max * 10) + S.on_stage_change(src) + + for(var/datum/symptom/S in symptoms) + S.Activate(src) + +// Tell symptoms stage changed +/datum/disease/advance/update_stage(new_stage) + ..() + for(var/datum/symptom/S in symptoms) + S.on_stage_change(src) + +// Compares type then ID. +/datum/disease/advance/IsSame(datum/disease/advance/D) + + if(!(istype(D, /datum/disease/advance))) + return 0 + + if(GetDiseaseID() != D.GetDiseaseID()) + return 0 + return 1 + +// Returns the advance disease with a different reference memory. +/datum/disease/advance/Copy() + var/datum/disease/advance/A = ..() + QDEL_LIST(A.symptoms) + for(var/datum/symptom/S in symptoms) + A.symptoms += S.Copy() + A.properties = properties.Copy() + A.id = id + A.mutable = mutable + A.oldres = oldres + //this is a new disease starting over at stage 1, so processing is not copied + return A + +//Describe this disease to an admin in detail (for logging) +/datum/disease/advance/admin_details() + var/list/name_symptoms = list() + for(var/datum/symptom/S in symptoms) + name_symptoms += S.name + return "[name] sym:[english_list(name_symptoms)] r:[totalResistance()] s:[totalStealth()] ss:[totalStageSpeed()] t:[totalTransmittable()]" + + +/* + + NEW PROCS + + */ + +// Mix the symptoms of two diseases (the src and the argument) +/datum/disease/advance/proc/Mix(datum/disease/advance/D) + if(!(IsSame(D))) + var/list/possible_symptoms = shuffle(D.symptoms) + for(var/datum/symptom/S in possible_symptoms) + AddSymptom(S.Copy()) + +/datum/disease/advance/proc/HasSymptom(datum/symptom/S) + for(var/datum/symptom/symp in symptoms) + if(symp.type == S.type) + return 1 + return 0 + +// Will generate new unique symptoms, use this if there are none. Returns a list of symptoms that were generated. +/datum/disease/advance/proc/GenerateSymptoms(level_min, level_max, amount_get = 0) + + var/list/generated = list() // Symptoms we generated. + + // Generate symptoms. By default, we only choose non-deadly symptoms. + var/list/possible_symptoms = list() + for(var/symp in SSdisease.list_symptoms) + var/datum/symptom/S = new symp + if(S.naturally_occuring && S.level >= level_min && S.level <= level_max) + if(!HasSymptom(S)) + possible_symptoms += S + + if(!possible_symptoms.len) + return generated + + // Random chance to get more than one symptom + var/number_of = amount_get + if(!amount_get) + number_of = 1 + while(prob(20)) + number_of += 1 + + for(var/i = 1; number_of >= i && possible_symptoms.len; i++) + generated += pick_n_take(possible_symptoms) + + return generated + +/datum/disease/advance/proc/Refresh(new_name = FALSE) + GenerateProperties() + AssignProperties() + if(processing && symptoms && symptoms.len) + for(var/datum/symptom/S in symptoms) + S.Start(src) + S.on_stage_change(src) + id = null + + var/the_id = GetDiseaseID() + if(!SSdisease.archive_diseases[the_id]) + SSdisease.archive_diseases[the_id] = src // So we don't infinite loop + SSdisease.archive_diseases[the_id] = Copy() + if(new_name) + AssignName() + +//Generate disease properties based on the effects. Returns an associated list. +/datum/disease/advance/proc/GenerateProperties() + properties = list("resistance" = 0, "stealth" = 0, "stage_rate" = 0, "transmittable" = 0, "severity" = 0) + + for(var/datum/symptom/S in symptoms) + properties["resistance"] += S.resistance + properties["stealth"] += S.stealth + properties["stage_rate"] += S.stage_speed + properties["transmittable"] += S.transmittable + if(!S.neutered) + properties["severity"] = max(properties["severity"], S.severity) // severity is based on the highest severity non-neutered symptom + +// Assign the properties that are in the list. +/datum/disease/advance/proc/AssignProperties() + + if(properties && properties.len) + if(properties["stealth"] >= 2) + visibility_flags |= HIDDEN_SCANNER + else + visibility_flags &= ~HIDDEN_SCANNER + + SetSpread(CLAMP(2 ** (properties["transmittable"] - symptoms.len), DISEASE_SPREAD_BLOOD, DISEASE_SPREAD_AIRBORNE)) + + permeability_mod = max(CEILING(0.4 * properties["transmittable"], 1), 1) + cure_chance = 15 - CLAMP(properties["resistance"], -5, 5) // can be between 10 and 20 + stage_prob = max(properties["stage_rate"], 2) + SetSeverity(properties["severity"]) + GenerateCure(properties) + else + CRASH("Our properties were empty or null!") + + +// Assign the spread type and give it the correct description. +/datum/disease/advance/proc/SetSpread(spread_id) + switch(spread_id) + if(DISEASE_SPREAD_NON_CONTAGIOUS) + spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS + spread_text = "None" + if(DISEASE_SPREAD_SPECIAL) + spread_flags = DISEASE_SPREAD_SPECIAL + spread_text = "None" + if(DISEASE_SPREAD_BLOOD) + spread_flags = DISEASE_SPREAD_BLOOD + spread_text = "Blood" + if(DISEASE_SPREAD_CONTACT_FLUIDS) + spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS + spread_text = "Fluids" + if(DISEASE_SPREAD_CONTACT_SKIN) + spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS | DISEASE_SPREAD_CONTACT_SKIN + spread_text = "On contact" + if(DISEASE_SPREAD_AIRBORNE) + spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_FLUIDS | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_AIRBORNE + spread_text = "Airborne" + +/datum/disease/advance/proc/SetSeverity(level_sev) + + switch(level_sev) + + if(-INFINITY to 0) + severity = DISEASE_SEVERITY_POSITIVE + if(1) + severity = DISEASE_SEVERITY_NONTHREAT + if(2) + severity = DISEASE_SEVERITY_MINOR + if(3) + severity = DISEASE_SEVERITY_MEDIUM + if(4) + severity = DISEASE_SEVERITY_HARMFUL + if(5) + severity = DISEASE_SEVERITY_DANGEROUS + if(6 to INFINITY) + severity = DISEASE_SEVERITY_BIOHAZARD + else + severity = "Unknown" + + +// Will generate a random cure, the less resistance the symptoms have, the harder the cure. +/datum/disease/advance/proc/GenerateCure() + if(properties && properties.len) + var/res = CLAMP(properties["resistance"] - (symptoms.len / 2), 1, advance_cures.len) + if(res == oldres) + return + cures = list(pick(advance_cures[res])) + oldres = res + + // Get the cure name from the cure_id + var/datum/reagent/D = GLOB.chemical_reagents_list[cures[1]] + cure_text = D.name + +// Randomly generate a symptom, has a chance to lose or gain a symptom. +/datum/disease/advance/proc/Evolve(min_level, max_level, ignore_mutable = FALSE) + if(!mutable && !ignore_mutable) + return + var/s = safepick(GenerateSymptoms(min_level, max_level, 1)) + if(s) + AddSymptom(s) + Refresh(TRUE) + return + +// Randomly remove a symptom. +/datum/disease/advance/proc/Devolve(ignore_mutable = FALSE) + if(!mutable && !ignore_mutable) + return + if(symptoms.len > 1) + var/s = safepick(symptoms) + if(s) + RemoveSymptom(s) + Refresh(TRUE) + +// Randomly neuter a symptom. +/datum/disease/advance/proc/Neuter(ignore_mutable = FALSE) + if(!mutable && !ignore_mutable) + return + if(symptoms.len) + var/s = safepick(symptoms) + if(s) + NeuterSymptom(s) + Refresh(TRUE) + +// Name the disease. +/datum/disease/advance/proc/AssignName(name = "Unknown") + Refresh() + var/datum/disease/advance/A = SSdisease.archive_diseases[GetDiseaseID()] + A.name = name + for(var/datum/disease/advance/AD in SSdisease.active_diseases) + AD.Refresh() + +// Return a unique ID of the disease. +/datum/disease/advance/GetDiseaseID() + if(!id) + var/list/L = list() + for(var/datum/symptom/S in symptoms) + if(S.neutered) + L += "[S.id]N" + else + L += S.id + L = sortList(L) // Sort the list so it doesn't matter which order the symptoms are in. + var/result = jointext(L, ":") + id = result + return id + + +// Add a symptom, if it is over the limit we take a random symptom away and add the new one. +/datum/disease/advance/proc/AddSymptom(datum/symptom/S) + + if(HasSymptom(S)) + return + + if(!(symptoms.len < (VIRUS_SYMPTOM_LIMIT - 1) + rand(-1, 1))) + RemoveSymptom(pick(symptoms)) + symptoms += S + S.OnAdd(src) + +// Simply removes the symptom. +/datum/disease/advance/proc/RemoveSymptom(datum/symptom/S) + symptoms -= S + S.OnRemove(src) + +// Neuter a symptom, so it will only affect stats +/datum/disease/advance/proc/NeuterSymptom(datum/symptom/S) + if(!S.neutered) + S.neutered = TRUE + S.name += " (neutered)" + S.OnRemove(src) + +/* + + Static Procs + +*/ + +// Mix a list of advance diseases and return the mixed result. +/proc/Advance_Mix(var/list/D_list) + var/list/diseases = list() + + for(var/datum/disease/advance/A in D_list) + diseases += A.Copy() + + if(!diseases.len) + return null + if(diseases.len <= 1) + return pick(diseases) // Just return the only entry. + + var/i = 0 + // Mix our diseases until we are left with only one result. + while(i < 20 && diseases.len > 1) + + i++ + + var/datum/disease/advance/D1 = pick(diseases) + diseases -= D1 + + var/datum/disease/advance/D2 = pick(diseases) + D2.Mix(D1) + + // Should be only 1 entry left, but if not let's only return a single entry + var/datum/disease/advance/to_return = pick(diseases) + to_return.Refresh(1) + return to_return + +/proc/SetViruses(datum/reagent/R, list/data) + if(data) + var/list/preserve = list() + if(istype(data) && data["viruses"]) + for(var/datum/disease/A in data["viruses"]) + preserve += A.Copy() + R.data = data.Copy() + if(preserve.len) + R.data["viruses"] = preserve + +/proc/AdminCreateVirus(client/user) + + if(!user) + return + + var/i = VIRUS_SYMPTOM_LIMIT + + var/datum/disease/advance/D = new() + D.symptoms = list() + + var/list/symptoms = list() + symptoms += "Done" + symptoms += SSdisease.list_symptoms.Copy() + do + if(user) + var/symptom = input(user, "Choose a symptom to add ([i] remaining)", "Choose a Symptom") in symptoms + if(isnull(symptom)) + return + else if(istext(symptom)) + i = 0 + else if(ispath(symptom)) + var/datum/symptom/S = new symptom + if(!D.HasSymptom(S)) + D.symptoms += S + i -= 1 + while(i > 0) + + if(D.symptoms.len > 0) + + var/new_name = stripped_input(user, "Name your new disease.", "New Name") + if(!new_name) + return + D.AssignName(new_name) + D.Refresh() + + for(var/mob/living/carbon/human/H in shuffle(GLOB.alive_mob_list)) + if(!is_station_level(H.z)) + continue + if(!H.HasDisease(D)) + H.ForceContractDisease(D) + break + + var/list/name_symptoms = list() + for(var/datum/symptom/S in D.symptoms) + name_symptoms += S.name + message_admins("[key_name_admin(user)] has triggered a custom virus outbreak of [D.admin_details()]") + log_virus("[key_name(user)] has triggered a custom virus outbreak of [D.admin_details()]!") + +/datum/disease/advance/proc/totalStageSpeed() + return properties["stage_rate"] + +/datum/disease/advance/proc/totalStealth() + return properties["stealth"] + +/datum/disease/advance/proc/totalResistance() + return properties["resistance"] + +/datum/disease/advance/proc/totalTransmittable() + return properties["transmittable"] diff --git a/code/datums/diseases/advance/presets.dm b/code/datums/diseases/advance/presets.dm index d2c4b1983f..68c3ceffea 100644 --- a/code/datums/diseases/advance/presets.dm +++ b/code/datums/diseases/advance/presets.dm @@ -1,42 +1,42 @@ -// Cold -/datum/disease/advance/cold - copy_type = /datum/disease/advance - -/datum/disease/advance/cold/New() - name = "Cold" - symptoms = list(new/datum/symptom/sneeze) - ..() - -// Flu -/datum/disease/advance/flu - copy_type = /datum/disease/advance - -/datum/disease/advance/flu/New() - name = "Flu" - symptoms = list(new/datum/symptom/cough) - ..() - -//Randomly generated Disease, for virus crates and events -/datum/disease/advance/random - name = "Experimental Disease" - copy_type = /datum/disease/advance - -/datum/disease/advance/random/New(max_symptoms, max_level = 8) - if(!max_symptoms) - max_symptoms = rand(1, VIRUS_SYMPTOM_LIMIT) - var/list/datum/symptom/possible_symptoms = list() - for(var/symptom in subtypesof(/datum/symptom)) - var/datum/symptom/S = symptom - if(initial(S.level) > max_level) - continue - if(initial(S.level) <= 0) //unobtainable symptoms - continue - possible_symptoms += S - for(var/i in 1 to max_symptoms) - var/datum/symptom/chosen_symptom = pick_n_take(possible_symptoms) - if(chosen_symptom) - var/datum/symptom/S = new chosen_symptom - symptoms += S - Refresh() - +// Cold +/datum/disease/advance/cold + copy_type = /datum/disease/advance + +/datum/disease/advance/cold/New() + name = "Cold" + symptoms = list(new/datum/symptom/sneeze) + ..() + +// Flu +/datum/disease/advance/flu + copy_type = /datum/disease/advance + +/datum/disease/advance/flu/New() + name = "Flu" + symptoms = list(new/datum/symptom/cough) + ..() + +//Randomly generated Disease, for virus crates and events +/datum/disease/advance/random + name = "Experimental Disease" + copy_type = /datum/disease/advance + +/datum/disease/advance/random/New(max_symptoms, max_level = 8) + if(!max_symptoms) + max_symptoms = rand(1, VIRUS_SYMPTOM_LIMIT) + var/list/datum/symptom/possible_symptoms = list() + for(var/symptom in subtypesof(/datum/symptom)) + var/datum/symptom/S = symptom + if(initial(S.level) > max_level) + continue + if(initial(S.level) <= 0) //unobtainable symptoms + continue + possible_symptoms += S + for(var/i in 1 to max_symptoms) + var/datum/symptom/chosen_symptom = pick_n_take(possible_symptoms) + if(chosen_symptom) + var/datum/symptom/S = new chosen_symptom + symptoms += S + Refresh() + name = "Sample #[rand(1,10000)]" \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/beard.dm b/code/datums/diseases/advance/symptoms/beard.dm index 6b26183828..d404c95ab6 100644 --- a/code/datums/diseases/advance/symptoms/beard.dm +++ b/code/datums/diseases/advance/symptoms/beard.dm @@ -1,51 +1,51 @@ -/* -////////////////////////////////////// -Facial Hypertrichosis - - No change to stealth. - Increases resistance. - Increases speed. - Slighlty increases transmittability - Intense Level. - -BONUS - Makes the mob grow a massive beard, regardless of gender. - -////////////////////////////////////// -*/ - -/datum/symptom/beard - - name = "Facial Hypertrichosis" - desc = "The virus increases hair production significantly, causing rapid beard growth." - stealth = 0 - resistance = 3 - stage_speed = 2 - transmittable = 1 - level = 4 - severity = 1 - symptom_delay_min = 18 - symptom_delay_max = 36 - -/datum/symptom/beard/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/M = A.affected_mob - if(ishuman(M)) - var/mob/living/carbon/human/H = M - switch(A.stage) - if(1, 2) - to_chat(H, "Your chin itches.") - if(H.facial_hair_style == "Shaved") - H.facial_hair_style = "Jensen Beard" - H.update_hair() - if(3, 4) - to_chat(H, "You feel tough.") - if(!(H.facial_hair_style == "Dwarf Beard") && !(H.facial_hair_style == "Very Long Beard") && !(H.facial_hair_style == "Full Beard")) - H.facial_hair_style = "Full Beard" - H.update_hair() - else - to_chat(H, "You feel manly!") - if(!(H.facial_hair_style == "Dwarf Beard") && !(H.facial_hair_style == "Very Long Beard")) - H.facial_hair_style = pick("Dwarf Beard", "Very Long Beard") - H.update_hair() +/* +////////////////////////////////////// +Facial Hypertrichosis + + No change to stealth. + Increases resistance. + Increases speed. + Slighlty increases transmittability + Intense Level. + +BONUS + Makes the mob grow a massive beard, regardless of gender. + +////////////////////////////////////// +*/ + +/datum/symptom/beard + + name = "Facial Hypertrichosis" + desc = "The virus increases hair production significantly, causing rapid beard growth." + stealth = 0 + resistance = 3 + stage_speed = 2 + transmittable = 1 + level = 4 + severity = 1 + symptom_delay_min = 18 + symptom_delay_max = 36 + +/datum/symptom/beard/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/M = A.affected_mob + if(ishuman(M)) + var/mob/living/carbon/human/H = M + switch(A.stage) + if(1, 2) + to_chat(H, "Your chin itches.") + if(H.facial_hair_style == "Shaved") + H.facial_hair_style = "Jensen Beard" + H.update_hair() + if(3, 4) + to_chat(H, "You feel tough.") + if(!(H.facial_hair_style == "Dwarf Beard") && !(H.facial_hair_style == "Very Long Beard") && !(H.facial_hair_style == "Full Beard")) + H.facial_hair_style = "Full Beard" + H.update_hair() + else + to_chat(H, "You feel manly!") + if(!(H.facial_hair_style == "Dwarf Beard") && !(H.facial_hair_style == "Very Long Beard")) + H.facial_hair_style = pick("Dwarf Beard", "Very Long Beard") + H.update_hair() diff --git a/code/datums/diseases/advance/symptoms/choking.dm b/code/datums/diseases/advance/symptoms/choking.dm index 069c62cf3f..559d8f4754 100644 --- a/code/datums/diseases/advance/symptoms/choking.dm +++ b/code/datums/diseases/advance/symptoms/choking.dm @@ -1,148 +1,148 @@ -/* -////////////////////////////////////// - -Choking - - Very very noticable. - Lowers resistance. - Decreases stage speed. - Decreases transmittablity tremendously. - Moderate Level. - -Bonus - Inflicts spikes of oxyloss - -////////////////////////////////////// -*/ - -/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 - transmittable = -4 - level = 3 - severity = 3 - 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) - if(!..()) - return - if(A.properties["stage_rate"] >= 8) - symptom_delay_min = 7 - symptom_delay_max = 24 - if(A.properties["stealth"] >= 4) - suppress_warning = TRUE - -/datum/symptom/choking/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/M = A.affected_mob - switch(A.stage) - if(1, 2) - if(prob(base_message_chance) && !suppress_warning) - to_chat(M, "[pick("You're having difficulty breathing.", "Your breathing becomes heavy.")]") - if(3, 4) - if(!suppress_warning) - to_chat(M, "[pick("Your windpipe feels like a straw.", "Your breathing becomes tremendously difficult.")]") - else - to_chat(M, "You feel very [pick("dizzy","woozy","faint")].") //fake bloodloss messages - Choke_stage_3_4(M, A) - M.emote("gasp") - else - to_chat(M, "[pick("You're choking!", "You can't breathe!")]") - Choke(M, A) - M.emote("gasp") - -/datum/symptom/choking/proc/Choke_stage_3_4(mob/living/M, datum/disease/advance/A) - M.adjustOxyLoss(rand(6,13)) - return 1 - -/datum/symptom/choking/proc/Choke(mob/living/M, datum/disease/advance/A) - M.adjustOxyLoss(rand(10,18)) - return 1 - -/* -////////////////////////////////////// - -Asphyxiation - - Very very noticable. - Decreases stage speed. - Decreases transmittablity. - -Bonus - Inflicts large spikes of oxyloss - Introduces Asphyxiating drugs to the system - Causes cardiac arrest on dying victims. - -////////////////////////////////////// -*/ - -/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 - transmittable = -2 - level = 7 - severity = 6 - base_message_chance = 15 - symptom_delay_min = 14 - symptom_delay_max = 30 - var/paralysis = FALSE - threshold_desc = "Stage Speed 8: Additionally synthesizes pancuronium and sodium thiopental inside the host.
      \ - Transmission 8: Doubles the damage caused by the symptom." - - -/datum/symptom/asphyxiation/Start(datum/disease/advance/A) - if(!..()) - return - if(A.properties["stage_rate"] >= 8) - paralysis = TRUE - if(A.properties["transmittable"] >= 8) - power = 2 - -/datum/symptom/asphyxiation/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/M = A.affected_mob - switch(A.stage) - if(3, 4) - to_chat(M, "[pick("Your windpipe feels thin.", "Your lungs feel small.")]") - Asphyxiate_stage_3_4(M, A) - M.emote("gasp") - if(5) - to_chat(M, "[pick("Your lungs hurt!", "It hurts to breathe!")]") - Asphyxiate(M, A) - M.emote("gasp") - if(M.getOxyLoss() >= 120) - M.visible_message("[M] stops breathing, as if their lungs have totally collapsed!") - Asphyxiate_death(M, A) - return - -/datum/symptom/asphyxiation/proc/Asphyxiate_stage_3_4(mob/living/M, datum/disease/advance/A) - var/get_damage = rand(10,15) * power - M.adjustOxyLoss(get_damage) - return 1 - -/datum/symptom/asphyxiation/proc/Asphyxiate(mob/living/M, datum/disease/advance/A) - var/get_damage = rand(15,21) * power - M.adjustOxyLoss(get_damage) - if(paralysis) - M.reagents.add_reagent_list(list(/datum/reagent/toxin/pancuronium = 3, /datum/reagent/toxin/sodium_thiopental = 3)) - return 1 - -/datum/symptom/asphyxiation/proc/Asphyxiate_death(mob/living/M, datum/disease/advance/A) - var/get_damage = rand(25,35) * power - M.adjustOxyLoss(get_damage) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, get_damage/2) - return 1 +/* +////////////////////////////////////// + +Choking + + Very very noticable. + Lowers resistance. + Decreases stage speed. + Decreases transmittablity tremendously. + Moderate Level. + +Bonus + Inflicts spikes of oxyloss + +////////////////////////////////////// +*/ + +/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 + transmittable = -4 + level = 3 + severity = 3 + 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) + if(!..()) + return + if(A.properties["stage_rate"] >= 8) + symptom_delay_min = 7 + symptom_delay_max = 24 + if(A.properties["stealth"] >= 4) + suppress_warning = TRUE + +/datum/symptom/choking/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/M = A.affected_mob + switch(A.stage) + if(1, 2) + if(prob(base_message_chance) && !suppress_warning) + to_chat(M, "[pick("You're having difficulty breathing.", "Your breathing becomes heavy.")]") + if(3, 4) + if(!suppress_warning) + to_chat(M, "[pick("Your windpipe feels like a straw.", "Your breathing becomes tremendously difficult.")]") + else + to_chat(M, "You feel very [pick("dizzy","woozy","faint")].") //fake bloodloss messages + Choke_stage_3_4(M, A) + M.emote("gasp") + else + to_chat(M, "[pick("You're choking!", "You can't breathe!")]") + Choke(M, A) + M.emote("gasp") + +/datum/symptom/choking/proc/Choke_stage_3_4(mob/living/M, datum/disease/advance/A) + M.adjustOxyLoss(rand(6,13)) + return 1 + +/datum/symptom/choking/proc/Choke(mob/living/M, datum/disease/advance/A) + M.adjustOxyLoss(rand(10,18)) + return 1 + +/* +////////////////////////////////////// + +Asphyxiation + + Very very noticable. + Decreases stage speed. + Decreases transmittablity. + +Bonus + Inflicts large spikes of oxyloss + Introduces Asphyxiating drugs to the system + Causes cardiac arrest on dying victims. + +////////////////////////////////////// +*/ + +/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 + transmittable = -2 + level = 7 + severity = 6 + base_message_chance = 15 + symptom_delay_min = 14 + symptom_delay_max = 30 + var/paralysis = FALSE + threshold_desc = "Stage Speed 8: Additionally synthesizes pancuronium and sodium thiopental inside the host.
      \ + Transmission 8: Doubles the damage caused by the symptom." + + +/datum/symptom/asphyxiation/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["stage_rate"] >= 8) + paralysis = TRUE + if(A.properties["transmittable"] >= 8) + power = 2 + +/datum/symptom/asphyxiation/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/M = A.affected_mob + switch(A.stage) + if(3, 4) + to_chat(M, "[pick("Your windpipe feels thin.", "Your lungs feel small.")]") + Asphyxiate_stage_3_4(M, A) + M.emote("gasp") + if(5) + to_chat(M, "[pick("Your lungs hurt!", "It hurts to breathe!")]") + Asphyxiate(M, A) + M.emote("gasp") + if(M.getOxyLoss() >= 120) + M.visible_message("[M] stops breathing, as if their lungs have totally collapsed!") + Asphyxiate_death(M, A) + return + +/datum/symptom/asphyxiation/proc/Asphyxiate_stage_3_4(mob/living/M, datum/disease/advance/A) + var/get_damage = rand(10,15) * power + M.adjustOxyLoss(get_damage) + return 1 + +/datum/symptom/asphyxiation/proc/Asphyxiate(mob/living/M, datum/disease/advance/A) + var/get_damage = rand(15,21) * power + M.adjustOxyLoss(get_damage) + if(paralysis) + M.reagents.add_reagent_list(list(/datum/reagent/toxin/pancuronium = 3, /datum/reagent/toxin/sodium_thiopental = 3)) + return 1 + +/datum/symptom/asphyxiation/proc/Asphyxiate_death(mob/living/M, datum/disease/advance/A) + var/get_damage = rand(25,35) * power + M.adjustOxyLoss(get_damage) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, get_damage/2) + return 1 diff --git a/code/datums/diseases/advance/symptoms/confusion.dm b/code/datums/diseases/advance/symptoms/confusion.dm index 260c6888d7..eb6c5342f9 100644 --- a/code/datums/diseases/advance/symptoms/confusion.dm +++ b/code/datums/diseases/advance/symptoms/confusion.dm @@ -1,61 +1,61 @@ -/* -////////////////////////////////////// - -Confusion - - Little bit hidden. - Lowers resistance. - Decreases stage speed. - Not very transmissibile. - Intense Level. - -Bonus - Makes the affected mob be confused for short periods of time. - -////////////////////////////////////// -*/ - -/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 - transmittable = 0 - level = 4 - severity = 2 - base_message_chance = 25 - 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) - if(!..()) - return - if(A.properties["resistance"] >= 6) - brain_damage = TRUE - if(A.properties["transmittable"] >= 6) - power = 1.5 - if(A.properties["stealth"] >= 4) - suppress_warning = TRUE - -/datum/symptom/confusion/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/carbon/M = A.affected_mob - switch(A.stage) - if(1, 2, 3, 4) - if(prob(base_message_chance) && !suppress_warning) - to_chat(M, "[pick("Your head hurts.", "Your mind blanks for a moment.")]") - else - to_chat(M, "You can't think straight!") - M.confused = min(100 * power, M.confused + 8) - if(brain_damage) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * power, 80) - M.updatehealth() - - return +/* +////////////////////////////////////// + +Confusion + + Little bit hidden. + Lowers resistance. + Decreases stage speed. + Not very transmissibile. + Intense Level. + +Bonus + Makes the affected mob be confused for short periods of time. + +////////////////////////////////////// +*/ + +/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 + transmittable = 0 + level = 4 + severity = 2 + base_message_chance = 25 + 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) + if(!..()) + return + if(A.properties["resistance"] >= 6) + brain_damage = TRUE + if(A.properties["transmittable"] >= 6) + power = 1.5 + if(A.properties["stealth"] >= 4) + suppress_warning = TRUE + +/datum/symptom/confusion/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/carbon/M = A.affected_mob + switch(A.stage) + if(1, 2, 3, 4) + if(prob(base_message_chance) && !suppress_warning) + to_chat(M, "[pick("Your head hurts.", "Your mind blanks for a moment.")]") + else + to_chat(M, "You can't think straight!") + M.confused = min(100 * power, M.confused + 8) + if(brain_damage) + M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * power, 80) + M.updatehealth() + + return diff --git a/code/datums/diseases/advance/symptoms/cough.dm b/code/datums/diseases/advance/symptoms/cough.dm index e4283101f5..b1767d7cb5 100644 --- a/code/datums/diseases/advance/symptoms/cough.dm +++ b/code/datums/diseases/advance/symptoms/cough.dm @@ -1,75 +1,75 @@ -/* -////////////////////////////////////// - -Coughing - - Noticable. - Little Resistance. - Doesn't increase stage speed much. - Transmissibile. - Low Level. - -BONUS - Will force the affected mob to drop small items! - -////////////////////////////////////// -*/ - -/datum/symptom/cough - - name = "Cough" - desc = "The virus irritates the throat of the host, causing occasional coughing." - stealth = -1 - resistance = 3 - stage_speed = 1 - transmittable = 2 - level = 1 - severity = 1 - base_message_chance = 15 - 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) - if(!..()) - return - if(A.properties["stealth"] >= 4) - suppress_warning = TRUE - if(A.spread_flags &= DISEASE_SPREAD_AIRBORNE) //infect bystanders - infective = TRUE - if(A.properties["resistance"] >= 3) //strong enough to drop items - power = 1.5 - if(A.properties["resistance"] >= 10) //strong enough to stun (rarely) - power = 2 - if(A.properties["stage_rate"] >= 6) //cough more often - symptom_delay_max = 10 - -/datum/symptom/cough/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/M = A.affected_mob - switch(A.stage) - if(1, 2, 3) - if(prob(base_message_chance) && !suppress_warning) - to_chat(M, "[pick("You swallow excess mucus.", "You lightly cough.")]") - else - M.emote("cough") - if(power >= 1.5) - var/obj/item/I = M.get_active_held_item() - if(I && I.w_class == WEIGHT_CLASS_TINY) - M.dropItemToGround(I) - if(power >= 2 && prob(10)) - to_chat(M, "[pick("You have a coughing fit!", "You can't stop coughing!")]") - M.Stun(20) - M.emote("cough") - addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 6) - addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 12) - addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 18) - if(infective && M.CanSpreadAirborneDisease()) - A.spread(1) - +/* +////////////////////////////////////// + +Coughing + + Noticable. + Little Resistance. + Doesn't increase stage speed much. + Transmissibile. + Low Level. + +BONUS + Will force the affected mob to drop small items! + +////////////////////////////////////// +*/ + +/datum/symptom/cough + + name = "Cough" + desc = "The virus irritates the throat of the host, causing occasional coughing." + stealth = -1 + resistance = 3 + stage_speed = 1 + transmittable = 2 + level = 1 + severity = 1 + base_message_chance = 15 + 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) + if(!..()) + return + if(A.properties["stealth"] >= 4) + suppress_warning = TRUE + if(A.spread_flags &= DISEASE_SPREAD_AIRBORNE) //infect bystanders + infective = TRUE + if(A.properties["resistance"] >= 3) //strong enough to drop items + power = 1.5 + if(A.properties["resistance"] >= 10) //strong enough to stun (rarely) + power = 2 + if(A.properties["stage_rate"] >= 6) //cough more often + symptom_delay_max = 10 + +/datum/symptom/cough/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/M = A.affected_mob + switch(A.stage) + if(1, 2, 3) + if(prob(base_message_chance) && !suppress_warning) + to_chat(M, "[pick("You swallow excess mucus.", "You lightly cough.")]") + else + M.emote("cough") + if(power >= 1.5) + var/obj/item/I = M.get_active_held_item() + if(I && I.w_class == WEIGHT_CLASS_TINY) + M.dropItemToGround(I) + if(power >= 2 && prob(10)) + to_chat(M, "[pick("You have a coughing fit!", "You can't stop coughing!")]") + M.Stun(20) + M.emote("cough") + addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 6) + addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 12) + addtimer(CALLBACK(M, /mob/.proc/emote, "cough"), 18) + if(infective && M.CanSpreadAirborneDisease()) + A.spread(1) + diff --git a/code/datums/diseases/advance/symptoms/deafness.dm b/code/datums/diseases/advance/symptoms/deafness.dm index 3718104b48..e0336506e3 100644 --- a/code/datums/diseases/advance/symptoms/deafness.dm +++ b/code/datums/diseases/advance/symptoms/deafness.dm @@ -1,59 +1,59 @@ -/* -////////////////////////////////////// - -Deafness - - Slightly noticable. - Lowers resistance. - Decreases stage speed slightly. - Decreases transmittablity. - Intense Level. - -Bonus - Causes intermittent loss of hearing. - -////////////////////////////////////// -*/ - -/datum/symptom/deafness - - name = "Deafness" - desc = "The virus causes inflammation of the eardrums, causing intermittent deafness." - stealth = -1 - resistance = -2 - stage_speed = -1 - transmittable = -3 - level = 4 - severity = 4 - 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) - if(!..()) - return - if(A.properties["stealth"] >= 4) - suppress_warning = TRUE - if(A.properties["resistance"] >= 9) //permanent deafness - power = 2 - -/datum/symptom/deafness/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/carbon/M = A.affected_mob - switch(A.stage) - if(3, 4) - if(prob(base_message_chance) && !suppress_warning) - to_chat(M, "[pick("You hear a ringing in your ear.", "Your ears pop.")]") - if(5) - if(power > 2) - var/obj/item/organ/ears/ears = M.getorganslot(ORGAN_SLOT_EARS) - if(istype(ears) && ears.damage < ears.maxHealth) - to_chat(M, "Your ears pop painfully and start bleeding!") - ears.damage = max(ears.damage, ears.maxHealth) - M.emote("scream") - else - to_chat(M, "Your ears pop and begin ringing loudly!") - M.minimumDeafTicks(20) +/* +////////////////////////////////////// + +Deafness + + Slightly noticable. + Lowers resistance. + Decreases stage speed slightly. + Decreases transmittablity. + Intense Level. + +Bonus + Causes intermittent loss of hearing. + +////////////////////////////////////// +*/ + +/datum/symptom/deafness + + name = "Deafness" + desc = "The virus causes inflammation of the eardrums, causing intermittent deafness." + stealth = -1 + resistance = -2 + stage_speed = -1 + transmittable = -3 + level = 4 + severity = 4 + 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) + if(!..()) + return + if(A.properties["stealth"] >= 4) + suppress_warning = TRUE + if(A.properties["resistance"] >= 9) //permanent deafness + power = 2 + +/datum/symptom/deafness/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/carbon/M = A.affected_mob + switch(A.stage) + if(3, 4) + if(prob(base_message_chance) && !suppress_warning) + to_chat(M, "[pick("You hear a ringing in your ear.", "Your ears pop.")]") + if(5) + if(power > 2) + var/obj/item/organ/ears/ears = M.getorganslot(ORGAN_SLOT_EARS) + if(istype(ears) && ears.damage < ears.maxHealth) + to_chat(M, "Your ears pop painfully and start bleeding!") + ears.damage = max(ears.damage, ears.maxHealth) + M.emote("scream") + else + to_chat(M, "Your ears pop and begin ringing loudly!") + M.minimumDeafTicks(20) diff --git a/code/datums/diseases/advance/symptoms/dizzy.dm b/code/datums/diseases/advance/symptoms/dizzy.dm index c7f7198f6b..b4b06be5ac 100644 --- a/code/datums/diseases/advance/symptoms/dizzy.dm +++ b/code/datums/diseases/advance/symptoms/dizzy.dm @@ -1,53 +1,53 @@ -/* -////////////////////////////////////// - -Dizziness - - Hidden. - Lowers resistance considerably. - Decreases stage speed. - Reduced transmittability - Intense Level. - -Bonus - Shakes the affected mob's screen for short periods. - -////////////////////////////////////// -*/ - -/datum/symptom/dizzy // Not the egg - - name = "Dizziness" - desc = "The virus causes inflammation of the vestibular system, leading to bouts of dizziness." - resistance = -2 - stage_speed = -3 - transmittable = -1 - level = 4 - severity = 2 - 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) - if(!..()) - return - if(A.properties["stealth"] >= 4) - suppress_warning = TRUE - if(A.properties["transmittable"] >= 6) //druggy - power = 2 - -/datum/symptom/dizzy/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/M = A.affected_mob - switch(A.stage) - if(1, 2, 3, 4) - if(prob(base_message_chance) && !suppress_warning) - to_chat(M, "[pick("You feel dizzy.", "Your head spins.")]") - else - to_chat(M, "A wave of dizziness washes over you!") - M.Dizzy(5) - if(power >= 2) +/* +////////////////////////////////////// + +Dizziness + + Hidden. + Lowers resistance considerably. + Decreases stage speed. + Reduced transmittability + Intense Level. + +Bonus + Shakes the affected mob's screen for short periods. + +////////////////////////////////////// +*/ + +/datum/symptom/dizzy // Not the egg + + name = "Dizziness" + desc = "The virus causes inflammation of the vestibular system, leading to bouts of dizziness." + resistance = -2 + stage_speed = -3 + transmittable = -1 + level = 4 + severity = 2 + 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) + if(!..()) + return + if(A.properties["stealth"] >= 4) + suppress_warning = TRUE + if(A.properties["transmittable"] >= 6) //druggy + power = 2 + +/datum/symptom/dizzy/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/M = A.affected_mob + switch(A.stage) + if(1, 2, 3, 4) + if(prob(base_message_chance) && !suppress_warning) + to_chat(M, "[pick("You feel dizzy.", "Your head spins.")]") + else + to_chat(M, "A wave of dizziness washes over you!") + M.Dizzy(5) + if(power >= 2) M.set_drugginess(5) \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/fever.dm b/code/datums/diseases/advance/symptoms/fever.dm index 5424e28502..a178cba196 100644 --- a/code/datums/diseases/advance/symptoms/fever.dm +++ b/code/datums/diseases/advance/symptoms/fever.dm @@ -1,60 +1,60 @@ -/* -////////////////////////////////////// - -Fever - - No change to hidden. - Increases resistance. - Increases stage speed. - Little transmittable. - Low level. - -Bonus - Heats up your body. - -////////////////////////////////////// -*/ - -/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 - transmittable = 2 - level = 2 - severity = 2 - base_message_chance = 20 - 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) - if(!..()) - return - if(A.properties["resistance"] >= 5) //dangerous fever - power = 1.5 - unsafe = TRUE - if(A.properties["resistance"] >= 10) - power = 2.5 - -/datum/symptom/fever/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/carbon/M = A.affected_mob - if(!unsafe || A.stage < 4) - to_chat(M, "[pick("You feel hot.", "You feel like you're burning.")]") - else - to_chat(M, "[pick("You feel too hot.", "You feel like your blood is boiling.")]") - if(M.bodytemperature < BODYTEMP_HEAT_DAMAGE_LIMIT || unsafe) - Heat(M, A) - -/datum/symptom/fever/proc/Heat(mob/living/M, datum/disease/advance/A) - var/get_heat = 6 * power - if(!unsafe) - M.adjust_bodytemperature(get_heat * A.stage, 0, BODYTEMP_HEAT_DAMAGE_LIMIT - 1) - else - M.adjust_bodytemperature(get_heat * A.stage) - return 1 +/* +////////////////////////////////////// + +Fever + + No change to hidden. + Increases resistance. + Increases stage speed. + Little transmittable. + Low level. + +Bonus + Heats up your body. + +////////////////////////////////////// +*/ + +/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 + transmittable = 2 + level = 2 + severity = 2 + base_message_chance = 20 + 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) + if(!..()) + return + if(A.properties["resistance"] >= 5) //dangerous fever + power = 1.5 + unsafe = TRUE + if(A.properties["resistance"] >= 10) + power = 2.5 + +/datum/symptom/fever/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/carbon/M = A.affected_mob + if(!unsafe || A.stage < 4) + to_chat(M, "[pick("You feel hot.", "You feel like you're burning.")]") + else + to_chat(M, "[pick("You feel too hot.", "You feel like your blood is boiling.")]") + if(M.bodytemperature < BODYTEMP_HEAT_DAMAGE_LIMIT || unsafe) + Heat(M, A) + +/datum/symptom/fever/proc/Heat(mob/living/M, datum/disease/advance/A) + var/get_heat = 6 * power + if(!unsafe) + M.adjust_bodytemperature(get_heat * A.stage, 0, BODYTEMP_HEAT_DAMAGE_LIMIT - 1) + else + M.adjust_bodytemperature(get_heat * A.stage) + return 1 diff --git a/code/datums/diseases/advance/symptoms/flesh_eating.dm b/code/datums/diseases/advance/symptoms/flesh_eating.dm index d1e9d3fdca..48668afc90 100644 --- a/code/datums/diseases/advance/symptoms/flesh_eating.dm +++ b/code/datums/diseases/advance/symptoms/flesh_eating.dm @@ -1,130 +1,130 @@ -/* -////////////////////////////////////// - -Necrotizing Fasciitis (AKA Flesh-Eating Disease) - - Very very noticable. - Lowers resistance tremendously. - No changes to stage speed. - Decreases transmittablity temrendously. - Fatal Level. - -Bonus - Deals brute damage over time. - -////////////////////////////////////// -*/ - -/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 - transmittable = -4 - level = 6 - severity = 5 - base_message_chance = 50 - symptom_delay_min = 15 - 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) - if(!..()) - return - if(A.properties["resistance"] >= 7) //extra bleeding - bleed = TRUE - if(A.properties["transmittable"] >= 8) //extra stamina damage - pain = TRUE - -/datum/symptom/flesh_eating/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/M = A.affected_mob - switch(A.stage) - if(2,3) - if(prob(base_message_chance)) - to_chat(M, "[pick("You feel a sudden pain across your body.", "Drops of blood appear suddenly on your skin.")]") - if(4,5) - to_chat(M, "[pick("You cringe as a violent pain takes over your body.", "It feels like your body is eating itself inside out.", "IT HURTS.")]") - Flesheat(M, A) - -/datum/symptom/flesh_eating/proc/Flesheat(mob/living/M, datum/disease/advance/A) - var/get_damage = rand(15,25) * power - M.adjustBruteLoss(get_damage) - if(pain) - M.adjustStaminaLoss(get_damage) - if(bleed) - if(ishuman(M)) - var/mob/living/carbon/human/H = M - H.bleed_rate += 5 * power - return 1 - -/* -////////////////////////////////////// - -Autophagocytosis (AKA Programmed mass cell death) - - Very noticable. - Lowers resistance. - Fast stage speed. - Decreases transmittablity. - Fatal Level. - -Bonus - Deals brute damage over time. - -////////////////////////////////////// -*/ - -/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 - transmittable = -2 - level = 7 - severity = 6 - base_message_chance = 50 - symptom_delay_min = 3 - 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) - if(!..()) - return - if(A.properties["stealth"] >= 5) - suppress_warning = TRUE - if(A.properties["stage_rate"] >= 7) //bleeding and hunger - chems = TRUE - -/datum/symptom/flesh_death/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/M = A.affected_mob - switch(A.stage) - if(2,3) - if(prob(base_message_chance) && !suppress_warning) - to_chat(M, "[pick("You feel your body break apart.", "Your skin rubs off like dust.")]") - if(4,5) - if(prob(base_message_chance / 2)) //reduce spam - to_chat(M, "[pick("You feel your muscles weakening.", "Some of your skin detaches itself.", "You feel sandy.")]") - Flesh_death(M, A) - -/datum/symptom/flesh_death/proc/Flesh_death(mob/living/M, datum/disease/advance/A) - var/get_damage = rand(6,10) - M.adjustBruteLoss(get_damage) - if(chems) - M.reagents.add_reagent_list(list(/datum/reagent/toxin/heparin = 2, /datum/reagent/toxin/lipolicide = 2)) - if(zombie) - M.reagents.add_reagent(/datum/reagent/romerol, 1) +/* +////////////////////////////////////// + +Necrotizing Fasciitis (AKA Flesh-Eating Disease) + + Very very noticable. + Lowers resistance tremendously. + No changes to stage speed. + Decreases transmittablity temrendously. + Fatal Level. + +Bonus + Deals brute damage over time. + +////////////////////////////////////// +*/ + +/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 + transmittable = -4 + level = 6 + severity = 5 + base_message_chance = 50 + symptom_delay_min = 15 + 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) + if(!..()) + return + if(A.properties["resistance"] >= 7) //extra bleeding + bleed = TRUE + if(A.properties["transmittable"] >= 8) //extra stamina damage + pain = TRUE + +/datum/symptom/flesh_eating/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/M = A.affected_mob + switch(A.stage) + if(2,3) + if(prob(base_message_chance)) + to_chat(M, "[pick("You feel a sudden pain across your body.", "Drops of blood appear suddenly on your skin.")]") + if(4,5) + to_chat(M, "[pick("You cringe as a violent pain takes over your body.", "It feels like your body is eating itself inside out.", "IT HURTS.")]") + Flesheat(M, A) + +/datum/symptom/flesh_eating/proc/Flesheat(mob/living/M, datum/disease/advance/A) + var/get_damage = rand(15,25) * power + M.adjustBruteLoss(get_damage) + if(pain) + M.adjustStaminaLoss(get_damage) + if(bleed) + if(ishuman(M)) + var/mob/living/carbon/human/H = M + H.bleed_rate += 5 * power + return 1 + +/* +////////////////////////////////////// + +Autophagocytosis (AKA Programmed mass cell death) + + Very noticable. + Lowers resistance. + Fast stage speed. + Decreases transmittablity. + Fatal Level. + +Bonus + Deals brute damage over time. + +////////////////////////////////////// +*/ + +/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 + transmittable = -2 + level = 7 + severity = 6 + base_message_chance = 50 + symptom_delay_min = 3 + 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) + if(!..()) + return + if(A.properties["stealth"] >= 5) + suppress_warning = TRUE + if(A.properties["stage_rate"] >= 7) //bleeding and hunger + chems = TRUE + +/datum/symptom/flesh_death/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/M = A.affected_mob + switch(A.stage) + if(2,3) + if(prob(base_message_chance) && !suppress_warning) + to_chat(M, "[pick("You feel your body break apart.", "Your skin rubs off like dust.")]") + if(4,5) + if(prob(base_message_chance / 2)) //reduce spam + to_chat(M, "[pick("You feel your muscles weakening.", "Some of your skin detaches itself.", "You feel sandy.")]") + Flesh_death(M, A) + +/datum/symptom/flesh_death/proc/Flesh_death(mob/living/M, datum/disease/advance/A) + var/get_damage = rand(6,10) + M.adjustBruteLoss(get_damage) + if(chems) + M.reagents.add_reagent_list(list(/datum/reagent/toxin/heparin = 2, /datum/reagent/toxin/lipolicide = 2)) + if(zombie) + M.reagents.add_reagent(/datum/reagent/romerol, 1) return 1 \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/genetics.dm b/code/datums/diseases/advance/symptoms/genetics.dm index c01fccee13..7f21b03dff 100644 --- a/code/datums/diseases/advance/symptoms/genetics.dm +++ b/code/datums/diseases/advance/symptoms/genetics.dm @@ -1,78 +1,78 @@ -/* -////////////////////////////////////// - -DNA Saboteur - - Very noticable. - Lowers resistance tremendously. - No changes to stage speed. - Decreases transmittablity tremendously. - Fatal Level. - -Bonus - Cleans the DNA of a person and then randomly gives them a trait. - -////////////////////////////////////// -*/ - -/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 - transmittable = -3 - level = 6 - severity = 4 - var/list/possible_mutations - var/archived_dna = null - base_message_chance = 50 - 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(!..()) - return - var/mob/living/carbon/C = A.affected_mob - if(!C.has_dna()) - return - switch(A.stage) - if(4, 5) - to_chat(C, "[pick("Your skin feels itchy.", "You feel light headed.")]") - C.dna.remove_mutation_group(possible_mutations) - for(var/i in 1 to power) - C.randmut(possible_mutations) - -// Archive their DNA before they were infected. -/datum/symptom/genetic_mutation/Start(datum/disease/advance/A) - if(!..()) - return - if(A.properties["stealth"] >= 5) //don't restore dna after curing - no_reset = TRUE - if(A.properties["stage_rate"] >= 10) //mutate more often - symptom_delay_min = 20 - symptom_delay_max = 60 - if(A.properties["resistance"] >= 8) //mutate twice - power = 2 - possible_mutations = (GLOB.bad_mutations | GLOB.not_good_mutations) - GLOB.mutations_list[RACEMUT] - var/mob/living/carbon/M = A.affected_mob - if(M) - if(!M.has_dna()) - return - archived_dna = M.dna.struc_enzymes - -// Give them back their old DNA when cured. -/datum/symptom/genetic_mutation/End(datum/disease/advance/A) - if(!..()) - return - if(!no_reset) - var/mob/living/carbon/M = A.affected_mob - if(M && archived_dna) - if(!M.has_dna()) - return - M.dna.struc_enzymes = archived_dna - M.domutcheck() +/* +////////////////////////////////////// + +DNA Saboteur + + Very noticable. + Lowers resistance tremendously. + No changes to stage speed. + Decreases transmittablity tremendously. + Fatal Level. + +Bonus + Cleans the DNA of a person and then randomly gives them a trait. + +////////////////////////////////////// +*/ + +/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 + transmittable = -3 + level = 6 + severity = 4 + var/list/possible_mutations + var/archived_dna = null + base_message_chance = 50 + 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(!..()) + return + var/mob/living/carbon/C = A.affected_mob + if(!C.has_dna()) + return + switch(A.stage) + if(4, 5) + to_chat(C, "[pick("Your skin feels itchy.", "You feel light headed.")]") + C.dna.remove_mutation_group(possible_mutations) + for(var/i in 1 to power) + C.randmut(possible_mutations) + +// Archive their DNA before they were infected. +/datum/symptom/genetic_mutation/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["stealth"] >= 5) //don't restore dna after curing + no_reset = TRUE + if(A.properties["stage_rate"] >= 10) //mutate more often + symptom_delay_min = 20 + symptom_delay_max = 60 + if(A.properties["resistance"] >= 8) //mutate twice + power = 2 + possible_mutations = (GLOB.bad_mutations | GLOB.not_good_mutations) - GLOB.mutations_list[RACEMUT] + var/mob/living/carbon/M = A.affected_mob + if(M) + if(!M.has_dna()) + return + archived_dna = M.dna.struc_enzymes + +// Give them back their old DNA when cured. +/datum/symptom/genetic_mutation/End(datum/disease/advance/A) + if(!..()) + return + if(!no_reset) + var/mob/living/carbon/M = A.affected_mob + if(M && archived_dna) + if(!M.has_dna()) + return + M.dna.struc_enzymes = archived_dna + M.domutcheck() diff --git a/code/datums/diseases/advance/symptoms/hallucigen.dm b/code/datums/diseases/advance/symptoms/hallucigen.dm index 39ecc61956..873d960524 100644 --- a/code/datums/diseases/advance/symptoms/hallucigen.dm +++ b/code/datums/diseases/advance/symptoms/hallucigen.dm @@ -1,65 +1,65 @@ -/* -////////////////////////////////////// - -Hallucigen - - Very noticable. - Lowers resistance considerably. - Decreases stage speed. - Reduced transmittable. - Critical Level. - -Bonus - Makes the affected mob be hallucinated for short periods of time. - -////////////////////////////////////// -*/ - -/datum/symptom/hallucigen - name = "Hallucigen" - desc = "The virus stimulates the brain, causing occasional hallucinations." - stealth = -2 - resistance = -3 - stage_speed = -3 - transmittable = -1 - level = 5 - severity = 2 - base_message_chance = 25 - 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) - if(!..()) - return - if(A.properties["stealth"] >= 4) //fake good symptom messages - fake_healthy = TRUE - base_message_chance = 50 - if(A.properties["stage_rate"] >= 7) //stronger hallucinations - power = 2 - -/datum/symptom/hallucigen/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/carbon/M = A.affected_mob - var/list/healthy_messages = list("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.",\ - "Your eyes feel great.", "You are now blinking manually.", "You don't feel the need to blink.") - switch(A.stage) - if(1, 2) - if(prob(base_message_chance)) - if(!fake_healthy) - to_chat(M, "[pick("Something appears in your peripheral vision, then winks out.", "You hear a faint whisper with no source.", "Your head aches.")]") - else - to_chat(M, "[pick(healthy_messages)]") - if(3, 4) - if(prob(base_message_chance)) - if(!fake_healthy) - to_chat(M, "[pick("Something is following you.", "You are being watched.", "You hear a whisper in your ear.", "Thumping footsteps slam toward you from nowhere.")]") - else - to_chat(M, "[pick(healthy_messages)]") - else - if(prob(base_message_chance)) - to_chat(M, "[pick("Oh, your head...", "Your head pounds.", "They're everywhere! Run!", "Something in the shadows...")]") - M.hallucination += (45 * power) +/* +////////////////////////////////////// + +Hallucigen + + Very noticable. + Lowers resistance considerably. + Decreases stage speed. + Reduced transmittable. + Critical Level. + +Bonus + Makes the affected mob be hallucinated for short periods of time. + +////////////////////////////////////// +*/ + +/datum/symptom/hallucigen + name = "Hallucigen" + desc = "The virus stimulates the brain, causing occasional hallucinations." + stealth = -2 + resistance = -3 + stage_speed = -3 + transmittable = -1 + level = 5 + severity = 2 + base_message_chance = 25 + 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) + if(!..()) + return + if(A.properties["stealth"] >= 4) //fake good symptom messages + fake_healthy = TRUE + base_message_chance = 50 + if(A.properties["stage_rate"] >= 7) //stronger hallucinations + power = 2 + +/datum/symptom/hallucigen/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/carbon/M = A.affected_mob + var/list/healthy_messages = list("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.",\ + "Your eyes feel great.", "You are now blinking manually.", "You don't feel the need to blink.") + switch(A.stage) + if(1, 2) + if(prob(base_message_chance)) + if(!fake_healthy) + to_chat(M, "[pick("Something appears in your peripheral vision, then winks out.", "You hear a faint whisper with no source.", "Your head aches.")]") + else + to_chat(M, "[pick(healthy_messages)]") + if(3, 4) + if(prob(base_message_chance)) + if(!fake_healthy) + to_chat(M, "[pick("Something is following you.", "You are being watched.", "You hear a whisper in your ear.", "Thumping footsteps slam toward you from nowhere.")]") + else + to_chat(M, "[pick(healthy_messages)]") + else + if(prob(base_message_chance)) + to_chat(M, "[pick("Oh, your head...", "Your head pounds.", "They're everywhere! Run!", "Something in the shadows...")]") + M.hallucination += (45 * power) diff --git a/code/datums/diseases/advance/symptoms/headache.dm b/code/datums/diseases/advance/symptoms/headache.dm index 973de1455b..72b03000ed 100644 --- a/code/datums/diseases/advance/symptoms/headache.dm +++ b/code/datums/diseases/advance/symptoms/headache.dm @@ -1,60 +1,60 @@ -/* -////////////////////////////////////// - -Headache - - Noticable. - Highly resistant. - Increases stage speed. - Not transmittable. - Low Level. - -BONUS - Displays an annoying message! - Should be used for buffing your disease. - -////////////////////////////////////// -*/ - -/datum/symptom/headache - - name = "Headache" - desc = "The virus causes inflammation inside the brain, causing constant headaches." - stealth = -1 - resistance = 4 - stage_speed = 2 - transmittable = 0 - level = 1 - severity = 1 - 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) - if(!..()) - return - if(A.properties["stealth"] >= 4) - base_message_chance = 50 - if(A.properties["stage_rate"] >= 6) //severe pain - power = 2 - if(A.properties["stage_rate"] >= 9) //cluster headaches - symptom_delay_min = 30 - symptom_delay_max = 60 - power = 3 - -/datum/symptom/headache/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/M = A.affected_mob - if(power < 2) - if(prob(base_message_chance) || A.stage >=4) - to_chat(M, "[pick("Your head hurts.", "Your head pounds.")]") - 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 && 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!")]") +/* +////////////////////////////////////// + +Headache + + Noticable. + Highly resistant. + Increases stage speed. + Not transmittable. + Low Level. + +BONUS + Displays an annoying message! + Should be used for buffing your disease. + +////////////////////////////////////// +*/ + +/datum/symptom/headache + + name = "Headache" + desc = "The virus causes inflammation inside the brain, causing constant headaches." + stealth = -1 + resistance = 4 + stage_speed = 2 + transmittable = 0 + level = 1 + severity = 1 + 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) + if(!..()) + return + if(A.properties["stealth"] >= 4) + base_message_chance = 50 + if(A.properties["stage_rate"] >= 6) //severe pain + power = 2 + if(A.properties["stage_rate"] >= 9) //cluster headaches + symptom_delay_min = 30 + symptom_delay_max = 60 + power = 3 + +/datum/symptom/headache/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/M = A.affected_mob + if(power < 2) + if(prob(base_message_chance) || A.stage >=4) + to_chat(M, "[pick("Your head hurts.", "Your head pounds.")]") + 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 && 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 d41e0bf225..c1b3526f41 100644 --- a/code/datums/diseases/advance/symptoms/heal.dm +++ b/code/datums/diseases/advance/symptoms/heal.dm @@ -1,485 +1,485 @@ -/datum/symptom/heal - name = "Basic Healing (does nothing)" //warning for adminspawn viruses - desc = "You should not be seeing this." - stealth = 0 - resistance = 0 - stage_speed = 0 - transmittable = 0 - level = 0 //not obtainable - base_message_chance = 20 //here used for the overlays - symptom_delay_min = 1 - symptom_delay_max = 1 - var/passive_message = "" //random message to infected but not actively healing people - threshold_desc = "Stage Speed 6: Doubles healing speed.
      \ - Stealth 4: Healing will no longer be visible to onlookers." - -/datum/symptom/heal/Start(datum/disease/advance/A) - if(!..()) - return - if(A.properties["stage_rate"] >= 6) //stronger healing - power = 2 - -/datum/symptom/heal/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/M = A.affected_mob - switch(A.stage) - if(4, 5) - var/effectiveness = CanHeal(A) - if(!effectiveness) - if(passive_message && prob(2) && passive_message_condition(M)) - to_chat(M, passive_message) - return - else - Heal(M, A, effectiveness) - return - -/datum/symptom/heal/proc/CanHeal(datum/disease/advance/A) - return power - -/datum/symptom/heal/proc/Heal(mob/living/M, datum/disease/advance/A, actual_power) - return TRUE - -/datum/symptom/heal/proc/passive_message_condition(mob/living/M) - return TRUE - - -/datum/symptom/heal/starlight - name = "Starlight Condensation" - desc = "The virus reacts to direct starlight, producing regenerative chemicals. Works best against toxin-based damage." - stealth = -1 - resistance = -2 - stage_speed = 0 - transmittable = 1 - level = 6 - passive_message = "You miss the feeling of starlight on your skin." - var/nearspace_penalty = 0.3 - threshold_desc = "Stage Speed 6: Increases healing speed.
      \ - Transmission 6: Removes penalty for only being close to space." - -/datum/symptom/heal/starlight/Start(datum/disease/advance/A) - if(!..()) - return - if(A.properties["transmittable"] >= 6) - nearspace_penalty = 1 - if(A.properties["stage_rate"] >= 6) - power = 2 - -/datum/symptom/heal/starlight/CanHeal(datum/disease/advance/A) - var/mob/living/M = A.affected_mob - if(istype(get_turf(M), /turf/open/space)) - return power - else - for(var/turf/T in view(M, 2)) - if(istype(T, /turf/open/space)) - return power * nearspace_penalty - -/datum/symptom/heal/starlight/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) - var/heal_amt = actual_power - if(M.getToxLoss() && prob(5)) - to_chat(M, "Your skin tingles as the starlight seems to heal you.") - - M.adjustToxLoss(-(4 * heal_amt), forced = TRUE) //most effective on toxins - - var/list/parts = M.get_damaged_bodyparts(1,1) - - if(!parts.len) - return - - for(var/obj/item/bodypart/L in parts) - if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len)) - M.update_damage_overlays() - return 1 - -/datum/symptom/heal/starlight/passive_message_condition(mob/living/M) - if(M.getBruteLoss() || M.getFireLoss() || M.getToxLoss()) - return TRUE - return FALSE - -/datum/symptom/heal/chem - name = "Toxolysis" - stealth = 0 - resistance = -2 - stage_speed = 2 - transmittable = -2 - level = 7 - var/food_conversion = FALSE - desc = "The virus rapidly breaks down any foreign chemicals in the bloodstream." - threshold_desc = "Resistance 7: Increases chem removal speed.
      \ - Stage Speed 6: Consumed chemicals nourish the host." - -/datum/symptom/heal/chem/Start(datum/disease/advance/A) - if(!..()) - return - if(A.properties["stage_rate"] >= 6) - food_conversion = TRUE - if(A.properties["resistance"] >= 7) - power = 2 - -/datum/symptom/heal/chem/Heal(mob/living/M, datum/disease/advance/A, actual_power) - for(var/E in M.reagents.reagent_list) //Not just toxins! - var/datum/reagent/R = E - M.reagents.remove_reagent(R.type, actual_power) - if(food_conversion) - M.nutrition += 0.3 - if(prob(2)) - to_chat(M, "You feel a mild warmth as your blood purifies itself.") - return 1 - - - -/datum/symptom/heal/metabolism - name = "Metabolic Boost" - stealth = -1 - resistance = -2 - stage_speed = 2 - transmittable = 1 - level = 7 - var/triple_metabolism = FALSE - var/reduced_hunger = FALSE - desc = "The virus causes the host's metabolism to accelerate rapidly, making them process chemicals twice as fast,\ - but also causing increased hunger." - threshold_desc = "Stealth 3: Reduces hunger rate.
      \ - Stage Speed 10: Chemical metabolization is tripled instead of doubled." - -/datum/symptom/heal/metabolism/Start(datum/disease/advance/A) - if(!..()) - return - if(A.properties["stage_rate"] >= 10) - triple_metabolism = TRUE - if(A.properties["stealth"] >= 3) - reduced_hunger = TRUE - -/datum/symptom/heal/metabolism/Heal(mob/living/carbon/C, datum/disease/advance/A, actual_power) - if(!istype(C)) - return - C.reagents.metabolize(C, can_overdose=TRUE) //this works even without a liver; it's intentional since the virus is metabolizing by itself - if(triple_metabolism) - C.reagents.metabolize(C, can_overdose=TRUE) - C.overeatduration = max(C.overeatduration - 2, 0) - var/lost_nutrition = 9 - (reduced_hunger * 5) - C.nutrition = max(C.nutrition - (lost_nutrition * HUNGER_FACTOR), 0) //Hunger depletes at 10x the normal speed - if(prob(2)) - to_chat(C, "You feel an odd gurgle in your stomach, as if it was working much faster than normal.") - return 1 - -/datum/symptom/heal/darkness - name = "Nocturnal Regeneration" - desc = "The virus is able to mend the host's flesh when in conditions of low light, repairing physical damage. More effective against brute damage." - stealth = 2 - resistance = -1 - stage_speed = -2 - transmittable = -1 - level = 6 - passive_message = "You feel tingling on your skin as light passes over it." - threshold_desc = "Stage Speed 8: Doubles healing speed." - -/datum/symptom/heal/darkness/Start(datum/disease/advance/A) - if(!..()) - return - if(A.properties["stage_rate"] >= 8) - power = 2 - -/datum/symptom/heal/darkness/CanHeal(datum/disease/advance/A) - var/mob/living/M = A.affected_mob - var/light_amount = 0 - if(isturf(M.loc)) //else, there's considered to be no light - var/turf/T = M.loc - light_amount = min(1,T.get_lumcount()) - 0.5 - if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD) - return power - -/datum/symptom/heal/darkness/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) - var/heal_amt = 2 * actual_power - - var/list/parts = M.get_damaged_bodyparts(1,1) - - if(!parts.len) - return - - if(prob(5)) - to_chat(M, "The darkness soothes and mends your wounds.") - - for(var/obj/item/bodypart/L in parts) - if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len * 0.5)) //more effective on brute - M.update_damage_overlays() - return 1 - -/datum/symptom/heal/darkness/passive_message_condition(mob/living/M) - if(M.getBruteLoss() || M.getFireLoss()) - return TRUE - return FALSE - -/datum/symptom/heal/coma - name = "Regenerative Coma" - desc = "The virus causes the host to fall into a death-like coma when severely damaged, then rapidly fixes the damage." - stealth = 0 - resistance = 2 - stage_speed = -3 - transmittable = -2 - level = 8 - passive_message = "The pain from your wounds makes you feel oddly sleepy..." - var/deathgasp = FALSE - var/stabilize = FALSE - var/active_coma = FALSE //to prevent multiple coma procs - threshold_desc = "Stealth 2: Host appears to die when falling into a coma.
      \ - Resistance 4: The virus also stabilizes the host while they are in critical condition.
      \ - Stage Speed 7: Increases healing speed." - -/datum/symptom/heal/coma/Start(datum/disease/advance/A) - if(!..()) - return - if(A.properties["stage_rate"] >= 7) - power = 1.5 - if(A.properties["resistance"] >= 4) - stabilize = TRUE - if(A.properties["stealth"] >= 2) - deathgasp = TRUE - -/datum/symptom/heal/coma/on_stage_change(datum/disease/advance/A) //mostly copy+pasted from the code for self-respiration's TRAIT_NOBREATH stuff - if(!..()) - return FALSE - if(A.stage >= 4 && stabilize) - ADD_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT) - else - REMOVE_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT) - return TRUE - -/datum/symptom/heal/coma/End(datum/disease/advance/A) - if(!..()) - return - REMOVE_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT) - -/datum/symptom/heal/coma/CanHeal(datum/disease/advance/A) - var/mob/living/M = A.affected_mob - if(HAS_TRAIT(M, TRAIT_DEATHCOMA)) - return power - else if(M.IsUnconscious() || M.stat == UNCONSCIOUS) - return power * 0.9 - else if(M.stat == SOFT_CRIT) - return power * 0.5 - else if(M.IsSleeping()) - return power * 0.25 - else if(M.getBruteLoss() + M.getFireLoss() >= 70 && !active_coma) - to_chat(M, "You feel yourself slip into a regenerative coma...") - active_coma = TRUE - addtimer(CALLBACK(src, .proc/coma, M), 60) - -/datum/symptom/heal/coma/proc/coma(mob/living/M) - if(deathgasp) - M.emote("deathgasp") - M.fakedeath("regenerative_coma") - M.update_stat() - M.update_canmove() - addtimer(CALLBACK(src, .proc/uncoma, M), 300) - -/datum/symptom/heal/coma/proc/uncoma(mob/living/M) - if(!active_coma) - return - active_coma = FALSE - M.cure_fakedeath("regenerative_coma") - M.update_stat() - M.update_canmove() - -/datum/symptom/heal/coma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) - var/heal_amt = 4 * actual_power - - var/list/parts = M.get_damaged_bodyparts(1,1) - - if(!parts.len) - return - - for(var/obj/item/bodypart/L in parts) - if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len)) - M.update_damage_overlays() - - if(active_coma && M.getBruteLoss() + M.getFireLoss() == 0) - uncoma(M) - - return 1 - -/datum/symptom/heal/coma/passive_message_condition(mob/living/M) - if((M.getBruteLoss() + M.getFireLoss()) > 30) - return TRUE - return FALSE - -/datum/symptom/heal/water - name = "Tissue Hydration" - desc = "The virus uses excess water inside and outside the body to repair damaged tissue cells. More effective against burns." - stealth = 0 - resistance = -1 - stage_speed = 0 - transmittable = 1 - level = 6 - passive_message = "Your skin feels oddly dry..." - var/absorption_coeff = 1 - threshold_desc = "Resistance 5: Water is consumed at a much slower rate.
      \ - Stage Speed 7: Increases healing speed." - -/datum/symptom/heal/water/Start(datum/disease/advance/A) - if(!..()) - return - if(A.properties["stage_rate"] >= 7) - power = 2 - if(A.properties["stealth"] >= 2) - absorption_coeff = 0.25 - -/datum/symptom/heal/water/CanHeal(datum/disease/advance/A) - . = 0 - var/mob/living/M = A.affected_mob - if(M.fire_stacks < 0) - M.fire_stacks = min(M.fire_stacks + 1 * absorption_coeff, 0) - . += power - if(M.reagents.has_reagent(/datum/reagent/water/holywater)) - M.reagents.remove_reagent(/datum/reagent/water/holywater, 0.5 * absorption_coeff) - . += power * 0.75 - else if(M.reagents.has_reagent(/datum/reagent/water)) - M.reagents.remove_reagent(/datum/reagent/water, 0.5 * absorption_coeff) - . += power * 0.5 - -/datum/symptom/heal/water/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) - var/heal_amt = 2 * actual_power - - var/list/parts = M.get_damaged_bodyparts(1,1) //more effective on burns - - if(!parts.len) - return - - if(prob(5)) - to_chat(M, "You feel yourself absorbing the water around you to soothe your damaged skin.") - - for(var/obj/item/bodypart/L in parts) - if(L.heal_damage(heal_amt/parts.len * 0.5, heal_amt/parts.len)) - M.update_damage_overlays() - - return 1 - -/datum/symptom/heal/water/passive_message_condition(mob/living/M) - if(M.getBruteLoss() || M.getFireLoss()) - return TRUE - return FALSE - -/datum/symptom/heal/plasma - name = "Plasma Fixation" - desc = "The virus draws plasma from the atmosphere and from inside the body to heal and stabilize body temperature." - stealth = 0 - resistance = 3 - stage_speed = -2 - transmittable = -2 - level = 8 - passive_message = "You feel an odd attraction to plasma." - var/temp_rate = 1 - threshold_desc = "Transmission 6: Increases temperature adjustment rate and heals toxin lovers.
      \ - Stage Speed 7: Increases healing speed." - -/datum/symptom/heal/plasma/Start(datum/disease/advance/A) - if(!..()) - return - if(A.properties["stage_rate"] >= 7) - power = 2 - if(A.properties["transmittable"] >= 6) - temp_rate = 4 - -/datum/symptom/heal/plasma/CanHeal(datum/disease/advance/A) - var/mob/living/M = A.affected_mob - var/datum/gas_mixture/environment - var/plasmamount - - . = 0 - - if(M.loc) - environment = M.loc.return_air() - if(environment) - plasmamount = environment.gases[/datum/gas/plasma] - if(plasmamount && plasmamount > GLOB.meta_gas_visibility[/datum/gas/plasma]) //if there's enough plasma in the air to see - . += power * 0.5 - if(M.reagents.has_reagent(/datum/reagent/toxin/plasma)) - . += power * 0.75 - -/datum/symptom/heal/plasma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) - var/heal_amt = 4 * actual_power - - if(prob(5)) - to_chat(M, "You feel yourself absorbing plasma inside and around you...") - - if(M.bodytemperature > BODYTEMP_NORMAL) - M.adjust_bodytemperature(-20 * temp_rate * TEMPERATURE_DAMAGE_COEFFICIENT,BODYTEMP_NORMAL) - if(prob(5)) - to_chat(M, "You feel less hot.") - else if(M.bodytemperature < (BODYTEMP_NORMAL + 1)) - M.adjust_bodytemperature(20 * temp_rate * TEMPERATURE_DAMAGE_COEFFICIENT,0,BODYTEMP_NORMAL) - if(prob(5)) - to_chat(M, "You feel warmer.") - - M.adjustToxLoss(-heal_amt, forced = (temp_rate == 4)) - - var/list/parts = M.get_damaged_bodyparts(1,1) - if(!parts.len) - return - if(prob(5)) - to_chat(M, "The pain from your wounds fades rapidly.") - for(var/obj/item/bodypart/L in parts) - if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len)) - M.update_damage_overlays() - return 1 - - -/datum/symptom/heal/radiation - name = "Radioactive Resonance" - desc = "The virus uses radiation to fix damage through dna mutations." - stealth = -1 - resistance = -2 - stage_speed = 2 - transmittable = -3 - level = 6 - symptom_delay_min = 1 - symptom_delay_max = 1 - passive_message = "Your skin glows faintly for a moment." - var/cellular_damage = FALSE - threshold_desc = "Transmission 6: Additionally heals cellular damage and toxin lovers.
      \ - Resistance 7: Increases healing speed." - -/datum/symptom/heal/radiation/Start(datum/disease/advance/A) - if(!..()) - return - if(A.properties["resistance"] >= 7) - power = 2 - if(A.properties["transmittable"] >= 6) - cellular_damage = TRUE - -/datum/symptom/heal/radiation/CanHeal(datum/disease/advance/A) - var/mob/living/M = A.affected_mob - switch(M.radiation) - if(0) - return FALSE - if(1 to RAD_MOB_SAFE) - return 0.25 - if(RAD_MOB_SAFE to RAD_BURN_THRESHOLD) - return 0.5 - if(RAD_BURN_THRESHOLD to RAD_MOB_MUTATE) - return 0.75 - if(RAD_MOB_MUTATE to RAD_MOB_KNOCKDOWN) - return 1 - else - return 1.5 - -/datum/symptom/heal/radiation/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) - var/heal_amt = actual_power - - if(cellular_damage) - M.adjustCloneLoss(-heal_amt * 0.5) - - M.adjustToxLoss(-(2 * heal_amt), forced = cellular_damage) - - var/list/parts = M.get_damaged_bodyparts(1,1) - - if(!parts.len) - return - - if(prob(4)) - to_chat(M, "Your skin glows faintly, and you feel your wounds mending themselves.") - - for(var/obj/item/bodypart/L in parts) - if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len)) - M.update_damage_overlays() - return 1 +/datum/symptom/heal + name = "Basic Healing (does nothing)" //warning for adminspawn viruses + desc = "You should not be seeing this." + stealth = 0 + resistance = 0 + stage_speed = 0 + transmittable = 0 + level = 0 //not obtainable + base_message_chance = 20 //here used for the overlays + symptom_delay_min = 1 + symptom_delay_max = 1 + var/passive_message = "" //random message to infected but not actively healing people + threshold_desc = "Stage Speed 6: Doubles healing speed.
      \ + Stealth 4: Healing will no longer be visible to onlookers." + +/datum/symptom/heal/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["stage_rate"] >= 6) //stronger healing + power = 2 + +/datum/symptom/heal/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/M = A.affected_mob + switch(A.stage) + if(4, 5) + var/effectiveness = CanHeal(A) + if(!effectiveness) + if(passive_message && prob(2) && passive_message_condition(M)) + to_chat(M, passive_message) + return + else + Heal(M, A, effectiveness) + return + +/datum/symptom/heal/proc/CanHeal(datum/disease/advance/A) + return power + +/datum/symptom/heal/proc/Heal(mob/living/M, datum/disease/advance/A, actual_power) + return TRUE + +/datum/symptom/heal/proc/passive_message_condition(mob/living/M) + return TRUE + + +/datum/symptom/heal/starlight + name = "Starlight Condensation" + desc = "The virus reacts to direct starlight, producing regenerative chemicals. Works best against toxin-based damage." + stealth = -1 + resistance = -2 + stage_speed = 0 + transmittable = 1 + level = 6 + passive_message = "You miss the feeling of starlight on your skin." + var/nearspace_penalty = 0.3 + threshold_desc = "Stage Speed 6: Increases healing speed.
      \ + Transmission 6: Removes penalty for only being close to space." + +/datum/symptom/heal/starlight/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["transmittable"] >= 6) + nearspace_penalty = 1 + if(A.properties["stage_rate"] >= 6) + power = 2 + +/datum/symptom/heal/starlight/CanHeal(datum/disease/advance/A) + var/mob/living/M = A.affected_mob + if(istype(get_turf(M), /turf/open/space)) + return power + else + for(var/turf/T in view(M, 2)) + if(istype(T, /turf/open/space)) + return power * nearspace_penalty + +/datum/symptom/heal/starlight/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) + var/heal_amt = actual_power + if(M.getToxLoss() && prob(5)) + to_chat(M, "Your skin tingles as the starlight seems to heal you.") + + M.adjustToxLoss(-(4 * heal_amt), forced = TRUE) //most effective on toxins + + var/list/parts = M.get_damaged_bodyparts(1,1) + + if(!parts.len) + return + + for(var/obj/item/bodypart/L in parts) + if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len)) + M.update_damage_overlays() + return 1 + +/datum/symptom/heal/starlight/passive_message_condition(mob/living/M) + if(M.getBruteLoss() || M.getFireLoss() || M.getToxLoss()) + return TRUE + return FALSE + +/datum/symptom/heal/chem + name = "Toxolysis" + stealth = 0 + resistance = -2 + stage_speed = 2 + transmittable = -2 + level = 7 + var/food_conversion = FALSE + desc = "The virus rapidly breaks down any foreign chemicals in the bloodstream." + threshold_desc = "Resistance 7: Increases chem removal speed.
      \ + Stage Speed 6: Consumed chemicals nourish the host." + +/datum/symptom/heal/chem/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["stage_rate"] >= 6) + food_conversion = TRUE + if(A.properties["resistance"] >= 7) + power = 2 + +/datum/symptom/heal/chem/Heal(mob/living/M, datum/disease/advance/A, actual_power) + for(var/E in M.reagents.reagent_list) //Not just toxins! + var/datum/reagent/R = E + M.reagents.remove_reagent(R.type, actual_power) + if(food_conversion) + M.nutrition += 0.3 + if(prob(2)) + to_chat(M, "You feel a mild warmth as your blood purifies itself.") + return 1 + + + +/datum/symptom/heal/metabolism + name = "Metabolic Boost" + stealth = -1 + resistance = -2 + stage_speed = 2 + transmittable = 1 + level = 7 + var/triple_metabolism = FALSE + var/reduced_hunger = FALSE + desc = "The virus causes the host's metabolism to accelerate rapidly, making them process chemicals twice as fast,\ + but also causing increased hunger." + threshold_desc = "Stealth 3: Reduces hunger rate.
      \ + Stage Speed 10: Chemical metabolization is tripled instead of doubled." + +/datum/symptom/heal/metabolism/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["stage_rate"] >= 10) + triple_metabolism = TRUE + if(A.properties["stealth"] >= 3) + reduced_hunger = TRUE + +/datum/symptom/heal/metabolism/Heal(mob/living/carbon/C, datum/disease/advance/A, actual_power) + if(!istype(C)) + return + C.reagents.metabolize(C, can_overdose=TRUE) //this works even without a liver; it's intentional since the virus is metabolizing by itself + if(triple_metabolism) + C.reagents.metabolize(C, can_overdose=TRUE) + C.overeatduration = max(C.overeatduration - 2, 0) + var/lost_nutrition = 9 - (reduced_hunger * 5) + C.nutrition = max(C.nutrition - (lost_nutrition * HUNGER_FACTOR), 0) //Hunger depletes at 10x the normal speed + if(prob(2)) + to_chat(C, "You feel an odd gurgle in your stomach, as if it was working much faster than normal.") + return 1 + +/datum/symptom/heal/darkness + name = "Nocturnal Regeneration" + desc = "The virus is able to mend the host's flesh when in conditions of low light, repairing physical damage. More effective against brute damage." + stealth = 2 + resistance = -1 + stage_speed = -2 + transmittable = -1 + level = 6 + passive_message = "You feel tingling on your skin as light passes over it." + threshold_desc = "Stage Speed 8: Doubles healing speed." + +/datum/symptom/heal/darkness/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["stage_rate"] >= 8) + power = 2 + +/datum/symptom/heal/darkness/CanHeal(datum/disease/advance/A) + var/mob/living/M = A.affected_mob + var/light_amount = 0 + if(isturf(M.loc)) //else, there's considered to be no light + var/turf/T = M.loc + light_amount = min(1,T.get_lumcount()) - 0.5 + if(light_amount < SHADOW_SPECIES_LIGHT_THRESHOLD) + return power + +/datum/symptom/heal/darkness/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) + var/heal_amt = 2 * actual_power + + var/list/parts = M.get_damaged_bodyparts(1,1) + + if(!parts.len) + return + + if(prob(5)) + to_chat(M, "The darkness soothes and mends your wounds.") + + for(var/obj/item/bodypart/L in parts) + if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len * 0.5)) //more effective on brute + M.update_damage_overlays() + return 1 + +/datum/symptom/heal/darkness/passive_message_condition(mob/living/M) + if(M.getBruteLoss() || M.getFireLoss()) + return TRUE + return FALSE + +/datum/symptom/heal/coma + name = "Regenerative Coma" + desc = "The virus causes the host to fall into a death-like coma when severely damaged, then rapidly fixes the damage." + stealth = 0 + resistance = 2 + stage_speed = -3 + transmittable = -2 + level = 8 + passive_message = "The pain from your wounds makes you feel oddly sleepy..." + var/deathgasp = FALSE + var/stabilize = FALSE + var/active_coma = FALSE //to prevent multiple coma procs + threshold_desc = "Stealth 2: Host appears to die when falling into a coma.
      \ + Resistance 4: The virus also stabilizes the host while they are in critical condition.
      \ + Stage Speed 7: Increases healing speed." + +/datum/symptom/heal/coma/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["stage_rate"] >= 7) + power = 1.5 + if(A.properties["resistance"] >= 4) + stabilize = TRUE + if(A.properties["stealth"] >= 2) + deathgasp = TRUE + +/datum/symptom/heal/coma/on_stage_change(datum/disease/advance/A) //mostly copy+pasted from the code for self-respiration's TRAIT_NOBREATH stuff + if(!..()) + return FALSE + if(A.stage >= 4 && stabilize) + ADD_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT) + else + REMOVE_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT) + return TRUE + +/datum/symptom/heal/coma/End(datum/disease/advance/A) + if(!..()) + return + REMOVE_TRAIT(A.affected_mob, TRAIT_NOCRITDAMAGE, DISEASE_TRAIT) + +/datum/symptom/heal/coma/CanHeal(datum/disease/advance/A) + var/mob/living/M = A.affected_mob + if(HAS_TRAIT(M, TRAIT_DEATHCOMA)) + return power + else if(M.IsUnconscious() || M.stat == UNCONSCIOUS) + return power * 0.9 + else if(M.stat == SOFT_CRIT) + return power * 0.5 + else if(M.IsSleeping()) + return power * 0.25 + else if(M.getBruteLoss() + M.getFireLoss() >= 70 && !active_coma) + to_chat(M, "You feel yourself slip into a regenerative coma...") + active_coma = TRUE + addtimer(CALLBACK(src, .proc/coma, M), 60) + +/datum/symptom/heal/coma/proc/coma(mob/living/M) + if(deathgasp) + M.emote("deathgasp") + M.fakedeath("regenerative_coma") + M.update_stat() + M.update_canmove() + addtimer(CALLBACK(src, .proc/uncoma, M), 300) + +/datum/symptom/heal/coma/proc/uncoma(mob/living/M) + if(!active_coma) + return + active_coma = FALSE + M.cure_fakedeath("regenerative_coma") + M.update_stat() + M.update_canmove() + +/datum/symptom/heal/coma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) + var/heal_amt = 4 * actual_power + + var/list/parts = M.get_damaged_bodyparts(1,1) + + if(!parts.len) + return + + for(var/obj/item/bodypart/L in parts) + if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len)) + M.update_damage_overlays() + + if(active_coma && M.getBruteLoss() + M.getFireLoss() == 0) + uncoma(M) + + return 1 + +/datum/symptom/heal/coma/passive_message_condition(mob/living/M) + if((M.getBruteLoss() + M.getFireLoss()) > 30) + return TRUE + return FALSE + +/datum/symptom/heal/water + name = "Tissue Hydration" + desc = "The virus uses excess water inside and outside the body to repair damaged tissue cells. More effective against burns." + stealth = 0 + resistance = -1 + stage_speed = 0 + transmittable = 1 + level = 6 + passive_message = "Your skin feels oddly dry..." + var/absorption_coeff = 1 + threshold_desc = "Resistance 5: Water is consumed at a much slower rate.
      \ + Stage Speed 7: Increases healing speed." + +/datum/symptom/heal/water/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["stage_rate"] >= 7) + power = 2 + if(A.properties["stealth"] >= 2) + absorption_coeff = 0.25 + +/datum/symptom/heal/water/CanHeal(datum/disease/advance/A) + . = 0 + var/mob/living/M = A.affected_mob + if(M.fire_stacks < 0) + M.fire_stacks = min(M.fire_stacks + 1 * absorption_coeff, 0) + . += power + if(M.reagents.has_reagent(/datum/reagent/water/holywater)) + M.reagents.remove_reagent(/datum/reagent/water/holywater, 0.5 * absorption_coeff) + . += power * 0.75 + else if(M.reagents.has_reagent(/datum/reagent/water)) + M.reagents.remove_reagent(/datum/reagent/water, 0.5 * absorption_coeff) + . += power * 0.5 + +/datum/symptom/heal/water/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) + var/heal_amt = 2 * actual_power + + var/list/parts = M.get_damaged_bodyparts(1,1) //more effective on burns + + if(!parts.len) + return + + if(prob(5)) + to_chat(M, "You feel yourself absorbing the water around you to soothe your damaged skin.") + + for(var/obj/item/bodypart/L in parts) + if(L.heal_damage(heal_amt/parts.len * 0.5, heal_amt/parts.len)) + M.update_damage_overlays() + + return 1 + +/datum/symptom/heal/water/passive_message_condition(mob/living/M) + if(M.getBruteLoss() || M.getFireLoss()) + return TRUE + return FALSE + +/datum/symptom/heal/plasma + name = "Plasma Fixation" + desc = "The virus draws plasma from the atmosphere and from inside the body to heal and stabilize body temperature." + stealth = 0 + resistance = 3 + stage_speed = -2 + transmittable = -2 + level = 8 + passive_message = "You feel an odd attraction to plasma." + var/temp_rate = 1 + threshold_desc = "Transmission 6: Increases temperature adjustment rate and heals toxin lovers.
      \ + Stage Speed 7: Increases healing speed." + +/datum/symptom/heal/plasma/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["stage_rate"] >= 7) + power = 2 + if(A.properties["transmittable"] >= 6) + temp_rate = 4 + +/datum/symptom/heal/plasma/CanHeal(datum/disease/advance/A) + var/mob/living/M = A.affected_mob + var/datum/gas_mixture/environment + var/plasmamount + + . = 0 + + if(M.loc) + environment = M.loc.return_air() + if(environment) + plasmamount = environment.gases[/datum/gas/plasma] + if(plasmamount && plasmamount > GLOB.meta_gas_visibility[/datum/gas/plasma]) //if there's enough plasma in the air to see + . += power * 0.5 + if(M.reagents.has_reagent(/datum/reagent/toxin/plasma)) + . += power * 0.75 + +/datum/symptom/heal/plasma/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) + var/heal_amt = 4 * actual_power + + if(prob(5)) + to_chat(M, "You feel yourself absorbing plasma inside and around you...") + + if(M.bodytemperature > BODYTEMP_NORMAL) + M.adjust_bodytemperature(-20 * temp_rate * TEMPERATURE_DAMAGE_COEFFICIENT,BODYTEMP_NORMAL) + if(prob(5)) + to_chat(M, "You feel less hot.") + else if(M.bodytemperature < (BODYTEMP_NORMAL + 1)) + M.adjust_bodytemperature(20 * temp_rate * TEMPERATURE_DAMAGE_COEFFICIENT,0,BODYTEMP_NORMAL) + if(prob(5)) + to_chat(M, "You feel warmer.") + + M.adjustToxLoss(-heal_amt, forced = (temp_rate == 4)) + + var/list/parts = M.get_damaged_bodyparts(1,1) + if(!parts.len) + return + if(prob(5)) + to_chat(M, "The pain from your wounds fades rapidly.") + for(var/obj/item/bodypart/L in parts) + if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len)) + M.update_damage_overlays() + return 1 + + +/datum/symptom/heal/radiation + name = "Radioactive Resonance" + desc = "The virus uses radiation to fix damage through dna mutations." + stealth = -1 + resistance = -2 + stage_speed = 2 + transmittable = -3 + level = 6 + symptom_delay_min = 1 + symptom_delay_max = 1 + passive_message = "Your skin glows faintly for a moment." + var/cellular_damage = FALSE + threshold_desc = "Transmission 6: Additionally heals cellular damage and toxin lovers.
      \ + Resistance 7: Increases healing speed." + +/datum/symptom/heal/radiation/Start(datum/disease/advance/A) + if(!..()) + return + if(A.properties["resistance"] >= 7) + power = 2 + if(A.properties["transmittable"] >= 6) + cellular_damage = TRUE + +/datum/symptom/heal/radiation/CanHeal(datum/disease/advance/A) + var/mob/living/M = A.affected_mob + switch(M.radiation) + if(0) + return FALSE + if(1 to RAD_MOB_SAFE) + return 0.25 + if(RAD_MOB_SAFE to RAD_BURN_THRESHOLD) + return 0.5 + if(RAD_BURN_THRESHOLD to RAD_MOB_MUTATE) + return 0.75 + if(RAD_MOB_MUTATE to RAD_MOB_KNOCKDOWN) + return 1 + else + return 1.5 + +/datum/symptom/heal/radiation/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) + var/heal_amt = actual_power + + if(cellular_damage) + M.adjustCloneLoss(-heal_amt * 0.5) + + M.adjustToxLoss(-(2 * heal_amt), forced = cellular_damage) + + var/list/parts = M.get_damaged_bodyparts(1,1) + + if(!parts.len) + return + + if(prob(4)) + to_chat(M, "Your skin glows faintly, and you feel your wounds mending themselves.") + + for(var/obj/item/bodypart/L in parts) + if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len)) + M.update_damage_overlays() + return 1 diff --git a/code/datums/diseases/advance/symptoms/itching.dm b/code/datums/diseases/advance/symptoms/itching.dm index 1ede16999d..b0812e0235 100644 --- a/code/datums/diseases/advance/symptoms/itching.dm +++ b/code/datums/diseases/advance/symptoms/itching.dm @@ -1,54 +1,54 @@ -/* -////////////////////////////////////// - -Itching - - Not noticable or unnoticable. - Resistant. - Increases stage speed. - Little transmissibility. - Low Level. - -BONUS - Displays an annoying message! - Should be used for buffing your disease. - -////////////////////////////////////// -*/ - -/datum/symptom/itching - - name = "Itching" - desc = "The virus irritates the skin, causing itching." - stealth = 0 - resistance = 3 - stage_speed = 3 - transmittable = 1 - level = 1 - severity = 1 - 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) - if(!..()) - return - if(A.properties["transmittable"] >= 6) //itch more often - symptom_delay_min = 1 - symptom_delay_max = 4 - if(A.properties["stage_rate"] >= 7) //scratch - scratch = TRUE - -/datum/symptom/itching/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/carbon/M = A.affected_mob - var/picked_bodypart = pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) - var/obj/item/bodypart/bodypart = M.get_bodypart(picked_bodypart) - if(bodypart && bodypart.status == BODYPART_ORGANIC && !bodypart.is_pseudopart) //robotic limbs will mean less scratching overall - var/can_scratch = scratch && !M.incapacitated() && get_location_accessible(M, picked_bodypart) - M.visible_message("[can_scratch ? "[M] scratches [M.p_their()] [bodypart.name]." : ""]", "Your [bodypart.name] itches. [can_scratch ? " You scratch it." : ""]") - if(can_scratch) +/* +////////////////////////////////////// + +Itching + + Not noticable or unnoticable. + Resistant. + Increases stage speed. + Little transmissibility. + Low Level. + +BONUS + Displays an annoying message! + Should be used for buffing your disease. + +////////////////////////////////////// +*/ + +/datum/symptom/itching + + name = "Itching" + desc = "The virus irritates the skin, causing itching." + stealth = 0 + resistance = 3 + stage_speed = 3 + transmittable = 1 + level = 1 + severity = 1 + 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) + if(!..()) + return + if(A.properties["transmittable"] >= 6) //itch more often + symptom_delay_min = 1 + symptom_delay_max = 4 + if(A.properties["stage_rate"] >= 7) //scratch + scratch = TRUE + +/datum/symptom/itching/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/carbon/M = A.affected_mob + var/picked_bodypart = pick(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) + var/obj/item/bodypart/bodypart = M.get_bodypart(picked_bodypart) + if(bodypart && bodypart.status == BODYPART_ORGANIC && !bodypart.is_pseudopart) //robotic limbs will mean less scratching overall + var/can_scratch = scratch && !M.incapacitated() && get_location_accessible(M, picked_bodypart) + M.visible_message("[can_scratch ? "[M] scratches [M.p_their()] [bodypart.name]." : ""]", "Your [bodypart.name] itches. [can_scratch ? " You scratch it." : ""]") + if(can_scratch) bodypart.receive_damage(0.5) \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/oxygen.dm b/code/datums/diseases/advance/symptoms/oxygen.dm index 65f8307101..e66bdf5ee0 100644 --- a/code/datums/diseases/advance/symptoms/oxygen.dm +++ b/code/datums/diseases/advance/symptoms/oxygen.dm @@ -1,68 +1,68 @@ -/* -////////////////////////////////////// - -Self-Respiration - - Slightly hidden. - Lowers resistance significantly. - Decreases stage speed significantly. - Decreases transmittablity tremendously. - Fatal Level. - -Bonus - The body generates salbutamol. - -////////////////////////////////////// -*/ - -/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 - transmittable = -4 - level = 6 - base_message_chance = 5 - 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) - if(!..()) - return - if(A.properties["resistance"] >= 8) //blood regeneration - regenerate_blood = TRUE - -/datum/symptom/oxygen/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/carbon/M = A.affected_mob - switch(A.stage) - if(4, 5) - M.adjustOxyLoss(-7, 0) - M.losebreath = max(0, M.losebreath - 4) - if(regenerate_blood && M.blood_volume < (BLOOD_VOLUME_NORMAL * M.blood_ratio)) - M.blood_volume += 1 - else - if(prob(base_message_chance)) - to_chat(M, "[pick("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.")]") - return - -/datum/symptom/oxygen/on_stage_change(datum/disease/advance/A) - if(!..()) - return FALSE - var/mob/living/carbon/M = A.affected_mob - if(A.stage >= 4) - ADD_TRAIT(M, TRAIT_NOBREATH, DISEASE_TRAIT) - else - REMOVE_TRAIT(M, TRAIT_NOBREATH, DISEASE_TRAIT) - return TRUE - -/datum/symptom/oxygen/End(datum/disease/advance/A) - if(!..()) - return - if(A.stage >= 4) +/* +////////////////////////////////////// + +Self-Respiration + + Slightly hidden. + Lowers resistance significantly. + Decreases stage speed significantly. + Decreases transmittablity tremendously. + Fatal Level. + +Bonus + The body generates salbutamol. + +////////////////////////////////////// +*/ + +/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 + transmittable = -4 + level = 6 + base_message_chance = 5 + 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) + if(!..()) + return + if(A.properties["resistance"] >= 8) //blood regeneration + regenerate_blood = TRUE + +/datum/symptom/oxygen/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/carbon/M = A.affected_mob + switch(A.stage) + if(4, 5) + M.adjustOxyLoss(-7, 0) + M.losebreath = max(0, M.losebreath - 4) + if(regenerate_blood && M.blood_volume < (BLOOD_VOLUME_NORMAL * M.blood_ratio)) + M.blood_volume += 1 + else + if(prob(base_message_chance)) + to_chat(M, "[pick("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.")]") + return + +/datum/symptom/oxygen/on_stage_change(datum/disease/advance/A) + if(!..()) + return FALSE + var/mob/living/carbon/M = A.affected_mob + if(A.stage >= 4) + ADD_TRAIT(M, TRAIT_NOBREATH, DISEASE_TRAIT) + else + REMOVE_TRAIT(M, TRAIT_NOBREATH, DISEASE_TRAIT) + return TRUE + +/datum/symptom/oxygen/End(datum/disease/advance/A) + if(!..()) + return + if(A.stage >= 4) REMOVE_TRAIT(A.affected_mob, TRAIT_NOBREATH, DISEASE_TRAIT) \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/shedding.dm b/code/datums/diseases/advance/symptoms/shedding.dm index 06df320496..58357f04e2 100644 --- a/code/datums/diseases/advance/symptoms/shedding.dm +++ b/code/datums/diseases/advance/symptoms/shedding.dm @@ -1,55 +1,55 @@ -/* -////////////////////////////////////// -Alopecia - - Not Noticeable. - Increases resistance slightly. - Increases stage speed. - Transmittable. - Intense Level. - -BONUS - Makes the mob lose hair. - -////////////////////////////////////// -*/ - -/datum/symptom/shedding - name = "Alopecia" - desc = "The virus causes rapid shedding of head and body hair." - stealth = 0 - resistance = 1 - stage_speed = 2 - transmittable = 2 - level = 4 - severity = 1 - base_message_chance = 50 - symptom_delay_min = 45 - symptom_delay_max = 90 - -/datum/symptom/shedding/Activate(datum/disease/advance/A) - if(!..()) - return - - var/mob/living/M = A.affected_mob - if(prob(base_message_chance)) - to_chat(M, "[pick("Your scalp itches.", "Your skin feels flaky.")]") - if(ishuman(M)) - var/mob/living/carbon/human/H = M - switch(A.stage) - if(3, 4) - if(!(H.hair_style == "Bald") && !(H.hair_style == "Balding Hair")) - to_chat(H, "Your hair starts to fall out in clumps...") - addtimer(CALLBACK(src, .proc/Shed, H, FALSE), 50) - if(5) - if(!(H.facial_hair_style == "Shaved") || !(H.hair_style == "Bald")) - to_chat(H, "Your hair starts to fall out in clumps...") - addtimer(CALLBACK(src, .proc/Shed, H, TRUE), 50) - -/datum/symptom/shedding/proc/Shed(mob/living/carbon/human/H, fullbald) - if(fullbald) - H.facial_hair_style = "Shaved" - H.hair_style = "Bald" - else - H.hair_style = "Balding Hair" - H.update_hair() +/* +////////////////////////////////////// +Alopecia + + Not Noticeable. + Increases resistance slightly. + Increases stage speed. + Transmittable. + Intense Level. + +BONUS + Makes the mob lose hair. + +////////////////////////////////////// +*/ + +/datum/symptom/shedding + name = "Alopecia" + desc = "The virus causes rapid shedding of head and body hair." + stealth = 0 + resistance = 1 + stage_speed = 2 + transmittable = 2 + level = 4 + severity = 1 + base_message_chance = 50 + symptom_delay_min = 45 + symptom_delay_max = 90 + +/datum/symptom/shedding/Activate(datum/disease/advance/A) + if(!..()) + return + + var/mob/living/M = A.affected_mob + if(prob(base_message_chance)) + to_chat(M, "[pick("Your scalp itches.", "Your skin feels flaky.")]") + if(ishuman(M)) + var/mob/living/carbon/human/H = M + switch(A.stage) + if(3, 4) + if(!(H.hair_style == "Bald") && !(H.hair_style == "Balding Hair")) + to_chat(H, "Your hair starts to fall out in clumps...") + addtimer(CALLBACK(src, .proc/Shed, H, FALSE), 50) + if(5) + if(!(H.facial_hair_style == "Shaved") || !(H.hair_style == "Bald")) + to_chat(H, "Your hair starts to fall out in clumps...") + addtimer(CALLBACK(src, .proc/Shed, H, TRUE), 50) + +/datum/symptom/shedding/proc/Shed(mob/living/carbon/human/H, fullbald) + if(fullbald) + H.facial_hair_style = "Shaved" + H.hair_style = "Bald" + else + H.hair_style = "Balding Hair" + H.update_hair() diff --git a/code/datums/diseases/advance/symptoms/shivering.dm b/code/datums/diseases/advance/symptoms/shivering.dm index e4bb5e1b3e..741e2a1e16 100644 --- a/code/datums/diseases/advance/symptoms/shivering.dm +++ b/code/datums/diseases/advance/symptoms/shivering.dm @@ -1,59 +1,59 @@ -/* -////////////////////////////////////// - -Shivering - - No change to hidden. - Increases resistance. - Increases stage speed. - Little transmittable. - Low level. - -Bonus - Cools down your body. - -////////////////////////////////////// -*/ - -/datum/symptom/shivering - name = "Shivering" - desc = "The virus inhibits the body's thermoregulation, cooling the body down." - stealth = 0 - resistance = 2 - stage_speed = 2 - transmittable = 2 - level = 2 - severity = 2 - 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) - if(!..()) - return - if(A.properties["stage_rate"] >= 5) //dangerous cold - power = 1.5 - unsafe = TRUE - if(A.properties["stage_rate"] >= 10) - power = 2.5 - -/datum/symptom/shivering/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/carbon/M = A.affected_mob - if(!unsafe || A.stage < 4) - to_chat(M, "[pick("You feel cold.", "You shiver.")]") - else - to_chat(M, "[pick("You feel your blood run cold.", "You feel ice in your veins.", "You feel like you can't heat up.", "You shiver violently." )]") - if(M.bodytemperature > BODYTEMP_COLD_DAMAGE_LIMIT || unsafe) - Chill(M, A) - -/datum/symptom/shivering/proc/Chill(mob/living/M, datum/disease/advance/A) - var/get_cold = 6 * power - var/limit = BODYTEMP_COLD_DAMAGE_LIMIT + 1 - if(unsafe) - limit = 0 - M.adjust_bodytemperature(-get_cold * A.stage, limit) +/* +////////////////////////////////////// + +Shivering + + No change to hidden. + Increases resistance. + Increases stage speed. + Little transmittable. + Low level. + +Bonus + Cools down your body. + +////////////////////////////////////// +*/ + +/datum/symptom/shivering + name = "Shivering" + desc = "The virus inhibits the body's thermoregulation, cooling the body down." + stealth = 0 + resistance = 2 + stage_speed = 2 + transmittable = 2 + level = 2 + severity = 2 + 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) + if(!..()) + return + if(A.properties["stage_rate"] >= 5) //dangerous cold + power = 1.5 + unsafe = TRUE + if(A.properties["stage_rate"] >= 10) + power = 2.5 + +/datum/symptom/shivering/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/carbon/M = A.affected_mob + if(!unsafe || A.stage < 4) + to_chat(M, "[pick("You feel cold.", "You shiver.")]") + else + to_chat(M, "[pick("You feel your blood run cold.", "You feel ice in your veins.", "You feel like you can't heat up.", "You shiver violently." )]") + if(M.bodytemperature > BODYTEMP_COLD_DAMAGE_LIMIT || unsafe) + Chill(M, A) + +/datum/symptom/shivering/proc/Chill(mob/living/M, datum/disease/advance/A) + var/get_cold = 6 * power + var/limit = BODYTEMP_COLD_DAMAGE_LIMIT + 1 + if(unsafe) + limit = 0 + M.adjust_bodytemperature(-get_cold * A.stage, limit) return 1 \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/sneeze.dm b/code/datums/diseases/advance/symptoms/sneeze.dm index 5e21fb3dd9..5d4d40fb95 100644 --- a/code/datums/diseases/advance/symptoms/sneeze.dm +++ b/code/datums/diseases/advance/symptoms/sneeze.dm @@ -1,52 +1,52 @@ -/* -////////////////////////////////////// - -Sneezing - - Very Noticable. - Increases resistance. - Doesn't increase stage speed. - Very transmissible. - Low Level. - -Bonus - Forces a spread type of AIRBORNE - with extra range! - -////////////////////////////////////// -*/ - -/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 - transmittable = 4 - level = 1 - 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) - if(!..()) - return - if(A.properties["transmittable"] >= 9) //longer spread range - power = 2 - if(A.properties["stealth"] >= 4) - suppress_warning = TRUE - -/datum/symptom/sneeze/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/M = A.affected_mob - switch(A.stage) - if(1, 2, 3) - if(!suppress_warning) - M.emote("sniff") - else - M.emote("sneeze") - if(M.CanSpreadAirborneDisease()) //don't spread germs if they covered their mouth +/* +////////////////////////////////////// + +Sneezing + + Very Noticable. + Increases resistance. + Doesn't increase stage speed. + Very transmissible. + Low Level. + +Bonus + Forces a spread type of AIRBORNE + with extra range! + +////////////////////////////////////// +*/ + +/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 + transmittable = 4 + level = 1 + 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) + if(!..()) + return + if(A.properties["transmittable"] >= 9) //longer spread range + power = 2 + if(A.properties["stealth"] >= 4) + suppress_warning = TRUE + +/datum/symptom/sneeze/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/M = A.affected_mob + switch(A.stage) + if(1, 2, 3) + if(!suppress_warning) + M.emote("sniff") + else + M.emote("sneeze") + if(M.CanSpreadAirborneDisease()) //don't spread germs if they covered their mouth A.spread(4 + power) \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/symptoms.dm b/code/datums/diseases/advance/symptoms/symptoms.dm index 99dbd397a2..fef6453b3a 100644 --- a/code/datums/diseases/advance/symptoms/symptoms.dm +++ b/code/datums/diseases/advance/symptoms/symptoms.dm @@ -1,81 +1,81 @@ -// Symptoms are the effects that engineered advanced diseases do. - -/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 - var/transmittable = 0 - // The type level of the symptom. Higher is harder to generate. - var/level = 0 - // The severity level of the symptom. Higher is more dangerous. - var/severity = 0 - // The hash tag for our diseases, we will add it up with our other symptoms to get a unique id! ID MUST BE UNIQUE!!! - var/id = "" - //Base chance of sending warning messages, so it can be modified - var/base_message_chance = 10 - //If the early warnings are suppressed or not - var/suppress_warning = FALSE - //Ticks between each activation - var/next_activation = 0 - var/symptom_delay_min = 1 - var/symptom_delay_max = 1 - //Can be used to multiply virus effects - var/power = 1 - //A neutered symptom has no effect, and only affects statistics. - var/neutered = FALSE - var/list/thresholds - var/naturally_occuring = TRUE //if this symptom can appear from /datum/disease/advance/GenerateSymptoms() - -/datum/symptom/New() - var/list/S = SSdisease.list_symptoms - for(var/i = 1; i <= S.len; i++) - if(type == S[i]) - id = "[i]" - return - CRASH("We couldn't assign an ID!") - -// Called when processing of the advance disease that holds this symptom infects a host and upon each Refresh() of that advance disease. -/datum/symptom/proc/Start(datum/disease/advance/A) - if(neutered) - return FALSE - return TRUE - -// 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) - if(neutered) - return FALSE - return TRUE - -/datum/symptom/proc/Activate(datum/disease/advance/A) - if(neutered) - return FALSE - if(world.time < next_activation) - return FALSE - else - next_activation = world.time + rand(symptom_delay_min * 10, symptom_delay_max * 10) - return TRUE - -/datum/symptom/proc/on_stage_change(datum/disease/advance/A) - if(neutered) - return FALSE - return TRUE - -/datum/symptom/proc/Copy() - var/datum/symptom/new_symp = new type - new_symp.name = name - new_symp.id = id - new_symp.neutered = neutered - return new_symp - -/datum/symptom/proc/generate_threshold_desc() - return - -/datum/symptom/proc/OnAdd(datum/disease/advance/A) //Overload when a symptom needs to be active before processing, like changing biotypes. - return - -/datum/symptom/proc/OnRemove(datum/disease/advance/A) //But dont forget to remove them too. +// Symptoms are the effects that engineered advanced diseases do. + +/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 + var/transmittable = 0 + // The type level of the symptom. Higher is harder to generate. + var/level = 0 + // The severity level of the symptom. Higher is more dangerous. + var/severity = 0 + // The hash tag for our diseases, we will add it up with our other symptoms to get a unique id! ID MUST BE UNIQUE!!! + var/id = "" + //Base chance of sending warning messages, so it can be modified + var/base_message_chance = 10 + //If the early warnings are suppressed or not + var/suppress_warning = FALSE + //Ticks between each activation + var/next_activation = 0 + var/symptom_delay_min = 1 + var/symptom_delay_max = 1 + //Can be used to multiply virus effects + var/power = 1 + //A neutered symptom has no effect, and only affects statistics. + var/neutered = FALSE + var/list/thresholds + var/naturally_occuring = TRUE //if this symptom can appear from /datum/disease/advance/GenerateSymptoms() + +/datum/symptom/New() + var/list/S = SSdisease.list_symptoms + for(var/i = 1; i <= S.len; i++) + if(type == S[i]) + id = "[i]" + return + CRASH("We couldn't assign an ID!") + +// Called when processing of the advance disease that holds this symptom infects a host and upon each Refresh() of that advance disease. +/datum/symptom/proc/Start(datum/disease/advance/A) + if(neutered) + return FALSE + return TRUE + +// 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) + if(neutered) + return FALSE + return TRUE + +/datum/symptom/proc/Activate(datum/disease/advance/A) + if(neutered) + return FALSE + if(world.time < next_activation) + return FALSE + else + next_activation = world.time + rand(symptom_delay_min * 10, symptom_delay_max * 10) + return TRUE + +/datum/symptom/proc/on_stage_change(datum/disease/advance/A) + if(neutered) + return FALSE + return TRUE + +/datum/symptom/proc/Copy() + var/datum/symptom/new_symp = new type + new_symp.name = name + new_symp.id = id + new_symp.neutered = neutered + return new_symp + +/datum/symptom/proc/generate_threshold_desc() + return + +/datum/symptom/proc/OnAdd(datum/disease/advance/A) //Overload when a symptom needs to be active before processing, like changing biotypes. + return + +/datum/symptom/proc/OnRemove(datum/disease/advance/A) //But dont forget to remove them too. return \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/voice_change.dm b/code/datums/diseases/advance/symptoms/voice_change.dm index 5f0b83e5c8..8b9b7d069a 100644 --- a/code/datums/diseases/advance/symptoms/voice_change.dm +++ b/code/datums/diseases/advance/symptoms/voice_change.dm @@ -1,81 +1,81 @@ -/* -////////////////////////////////////// - -Voice Change - - Noticeable. - Lowers resistance. - Decreases stage speed. - Increased transmittable. - Fatal Level. - -Bonus - Changes the voice of the affected mob. Causing confusion in communication. - -////////////////////////////////////// -*/ - -/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 - transmittable = 2 - level = 6 - severity = 2 - base_message_chance = 100 - symptom_delay_min = 60 - symptom_delay_max = 120 - 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) - if(!..()) - return - if(A.properties["stealth"] >= 3) - suppress_warning = TRUE - if(A.properties["stage_rate"] >= 7) //faster change of voice - base_message_chance = 25 - symptom_delay_min = 25 - symptom_delay_max = 85 - if(A.properties["transmittable"] >= 14) //random language - scramble_language = TRUE - var/mob/living/M = A.affected_mob - var/datum/language_holder/mob_language = M.get_language_holder() - original_language = mob_language.copy() - -/datum/symptom/voice_change/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/carbon/M = A.affected_mob - switch(A.stage) - if(1, 2, 3, 4) - if(prob(base_message_chance) && !suppress_warning) - to_chat(M, "[pick("Your throat hurts.", "You clear your throat.")]") - else - if(ishuman(M)) - var/mob/living/carbon/human/H = M - H.SetSpecialVoice(H.dna.species.random_name(H.gender)) - if(scramble_language) - H.remove_language(current_language) - current_language = pick(subtypesof(/datum/language) - /datum/language/common) - H.grant_language(current_language) - var/datum/language_holder/mob_language = H.get_language_holder() - mob_language.only_speaks_language = current_language - -/datum/symptom/voice_change/End(datum/disease/advance/A) - ..() - if(ishuman(A.affected_mob)) - var/mob/living/carbon/human/H = A.affected_mob - H.UnsetSpecialVoice() - if(scramble_language) - var/mob/living/M = A.affected_mob - M.copy_known_languages_from(original_language, TRUE) - current_language = null - QDEL_NULL(original_language) +/* +////////////////////////////////////// + +Voice Change + + Noticeable. + Lowers resistance. + Decreases stage speed. + Increased transmittable. + Fatal Level. + +Bonus + Changes the voice of the affected mob. Causing confusion in communication. + +////////////////////////////////////// +*/ + +/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 + transmittable = 2 + level = 6 + severity = 2 + base_message_chance = 100 + symptom_delay_min = 60 + symptom_delay_max = 120 + 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) + if(!..()) + return + if(A.properties["stealth"] >= 3) + suppress_warning = TRUE + if(A.properties["stage_rate"] >= 7) //faster change of voice + base_message_chance = 25 + symptom_delay_min = 25 + symptom_delay_max = 85 + if(A.properties["transmittable"] >= 14) //random language + scramble_language = TRUE + var/mob/living/M = A.affected_mob + var/datum/language_holder/mob_language = M.get_language_holder() + original_language = mob_language.copy() + +/datum/symptom/voice_change/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/carbon/M = A.affected_mob + switch(A.stage) + if(1, 2, 3, 4) + if(prob(base_message_chance) && !suppress_warning) + to_chat(M, "[pick("Your throat hurts.", "You clear your throat.")]") + else + if(ishuman(M)) + var/mob/living/carbon/human/H = M + H.SetSpecialVoice(H.dna.species.random_name(H.gender)) + if(scramble_language) + H.remove_language(current_language) + current_language = pick(subtypesof(/datum/language) - /datum/language/common) + H.grant_language(current_language) + var/datum/language_holder/mob_language = H.get_language_holder() + mob_language.only_speaks_language = current_language + +/datum/symptom/voice_change/End(datum/disease/advance/A) + ..() + if(ishuman(A.affected_mob)) + var/mob/living/carbon/human/H = A.affected_mob + H.UnsetSpecialVoice() + if(scramble_language) + var/mob/living/M = A.affected_mob + M.copy_known_languages_from(original_language, TRUE) + current_language = null + QDEL_NULL(original_language) diff --git a/code/datums/diseases/advance/symptoms/vomit.dm b/code/datums/diseases/advance/symptoms/vomit.dm index 04b0778ccd..f53638bc12 100644 --- a/code/datums/diseases/advance/symptoms/vomit.dm +++ b/code/datums/diseases/advance/symptoms/vomit.dm @@ -1,63 +1,63 @@ -/* -////////////////////////////////////// - -Vomiting - - Very Very Noticable. - Decreases resistance. - Doesn't increase stage speed. - Little transmissibility. - Medium Level. - -Bonus - Forces the affected mob to vomit! - Meaning your disease can spread via - people walking on vomit. - Makes the affected mob lose nutrition and - heal toxin damage. - -////////////////////////////////////// -*/ - -/datum/symptom/vomit - - name = "Vomiting" - desc = "The virus causes nausea and irritates the stomach, causing occasional vomit." - stealth = -2 - resistance = -1 - stage_speed = 0 - transmittable = 1 - level = 3 - severity = 3 - base_message_chance = 100 - symptom_delay_min = 25 - 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) - if(!..()) - return - if(A.properties["stealth"] >= 4) - suppress_warning = TRUE - if(A.properties["resistance"] >= 7) //blood vomit - vomit_blood = TRUE - if(A.properties["transmittable"] >= 7) //projectile vomit - proj_vomit = 5 - -/datum/symptom/vomit/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/M = A.affected_mob - switch(A.stage) - if(1, 2, 3, 4) - if(prob(base_message_chance) && !suppress_warning) - to_chat(M, "[pick("You feel nauseated.", "You feel like you're going to throw up!")]") - else - vomit(M) - -/datum/symptom/vomit/proc/vomit(mob/living/carbon/M) - M.vomit(20, vomit_blood, distance = proj_vomit) +/* +////////////////////////////////////// + +Vomiting + + Very Very Noticable. + Decreases resistance. + Doesn't increase stage speed. + Little transmissibility. + Medium Level. + +Bonus + Forces the affected mob to vomit! + Meaning your disease can spread via + people walking on vomit. + Makes the affected mob lose nutrition and + heal toxin damage. + +////////////////////////////////////// +*/ + +/datum/symptom/vomit + + name = "Vomiting" + desc = "The virus causes nausea and irritates the stomach, causing occasional vomit." + stealth = -2 + resistance = -1 + stage_speed = 0 + transmittable = 1 + level = 3 + severity = 3 + base_message_chance = 100 + symptom_delay_min = 25 + 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) + if(!..()) + return + if(A.properties["stealth"] >= 4) + suppress_warning = TRUE + if(A.properties["resistance"] >= 7) //blood vomit + vomit_blood = TRUE + if(A.properties["transmittable"] >= 7) //projectile vomit + proj_vomit = 5 + +/datum/symptom/vomit/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/M = A.affected_mob + switch(A.stage) + if(1, 2, 3, 4) + if(prob(base_message_chance) && !suppress_warning) + to_chat(M, "[pick("You feel nauseated.", "You feel like you're going to throw up!")]") + else + vomit(M) + +/datum/symptom/vomit/proc/vomit(mob/living/carbon/M) + M.vomit(20, vomit_blood, distance = proj_vomit) diff --git a/code/datums/diseases/advance/symptoms/weight.dm b/code/datums/diseases/advance/symptoms/weight.dm index c97667733d..66fc90f1f8 100644 --- a/code/datums/diseases/advance/symptoms/weight.dm +++ b/code/datums/diseases/advance/symptoms/weight.dm @@ -1,51 +1,51 @@ -/* -////////////////////////////////////// - -Weight Loss - - Very Very Noticable. - Decreases resistance. - Decreases stage speed. - Reduced Transmittable. - High level. - -Bonus - Decreases the weight of the mob, - forcing it to be skinny. - -////////////////////////////////////// -*/ - -/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 = -2 - resistance = 2 - stage_speed = -2 - transmittable = -2 - level = 3 - severity = 3 - 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) - if(!..()) - return - if(A.properties["stealth"] >= 4) //warn less often - base_message_chance = 25 - -/datum/symptom/weight_loss/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/M = A.affected_mob - switch(A.stage) - if(1, 2, 3, 4) - if(prob(base_message_chance)) - to_chat(M, "[pick("You feel hungry.", "You crave for food.")]") - else - to_chat(M, "[pick("So hungry...", "You'd kill someone for a bite of food...", "Hunger cramps seize you...")]") - M.overeatduration = max(M.overeatduration - 100, 0) +/* +////////////////////////////////////// + +Weight Loss + + Very Very Noticable. + Decreases resistance. + Decreases stage speed. + Reduced Transmittable. + High level. + +Bonus + Decreases the weight of the mob, + forcing it to be skinny. + +////////////////////////////////////// +*/ + +/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 = -2 + resistance = 2 + stage_speed = -2 + transmittable = -2 + level = 3 + severity = 3 + 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) + if(!..()) + return + if(A.properties["stealth"] >= 4) //warn less often + base_message_chance = 25 + +/datum/symptom/weight_loss/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/M = A.affected_mob + switch(A.stage) + if(1, 2, 3, 4) + if(prob(base_message_chance)) + to_chat(M, "[pick("You feel hungry.", "You crave for food.")]") + else + to_chat(M, "[pick("So hungry...", "You'd kill someone for a bite of food...", "Hunger cramps seize you...")]") + M.overeatduration = max(M.overeatduration - 100, 0) M.nutrition = max(M.nutrition - 100, 0) \ No newline at end of file diff --git a/code/datums/diseases/advance/symptoms/youth.dm b/code/datums/diseases/advance/symptoms/youth.dm index 927be03ed9..d2712a0146 100644 --- a/code/datums/diseases/advance/symptoms/youth.dm +++ b/code/datums/diseases/advance/symptoms/youth.dm @@ -1,58 +1,58 @@ -/* -////////////////////////////////////// -Eternal Youth - - Moderate stealth boost. - Increases resistance tremendously. - Increases stage speed tremendously. - Reduces transmission tremendously. - Critical Level. - -BONUS - Gives you immortality and eternal youth!!! - Can be used to buff your virus - -////////////////////////////////////// -*/ - -/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 - transmittable = -4 - level = 5 - base_message_chance = 100 - symptom_delay_min = 25 - symptom_delay_max = 50 - -/datum/symptom/youth/Activate(datum/disease/advance/A) - if(!..()) - return - var/mob/living/M = A.affected_mob - if(ishuman(M)) - var/mob/living/carbon/human/H = M - switch(A.stage) - if(1) - if(H.age > 41) - H.age = 41 - to_chat(H, "You haven't had this much energy in years!") - if(2) - if(H.age > 36) - H.age = 36 - to_chat(H, "You're suddenly in a good mood.") - if(3) - if(H.age > 31) - H.age = 31 - to_chat(H, "You begin to feel more lithe.") - if(4) - if(H.age > 26) - H.age = 26 - to_chat(H, "You feel reinvigorated.") - if(5) - if(H.age > 21) - H.age = 21 +/* +////////////////////////////////////// +Eternal Youth + + Moderate stealth boost. + Increases resistance tremendously. + Increases stage speed tremendously. + Reduces transmission tremendously. + Critical Level. + +BONUS + Gives you immortality and eternal youth!!! + Can be used to buff your virus + +////////////////////////////////////// +*/ + +/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 + transmittable = -4 + level = 5 + base_message_chance = 100 + symptom_delay_min = 25 + symptom_delay_max = 50 + +/datum/symptom/youth/Activate(datum/disease/advance/A) + if(!..()) + return + var/mob/living/M = A.affected_mob + if(ishuman(M)) + var/mob/living/carbon/human/H = M + switch(A.stage) + if(1) + if(H.age > 41) + H.age = 41 + to_chat(H, "You haven't had this much energy in years!") + if(2) + if(H.age > 36) + H.age = 36 + to_chat(H, "You're suddenly in a good mood.") + if(3) + if(H.age > 31) + H.age = 31 + to_chat(H, "You begin to feel more lithe.") + if(4) + if(H.age > 26) + H.age = 26 + to_chat(H, "You feel reinvigorated.") + if(5) + if(H.age > 21) + H.age = 21 to_chat(H, "You feel like you can take on the world!") \ No newline at end of file diff --git a/code/datums/diseases/appendicitis.dm b/code/datums/diseases/appendicitis.dm index be7e6ceecd..7a6ea142b3 100644 --- a/code/datums/diseases/appendicitis.dm +++ b/code/datums/diseases/appendicitis.dm @@ -1,36 +1,36 @@ -/datum/disease/appendicitis - form = "Condition" - name = "Appendicitis" - max_stages = 3 - cure_text = "Surgery" - agent = "Shitty Appendix" - viable_mobtypes = list(/mob/living/carbon/human) - permeability_mod = 1 - desc = "If left untreated the subject will become very weak, and may vomit often." - severity = DISEASE_SEVERITY_MEDIUM - disease_flags = CAN_CARRY|CAN_RESIST - spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS - visibility_flags = HIDDEN_PANDEMIC - required_organs = list(/obj/item/organ/appendix) - bypasses_immunity = TRUE // Immunity is based on not having an appendix; this isn't a virus - -/datum/disease/appendicitis/stage_act() - ..() - switch(stage) - if(1) - if(prob(5)) - affected_mob.emote("cough") - if(2) - var/obj/item/organ/appendix/A = affected_mob.getorgan(/obj/item/organ/appendix) - if(A) - A.inflamed = 1 - A.update_icon() - if(prob(3)) - to_chat(affected_mob, "You feel a stabbing pain in your abdomen!") - affected_mob.adjustOrganLoss(ORGAN_SLOT_APPENDIX, 5) - affected_mob.Stun(rand(40,60)) - affected_mob.adjustToxLoss(1) - if(3) - if(prob(1)) - affected_mob.vomit(95) - affected_mob.adjustOrganLoss(ORGAN_SLOT_APPENDIX, 15) +/datum/disease/appendicitis + form = "Condition" + name = "Appendicitis" + max_stages = 3 + cure_text = "Surgery" + agent = "Shitty Appendix" + viable_mobtypes = list(/mob/living/carbon/human) + permeability_mod = 1 + desc = "If left untreated the subject will become very weak, and may vomit often." + severity = DISEASE_SEVERITY_MEDIUM + disease_flags = CAN_CARRY|CAN_RESIST + spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS + visibility_flags = HIDDEN_PANDEMIC + required_organs = list(/obj/item/organ/appendix) + bypasses_immunity = TRUE // Immunity is based on not having an appendix; this isn't a virus + +/datum/disease/appendicitis/stage_act() + ..() + switch(stage) + if(1) + if(prob(5)) + affected_mob.emote("cough") + if(2) + var/obj/item/organ/appendix/A = affected_mob.getorgan(/obj/item/organ/appendix) + if(A) + A.inflamed = 1 + A.update_icon() + if(prob(3)) + to_chat(affected_mob, "You feel a stabbing pain in your abdomen!") + affected_mob.adjustOrganLoss(ORGAN_SLOT_APPENDIX, 5) + affected_mob.Stun(rand(40,60)) + affected_mob.adjustToxLoss(1) + if(3) + if(prob(1)) + affected_mob.vomit(95) + affected_mob.adjustOrganLoss(ORGAN_SLOT_APPENDIX, 15) diff --git a/code/datums/diseases/beesease.dm b/code/datums/diseases/beesease.dm index edd6f151c9..074bda0560 100644 --- a/code/datums/diseases/beesease.dm +++ b/code/datums/diseases/beesease.dm @@ -1,39 +1,39 @@ -/datum/disease/beesease - name = "Beesease" - form = "Infection" - max_stages = 4 - spread_text = "On contact" - spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS - cure_text = "Sugar" - cures = list(/datum/reagent/consumable/sugar) - agent = "Apidae Infection" - viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - desc = "If left untreated subject will regurgitate bees." - severity = DISEASE_SEVERITY_MEDIUM - infectable_biotypes = list(MOB_ORGANIC, MOB_UNDEAD) //bees nesting in corpses - -/datum/disease/beesease/stage_act() - ..() - switch(stage) - if(2) //also changes say, see say.dm - if(prob(2)) - to_chat(affected_mob, "You taste honey in your mouth.") - if(3) - if(prob(10)) - to_chat(affected_mob, "Your stomach rumbles.") - if(prob(2)) - to_chat(affected_mob, "Your stomach stings painfully.") - if(prob(20)) - affected_mob.adjustToxLoss(2) - affected_mob.updatehealth() - if(4) - if(prob(10)) - affected_mob.visible_message("[affected_mob] buzzes.", \ - "Your stomach buzzes violently!") - if(prob(5)) - to_chat(affected_mob, "You feel something moving in your throat.") - if(prob(1)) - affected_mob.visible_message("[affected_mob] coughs up a swarm of bees!", \ - "You cough up a swarm of bees!") - new /mob/living/simple_animal/hostile/poison/bees(affected_mob.loc) +/datum/disease/beesease + name = "Beesease" + form = "Infection" + max_stages = 4 + spread_text = "On contact" + spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS + cure_text = "Sugar" + cures = list(/datum/reagent/consumable/sugar) + agent = "Apidae Infection" + viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) + desc = "If left untreated subject will regurgitate bees." + severity = DISEASE_SEVERITY_MEDIUM + infectable_biotypes = list(MOB_ORGANIC, MOB_UNDEAD) //bees nesting in corpses + +/datum/disease/beesease/stage_act() + ..() + switch(stage) + if(2) //also changes say, see say.dm + if(prob(2)) + to_chat(affected_mob, "You taste honey in your mouth.") + if(3) + if(prob(10)) + to_chat(affected_mob, "Your stomach rumbles.") + if(prob(2)) + to_chat(affected_mob, "Your stomach stings painfully.") + if(prob(20)) + affected_mob.adjustToxLoss(2) + affected_mob.updatehealth() + if(4) + if(prob(10)) + affected_mob.visible_message("[affected_mob] buzzes.", \ + "Your stomach buzzes violently!") + if(prob(5)) + to_chat(affected_mob, "You feel something moving in your throat.") + if(prob(1)) + affected_mob.visible_message("[affected_mob] coughs up a swarm of bees!", \ + "You cough up a swarm of bees!") + new /mob/living/simple_animal/hostile/poison/bees(affected_mob.loc) return \ No newline at end of file diff --git a/code/datums/diseases/brainrot.dm b/code/datums/diseases/brainrot.dm index 1028d1fff4..57628efe36 100644 --- a/code/datums/diseases/brainrot.dm +++ b/code/datums/diseases/brainrot.dm @@ -1,59 +1,59 @@ -/datum/disease/brainrot - name = "Brainrot" - max_stages = 4 - spread_text = "On contact" - spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS - cure_text = "Mannitol" - cures = list(/datum/reagent/medicine/mannitol) - agent = "Cryptococcus Cosmosis" - viable_mobtypes = list(/mob/living/carbon/human) - cure_chance = 15//higher chance to cure, since two reagents are required - desc = "This disease destroys the braincells, causing brain fever, brain necrosis and general intoxication." - required_organs = list(/obj/item/organ/brain) - severity = DISEASE_SEVERITY_HARMFUL - -/datum/disease/brainrot/stage_act() //Removed toxloss because damaging diseases are pretty horrible. Last round it killed the entire station because the cure didn't work -- Urist -ACTUALLY Removed rather than commented out, I don't see it returning - RR - ..() - - switch(stage) - if(2) - if(prob(2)) - affected_mob.emote("blink") - if(prob(2)) - affected_mob.emote("yawn") - if(prob(2)) - to_chat(affected_mob, "You don't feel like yourself.") - if(prob(5)) - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1, 170) - affected_mob.updatehealth() - if(3) - if(prob(2)) - affected_mob.emote("stare") - if(prob(2)) - affected_mob.emote("drool") - if(prob(10)) - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2, 170) - affected_mob.updatehealth() - if(prob(2)) - to_chat(affected_mob, "Your try to remember something important...but can't.") - - if(4) - if(prob(2)) - affected_mob.emote("stare") - if(prob(2)) - affected_mob.emote("drool") - if(prob(15)) - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3, 170) - affected_mob.updatehealth() - if(prob(2)) - to_chat(affected_mob, "Strange buzzing fills your head, removing all thoughts.") - if(prob(3)) - to_chat(affected_mob, "You lose consciousness...") - affected_mob.visible_message("[affected_mob] suddenly collapses") - affected_mob.Unconscious(rand(100,200)) - if(prob(1)) - affected_mob.emote("snore") - if(prob(15)) - affected_mob.stuttering += 3 - - return +/datum/disease/brainrot + name = "Brainrot" + max_stages = 4 + spread_text = "On contact" + spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS + cure_text = "Mannitol" + cures = list(/datum/reagent/medicine/mannitol) + agent = "Cryptococcus Cosmosis" + viable_mobtypes = list(/mob/living/carbon/human) + cure_chance = 15//higher chance to cure, since two reagents are required + desc = "This disease destroys the braincells, causing brain fever, brain necrosis and general intoxication." + required_organs = list(/obj/item/organ/brain) + severity = DISEASE_SEVERITY_HARMFUL + +/datum/disease/brainrot/stage_act() //Removed toxloss because damaging diseases are pretty horrible. Last round it killed the entire station because the cure didn't work -- Urist -ACTUALLY Removed rather than commented out, I don't see it returning - RR + ..() + + switch(stage) + if(2) + if(prob(2)) + affected_mob.emote("blink") + if(prob(2)) + affected_mob.emote("yawn") + if(prob(2)) + to_chat(affected_mob, "You don't feel like yourself.") + if(prob(5)) + affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1, 170) + affected_mob.updatehealth() + if(3) + if(prob(2)) + affected_mob.emote("stare") + if(prob(2)) + affected_mob.emote("drool") + if(prob(10)) + affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2, 170) + affected_mob.updatehealth() + if(prob(2)) + to_chat(affected_mob, "Your try to remember something important...but can't.") + + if(4) + if(prob(2)) + affected_mob.emote("stare") + if(prob(2)) + affected_mob.emote("drool") + if(prob(15)) + affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3, 170) + affected_mob.updatehealth() + if(prob(2)) + to_chat(affected_mob, "Strange buzzing fills your head, removing all thoughts.") + if(prob(3)) + to_chat(affected_mob, "You lose consciousness...") + affected_mob.visible_message("[affected_mob] suddenly collapses") + affected_mob.Unconscious(rand(100,200)) + if(prob(1)) + affected_mob.emote("snore") + if(prob(15)) + affected_mob.stuttering += 3 + + return diff --git a/code/datums/diseases/cold.dm b/code/datums/diseases/cold.dm index 8bbb05e17c..660793ed83 100644 --- a/code/datums/diseases/cold.dm +++ b/code/datums/diseases/cold.dm @@ -1,53 +1,53 @@ -/datum/disease/cold - name = "The Cold" - max_stages = 3 - cure_text = "Rest & Spaceacillin" - cures = list(/datum/reagent/medicine/spaceacillin) - agent = "XY-rhinovirus" - viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - permeability_mod = 0.5 - desc = "If left untreated the subject will contract the flu." - severity = DISEASE_SEVERITY_NONTHREAT - -/datum/disease/cold/stage_act() - ..() - switch(stage) - if(2) - if(affected_mob.lying && prob(40)) //changed FROM prob(10) until sleeping is fixed - to_chat(affected_mob, "You feel better.") - cure() - return - if(prob(1) && prob(5)) - to_chat(affected_mob, "You feel better.") - cure() - return - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(1)) - to_chat(affected_mob, "Your throat feels sore.") - if(prob(1)) - to_chat(affected_mob, "Mucous runs down the back of your throat.") - if(3) - if(affected_mob.lying && prob(25)) //changed FROM prob(5) until sleeping is fixed - to_chat(affected_mob, "You feel better.") - cure() - return - if(prob(1) && prob(1)) - to_chat(affected_mob, "You feel better.") - cure() - return - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(1)) - to_chat(affected_mob, "Your throat feels sore.") - if(prob(1)) - to_chat(affected_mob, "Mucous runs down the back of your throat.") - if(prob(1) && prob(50)) - if(!affected_mob.disease_resistances.Find(/datum/disease/flu)) - var/datum/disease/Flu = new /datum/disease/flu() - affected_mob.ForceContractDisease(Flu, FALSE, TRUE) +/datum/disease/cold + name = "The Cold" + max_stages = 3 + cure_text = "Rest & Spaceacillin" + cures = list(/datum/reagent/medicine/spaceacillin) + agent = "XY-rhinovirus" + viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) + permeability_mod = 0.5 + desc = "If left untreated the subject will contract the flu." + severity = DISEASE_SEVERITY_NONTHREAT + +/datum/disease/cold/stage_act() + ..() + switch(stage) + if(2) + if(affected_mob.lying && prob(40)) //changed FROM prob(10) until sleeping is fixed + to_chat(affected_mob, "You feel better.") + cure() + return + if(prob(1) && prob(5)) + to_chat(affected_mob, "You feel better.") + cure() + return + if(prob(1)) + affected_mob.emote("sneeze") + if(prob(1)) + affected_mob.emote("cough") + if(prob(1)) + to_chat(affected_mob, "Your throat feels sore.") + if(prob(1)) + to_chat(affected_mob, "Mucous runs down the back of your throat.") + if(3) + if(affected_mob.lying && prob(25)) //changed FROM prob(5) until sleeping is fixed + to_chat(affected_mob, "You feel better.") + cure() + return + if(prob(1) && prob(1)) + to_chat(affected_mob, "You feel better.") + cure() + return + if(prob(1)) + affected_mob.emote("sneeze") + if(prob(1)) + affected_mob.emote("cough") + if(prob(1)) + to_chat(affected_mob, "Your throat feels sore.") + if(prob(1)) + to_chat(affected_mob, "Mucous runs down the back of your throat.") + if(prob(1) && prob(50)) + if(!affected_mob.disease_resistances.Find(/datum/disease/flu)) + var/datum/disease/Flu = new /datum/disease/flu() + affected_mob.ForceContractDisease(Flu, FALSE, TRUE) cure() \ No newline at end of file diff --git a/code/datums/diseases/cold9.dm b/code/datums/diseases/cold9.dm index eea3147107..47f391ecf7 100644 --- a/code/datums/diseases/cold9.dm +++ b/code/datums/diseases/cold9.dm @@ -1,39 +1,39 @@ -/datum/disease/cold9 - name = "The Cold" - max_stages = 3 - spread_text = "On contact" - spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS - cure_text = "Common Cold Anti-bodies & Spaceacillin" - cures = list(/datum/reagent/medicine/spaceacillin) - agent = "ICE9-rhinovirus" - viable_mobtypes = list(/mob/living/carbon/human) - desc = "If left untreated the subject will slow, as if partly frozen." - severity = DISEASE_SEVERITY_HARMFUL - -/datum/disease/cold9/stage_act() - ..() - switch(stage) - if(2) - affected_mob.adjust_bodytemperature(-10) - if(prob(1) && prob(10)) - to_chat(affected_mob, "You feel better.") - cure() - return - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(1)) - to_chat(affected_mob, "Your throat feels sore.") - if(prob(5)) - to_chat(affected_mob, "You feel stiff.") - if(3) - affected_mob.adjust_bodytemperature(-20) - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(1)) - to_chat(affected_mob, "Your throat feels sore.") - if(prob(10)) +/datum/disease/cold9 + name = "The Cold" + max_stages = 3 + spread_text = "On contact" + spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS + cure_text = "Common Cold Anti-bodies & Spaceacillin" + cures = list(/datum/reagent/medicine/spaceacillin) + agent = "ICE9-rhinovirus" + viable_mobtypes = list(/mob/living/carbon/human) + desc = "If left untreated the subject will slow, as if partly frozen." + severity = DISEASE_SEVERITY_HARMFUL + +/datum/disease/cold9/stage_act() + ..() + switch(stage) + if(2) + affected_mob.adjust_bodytemperature(-10) + if(prob(1) && prob(10)) + to_chat(affected_mob, "You feel better.") + cure() + return + if(prob(1)) + affected_mob.emote("sneeze") + if(prob(1)) + affected_mob.emote("cough") + if(prob(1)) + to_chat(affected_mob, "Your throat feels sore.") + if(prob(5)) + to_chat(affected_mob, "You feel stiff.") + if(3) + affected_mob.adjust_bodytemperature(-20) + if(prob(1)) + affected_mob.emote("sneeze") + if(prob(1)) + affected_mob.emote("cough") + if(prob(1)) + to_chat(affected_mob, "Your throat feels sore.") + if(prob(10)) to_chat(affected_mob, "You feel stiff.") \ No newline at end of file diff --git a/code/datums/diseases/dna_spread.dm b/code/datums/diseases/dna_spread.dm index 972a7f4e18..3a67230d36 100644 --- a/code/datums/diseases/dna_spread.dm +++ b/code/datums/diseases/dna_spread.dm @@ -1,74 +1,74 @@ -/datum/disease/dnaspread - name = "Space Retrovirus" - max_stages = 4 - spread_text = "On contact" - spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS - cure_text = "Mutadone" - cures = list(/datum/reagent/medicine/mutadone) - disease_flags = CAN_CARRY|CAN_RESIST|CURABLE - agent = "S4E1 retrovirus" - viable_mobtypes = list(/mob/living/carbon/human) - var/datum/dna/original_dna = null - var/transformed = 0 - desc = "This disease transplants the genetic code of the initial vector into new hosts." - severity = DISEASE_SEVERITY_MEDIUM - - -/datum/disease/dnaspread/stage_act() - ..() - if(!affected_mob.dna) - cure() - if((NOTRANSSTING in affected_mob.dna.species.species_traits) || (NO_DNA_COPY in affected_mob.dna.species.species_traits)) //Only species that can be spread by transformation sting can be spread by the retrovirus - cure() - - if(!strain_data["dna"]) - //Absorbs the target DNA. - strain_data["dna"] = new affected_mob.dna.type - affected_mob.dna.copy_dna(strain_data["dna"]) - carrier = TRUE - stage = 4 - return - - switch(stage) - if(2 || 3) //Pretend to be a cold and give time to spread. - if(prob(8)) - affected_mob.emote("sneeze") - if(prob(8)) - affected_mob.emote("cough") - if(prob(1)) - to_chat(affected_mob, "Your muscles ache.") - if(prob(20)) - affected_mob.take_bodypart_damage(1) - if(prob(1)) - to_chat(affected_mob, "Your stomach hurts.") - if(prob(20)) - affected_mob.adjustToxLoss(2) - affected_mob.updatehealth() - if(4) - if(!transformed && !carrier) - //Save original dna for when the disease is cured. - original_dna = new affected_mob.dna.type - affected_mob.dna.copy_dna(original_dna) - - to_chat(affected_mob, "You don't feel like yourself..") - var/datum/dna/transform_dna = strain_data["dna"] - - transform_dna.transfer_identity(affected_mob, transfer_SE = 1) - affected_mob.real_name = affected_mob.dna.real_name - affected_mob.updateappearance(mutcolor_update=1) - affected_mob.domutcheck() - - transformed = 1 - carrier = 1 //Just chill out at stage 4 - - return - -/datum/disease/dnaspread/Destroy() - if (original_dna && transformed && affected_mob) - original_dna.transfer_identity(affected_mob, transfer_SE = 1) - affected_mob.real_name = affected_mob.dna.real_name - affected_mob.updateappearance(mutcolor_update=1) - affected_mob.domutcheck() - - to_chat(affected_mob, "You feel more like yourself.") - return ..() +/datum/disease/dnaspread + name = "Space Retrovirus" + max_stages = 4 + spread_text = "On contact" + spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS + cure_text = "Mutadone" + cures = list(/datum/reagent/medicine/mutadone) + disease_flags = CAN_CARRY|CAN_RESIST|CURABLE + agent = "S4E1 retrovirus" + viable_mobtypes = list(/mob/living/carbon/human) + var/datum/dna/original_dna = null + var/transformed = 0 + desc = "This disease transplants the genetic code of the initial vector into new hosts." + severity = DISEASE_SEVERITY_MEDIUM + + +/datum/disease/dnaspread/stage_act() + ..() + if(!affected_mob.dna) + cure() + if((NOTRANSSTING in affected_mob.dna.species.species_traits) || (NO_DNA_COPY in affected_mob.dna.species.species_traits)) //Only species that can be spread by transformation sting can be spread by the retrovirus + cure() + + if(!strain_data["dna"]) + //Absorbs the target DNA. + strain_data["dna"] = new affected_mob.dna.type + affected_mob.dna.copy_dna(strain_data["dna"]) + carrier = TRUE + stage = 4 + return + + switch(stage) + if(2 || 3) //Pretend to be a cold and give time to spread. + if(prob(8)) + affected_mob.emote("sneeze") + if(prob(8)) + affected_mob.emote("cough") + if(prob(1)) + to_chat(affected_mob, "Your muscles ache.") + if(prob(20)) + affected_mob.take_bodypart_damage(1) + if(prob(1)) + to_chat(affected_mob, "Your stomach hurts.") + if(prob(20)) + affected_mob.adjustToxLoss(2) + affected_mob.updatehealth() + if(4) + if(!transformed && !carrier) + //Save original dna for when the disease is cured. + original_dna = new affected_mob.dna.type + affected_mob.dna.copy_dna(original_dna) + + to_chat(affected_mob, "You don't feel like yourself..") + var/datum/dna/transform_dna = strain_data["dna"] + + transform_dna.transfer_identity(affected_mob, transfer_SE = 1) + affected_mob.real_name = affected_mob.dna.real_name + affected_mob.updateappearance(mutcolor_update=1) + affected_mob.domutcheck() + + transformed = 1 + carrier = 1 //Just chill out at stage 4 + + return + +/datum/disease/dnaspread/Destroy() + if (original_dna && transformed && affected_mob) + original_dna.transfer_identity(affected_mob, transfer_SE = 1) + affected_mob.real_name = affected_mob.dna.real_name + affected_mob.updateappearance(mutcolor_update=1) + affected_mob.domutcheck() + + to_chat(affected_mob, "You feel more like yourself.") + return ..() diff --git a/code/datums/diseases/fake_gbs.dm b/code/datums/diseases/fake_gbs.dm index 70bcc67d21..37628a5502 100644 --- a/code/datums/diseases/fake_gbs.dm +++ b/code/datums/diseases/fake_gbs.dm @@ -1,32 +1,32 @@ -/datum/disease/fake_gbs - name = "GBS" - max_stages = 5 - spread_text = "On contact" - spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS - cure_text = "Synaptizine & Sulfur" - cures = list(/datum/reagent/medicine/synaptizine,/datum/reagent/sulfur) - agent = "Gravitokinetic Bipotential SADS-" - viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - desc = "If left untreated death will occur." - severity = DISEASE_SEVERITY_BIOHAZARD - -/datum/disease/fake_gbs/stage_act() - ..() - switch(stage) - if(2) - if(prob(1)) - affected_mob.emote("sneeze") - if(3) - if(prob(5)) - affected_mob.emote("cough") - else if(prob(5)) - affected_mob.emote("gasp") - if(prob(10)) - to_chat(affected_mob, "You're starting to feel very weak...") - if(4) - if(prob(10)) - affected_mob.emote("cough") - - if(5) - if(prob(10)) - affected_mob.emote("cough") +/datum/disease/fake_gbs + name = "GBS" + max_stages = 5 + spread_text = "On contact" + spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS + cure_text = "Synaptizine & Sulfur" + cures = list(/datum/reagent/medicine/synaptizine,/datum/reagent/sulfur) + agent = "Gravitokinetic Bipotential SADS-" + viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) + desc = "If left untreated death will occur." + severity = DISEASE_SEVERITY_BIOHAZARD + +/datum/disease/fake_gbs/stage_act() + ..() + switch(stage) + if(2) + if(prob(1)) + affected_mob.emote("sneeze") + if(3) + if(prob(5)) + affected_mob.emote("cough") + else if(prob(5)) + affected_mob.emote("gasp") + if(prob(10)) + to_chat(affected_mob, "You're starting to feel very weak...") + if(4) + if(prob(10)) + affected_mob.emote("cough") + + if(5) + if(prob(10)) + affected_mob.emote("cough") diff --git a/code/datums/diseases/flu.dm b/code/datums/diseases/flu.dm index 4fc646a590..7672118774 100644 --- a/code/datums/diseases/flu.dm +++ b/code/datums/diseases/flu.dm @@ -1,54 +1,54 @@ -/datum/disease/flu - name = "The Flu" - max_stages = 3 - spread_text = "Airborne" - cure_text = "Spaceacillin" - cures = list(/datum/reagent/medicine/spaceacillin) - cure_chance = 10 - agent = "H13N1 flu virion" - viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) - permeability_mod = 0.75 - desc = "If left untreated the subject will feel quite unwell." - severity = DISEASE_SEVERITY_MINOR - -/datum/disease/flu/stage_act() - ..() - switch(stage) - if(2) - if(affected_mob.lying && prob(20)) - to_chat(affected_mob, "You feel better.") - stage-- - return - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(1)) - to_chat(affected_mob, "Your muscles ache.") - if(prob(20)) - affected_mob.take_bodypart_damage(1) - if(prob(1)) - to_chat(affected_mob, "Your stomach hurts.") - if(prob(20)) - affected_mob.adjustToxLoss(1) - affected_mob.updatehealth() - - if(3) - if(affected_mob.lying && prob(15)) - to_chat(affected_mob, "You feel better.") - stage-- - return - if(prob(1)) - affected_mob.emote("sneeze") - if(prob(1)) - affected_mob.emote("cough") - if(prob(1)) - to_chat(affected_mob, "Your muscles ache.") - if(prob(20)) - affected_mob.take_bodypart_damage(1) - if(prob(1)) - to_chat(affected_mob, "Your stomach hurts.") - if(prob(20)) - affected_mob.adjustToxLoss(1) - affected_mob.updatehealth() - return +/datum/disease/flu + name = "The Flu" + max_stages = 3 + spread_text = "Airborne" + cure_text = "Spaceacillin" + cures = list(/datum/reagent/medicine/spaceacillin) + cure_chance = 10 + agent = "H13N1 flu virion" + viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) + permeability_mod = 0.75 + desc = "If left untreated the subject will feel quite unwell." + severity = DISEASE_SEVERITY_MINOR + +/datum/disease/flu/stage_act() + ..() + switch(stage) + if(2) + if(affected_mob.lying && prob(20)) + to_chat(affected_mob, "You feel better.") + stage-- + return + if(prob(1)) + affected_mob.emote("sneeze") + if(prob(1)) + affected_mob.emote("cough") + if(prob(1)) + to_chat(affected_mob, "Your muscles ache.") + if(prob(20)) + affected_mob.take_bodypart_damage(1) + if(prob(1)) + to_chat(affected_mob, "Your stomach hurts.") + if(prob(20)) + affected_mob.adjustToxLoss(1) + affected_mob.updatehealth() + + if(3) + if(affected_mob.lying && prob(15)) + to_chat(affected_mob, "You feel better.") + stage-- + return + if(prob(1)) + affected_mob.emote("sneeze") + if(prob(1)) + affected_mob.emote("cough") + if(prob(1)) + to_chat(affected_mob, "Your muscles ache.") + if(prob(20)) + affected_mob.take_bodypart_damage(1) + if(prob(1)) + to_chat(affected_mob, "Your stomach hurts.") + if(prob(20)) + affected_mob.adjustToxLoss(1) + affected_mob.updatehealth() + return diff --git a/code/datums/diseases/fluspanish.dm b/code/datums/diseases/fluspanish.dm index 1557ddfbd8..3297877fe9 100644 --- a/code/datums/diseases/fluspanish.dm +++ b/code/datums/diseases/fluspanish.dm @@ -1,36 +1,36 @@ -/datum/disease/fluspanish - name = "Spanish inquisition Flu" - max_stages = 3 - spread_text = "Airborne" - cure_text = "Spaceacillin & Anti-bodies to the common flu" - cures = list(/datum/reagent/medicine/spaceacillin) - cure_chance = 10 - agent = "1nqu1s1t10n flu virion" - viable_mobtypes = list(/mob/living/carbon/human) - permeability_mod = 0.75 - desc = "If left untreated the subject will burn to death for being a heretic." - severity = DISEASE_SEVERITY_DANGEROUS - -/datum/disease/fluspanish/stage_act() - ..() - switch(stage) - if(2) - affected_mob.adjust_bodytemperature(10) - if(prob(5)) - affected_mob.emote("sneeze") - if(prob(5)) - affected_mob.emote("cough") - if(prob(1)) - to_chat(affected_mob, "You're burning in your own skin!") - affected_mob.take_bodypart_damage(0,5) - - if(3) - affected_mob.adjust_bodytemperature(20) - if(prob(5)) - affected_mob.emote("sneeze") - if(prob(5)) - affected_mob.emote("cough") - if(prob(5)) - to_chat(affected_mob, "You're burning in your own skin!") - affected_mob.take_bodypart_damage(0,5) - return +/datum/disease/fluspanish + name = "Spanish inquisition Flu" + max_stages = 3 + spread_text = "Airborne" + cure_text = "Spaceacillin & Anti-bodies to the common flu" + cures = list(/datum/reagent/medicine/spaceacillin) + cure_chance = 10 + agent = "1nqu1s1t10n flu virion" + viable_mobtypes = list(/mob/living/carbon/human) + permeability_mod = 0.75 + desc = "If left untreated the subject will burn to death for being a heretic." + severity = DISEASE_SEVERITY_DANGEROUS + +/datum/disease/fluspanish/stage_act() + ..() + switch(stage) + if(2) + affected_mob.adjust_bodytemperature(10) + if(prob(5)) + affected_mob.emote("sneeze") + if(prob(5)) + affected_mob.emote("cough") + if(prob(1)) + to_chat(affected_mob, "You're burning in your own skin!") + affected_mob.take_bodypart_damage(0,5) + + if(3) + affected_mob.adjust_bodytemperature(20) + if(prob(5)) + affected_mob.emote("sneeze") + if(prob(5)) + affected_mob.emote("cough") + if(prob(5)) + to_chat(affected_mob, "You're burning in your own skin!") + affected_mob.take_bodypart_damage(0,5) + return diff --git a/code/datums/diseases/gbs.dm b/code/datums/diseases/gbs.dm index 8a6eab6048..8ac1996855 100644 --- a/code/datums/diseases/gbs.dm +++ b/code/datums/diseases/gbs.dm @@ -1,31 +1,31 @@ -/datum/disease/gbs - name = "GBS" - max_stages = 4 - spread_text = "On contact" - spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS - cure_text = "Synaptizine & Sulfur" - cures = list(/datum/reagent/medicine/synaptizine,/datum/reagent/sulfur) - cure_chance = 15//higher chance to cure, since two reagents are required - agent = "Gravitokinetic Bipotential SADS+" - viable_mobtypes = list(/mob/living/carbon/human) - disease_flags = CAN_CARRY|CAN_RESIST|CURABLE - permeability_mod = 1 - severity = DISEASE_SEVERITY_BIOHAZARD - -/datum/disease/gbs/stage_act() - ..() - switch(stage) - if(2) - if(prob(5)) - affected_mob.emote("cough") - if(3) - if(prob(5)) - affected_mob.emote("gasp") - if(prob(10)) - to_chat(affected_mob, "Your body hurts all over!") - if(4) - to_chat(affected_mob, "Your body feels as if it's trying to rip itself apart!") - if(prob(50)) - affected_mob.gib() - else - return +/datum/disease/gbs + name = "GBS" + max_stages = 4 + spread_text = "On contact" + spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS + cure_text = "Synaptizine & Sulfur" + cures = list(/datum/reagent/medicine/synaptizine,/datum/reagent/sulfur) + cure_chance = 15//higher chance to cure, since two reagents are required + agent = "Gravitokinetic Bipotential SADS+" + viable_mobtypes = list(/mob/living/carbon/human) + disease_flags = CAN_CARRY|CAN_RESIST|CURABLE + permeability_mod = 1 + severity = DISEASE_SEVERITY_BIOHAZARD + +/datum/disease/gbs/stage_act() + ..() + switch(stage) + if(2) + if(prob(5)) + affected_mob.emote("cough") + if(3) + if(prob(5)) + affected_mob.emote("gasp") + if(prob(10)) + to_chat(affected_mob, "Your body hurts all over!") + if(4) + to_chat(affected_mob, "Your body feels as if it's trying to rip itself apart!") + if(prob(50)) + affected_mob.gib() + else + return diff --git a/code/datums/diseases/magnitis.dm b/code/datums/diseases/magnitis.dm index cb00f571aa..29e6657e13 100644 --- a/code/datums/diseases/magnitis.dm +++ b/code/datums/diseases/magnitis.dm @@ -1,68 +1,68 @@ -/datum/disease/magnitis - name = "Magnitis" - max_stages = 4 - spread_text = "Airborne" - cure_text = "Iron" - cures = list(/datum/reagent/iron) - agent = "Fukkos Miracos" - viable_mobtypes = list(/mob/living/carbon/human) - disease_flags = CAN_CARRY|CAN_RESIST|CURABLE - permeability_mod = 0.75 - desc = "This disease disrupts the magnetic field of your body, making it act as if a powerful magnet. Injections of iron help stabilize the field." - severity = DISEASE_SEVERITY_MEDIUM - infectable_biotypes = list(MOB_ORGANIC, MOB_ROBOTIC) - process_dead = TRUE - -/datum/disease/magnitis/stage_act() - ..() - switch(stage) - if(2) - if(prob(2)) - to_chat(affected_mob, "You feel a slight shock course through your body.") - if(prob(2)) - for(var/obj/M in orange(2,affected_mob)) - if(!M.anchored && (M.flags_1 & CONDUCT_1)) - step_towards(M,affected_mob) - for(var/mob/living/silicon/S in orange(2,affected_mob)) - if(isAI(S)) - continue - step_towards(S,affected_mob) - if(3) - if(prob(2)) - to_chat(affected_mob, "You feel a strong shock course through your body.") - if(prob(2)) - to_chat(affected_mob, "You feel like clowning around.") - if(prob(4)) - for(var/obj/M in orange(4,affected_mob)) - if(!M.anchored && (M.flags_1 & CONDUCT_1)) - var/i - var/iter = rand(1,2) - for(i=0,iYou feel a powerful shock course through your body.") - if(prob(2)) - to_chat(affected_mob, "You query upon the nature of miracles.") - if(prob(8)) - for(var/obj/M in orange(6,affected_mob)) - if(!M.anchored && (M.flags_1 & CONDUCT_1)) - var/i - var/iter = rand(1,3) - for(i=0,iYou feel a slight shock course through your body.") + if(prob(2)) + for(var/obj/M in orange(2,affected_mob)) + if(!M.anchored && (M.flags_1 & CONDUCT_1)) + step_towards(M,affected_mob) + for(var/mob/living/silicon/S in orange(2,affected_mob)) + if(isAI(S)) + continue + step_towards(S,affected_mob) + if(3) + if(prob(2)) + to_chat(affected_mob, "You feel a strong shock course through your body.") + if(prob(2)) + to_chat(affected_mob, "You feel like clowning around.") + if(prob(4)) + for(var/obj/M in orange(4,affected_mob)) + if(!M.anchored && (M.flags_1 & CONDUCT_1)) + var/i + var/iter = rand(1,2) + for(i=0,iYou feel a powerful shock course through your body.") + if(prob(2)) + to_chat(affected_mob, "You query upon the nature of miracles.") + if(prob(8)) + for(var/obj/M in orange(6,affected_mob)) + if(!M.anchored && (M.flags_1 & CONDUCT_1)) + var/i + var/iter = rand(1,3) + for(i=0,iYou feel a little silly.") - if(2) - if(prob(10)) - to_chat(affected_mob, "You start seeing rainbows.") - if(3) - if(prob(10)) - to_chat(affected_mob, "Your thoughts are interrupted by a loud HONK!") - if(4) - if(prob(5)) - affected_mob.say( pick( list("HONK!", "Honk!", "Honk.", "Honk?", "Honk!!", "Honk?!", "Honk...") ) , forced = "pierrot's throat") - -/datum/disease/pierrot_throat/after_add() - RegisterSignal(affected_mob, COMSIG_MOB_SAY, .proc/handle_speech) - -/datum/disease/pierrot_throat/proc/handle_speech(datum/source, list/speech_args) - var/message = speech_args[SPEECH_MESSAGE] - var/list/split_message = splittext(message, " ") //List each word in the message - var/applied = 0 - for (var/i in 1 to length(split_message)) - if(prob(3 * stage)) //Stage 1: 3% Stage 2: 6% Stage 3: 9% Stage 4: 12% - if(findtext(split_message[i], "*") || findtext(split_message[i], ";") || findtext(split_message[i], ":")) - continue - split_message[i] = "HONK" - if (applied++ > stage) - break - if (applied) - speech_args[SPEECH_SPANS] |= SPAN_CLOWN // a little bonus - message = jointext(split_message, " ") - speech_args[SPEECH_MESSAGE] = message - -/datum/disease/pierrot_throat/Destroy() - UnregisterSignal(affected_mob, COMSIG_MOB_SAY) - return ..() - -/datum/disease/pierrot_throat/remove_disease() - UnregisterSignal(affected_mob, COMSIG_MOB_SAY) +/datum/disease/pierrot_throat + name = "Pierrot's Throat" + max_stages = 4 + spread_text = "Airborne" + cure_text = "Banana products, especially banana bread." + cures = list(/datum/reagent/consumable/banana) + cure_chance = 75 + agent = "H0NI<42 Virus" + viable_mobtypes = list(/mob/living/carbon/human) + permeability_mod = 0.75 + desc = "If left untreated the subject will probably drive others to insanity." + severity = DISEASE_SEVERITY_MEDIUM + +/datum/disease/pierrot_throat/stage_act() + ..() + switch(stage) + if(1) + if(prob(10)) + to_chat(affected_mob, "You feel a little silly.") + if(2) + if(prob(10)) + to_chat(affected_mob, "You start seeing rainbows.") + if(3) + if(prob(10)) + to_chat(affected_mob, "Your thoughts are interrupted by a loud HONK!") + if(4) + if(prob(5)) + affected_mob.say( pick( list("HONK!", "Honk!", "Honk.", "Honk?", "Honk!!", "Honk?!", "Honk...") ) , forced = "pierrot's throat") + +/datum/disease/pierrot_throat/after_add() + RegisterSignal(affected_mob, COMSIG_MOB_SAY, .proc/handle_speech) + +/datum/disease/pierrot_throat/proc/handle_speech(datum/source, list/speech_args) + var/message = speech_args[SPEECH_MESSAGE] + var/list/split_message = splittext(message, " ") //List each word in the message + var/applied = 0 + for (var/i in 1 to length(split_message)) + if(prob(3 * stage)) //Stage 1: 3% Stage 2: 6% Stage 3: 9% Stage 4: 12% + if(findtext(split_message[i], "*") || findtext(split_message[i], ";") || findtext(split_message[i], ":")) + continue + split_message[i] = "HONK" + if (applied++ > stage) + break + if (applied) + speech_args[SPEECH_SPANS] |= SPAN_CLOWN // a little bonus + message = jointext(split_message, " ") + speech_args[SPEECH_MESSAGE] = message + +/datum/disease/pierrot_throat/Destroy() + UnregisterSignal(affected_mob, COMSIG_MOB_SAY) + return ..() + +/datum/disease/pierrot_throat/remove_disease() + UnregisterSignal(affected_mob, COMSIG_MOB_SAY) return ..() \ No newline at end of file diff --git a/code/datums/diseases/retrovirus.dm b/code/datums/diseases/retrovirus.dm index 5854249e54..160a9f98ad 100644 --- a/code/datums/diseases/retrovirus.dm +++ b/code/datums/diseases/retrovirus.dm @@ -1,84 +1,84 @@ -/datum/disease/dna_retrovirus - name = "Retrovirus" - max_stages = 4 - spread_text = "Contact" - spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS - cure_text = "Rest or an injection of mutadone" - cure_chance = 6 - agent = "" - viable_mobtypes = list(/mob/living/carbon/human) - desc = "A DNA-altering retrovirus that scrambles the structural and unique enzymes of a host constantly." - severity = DISEASE_SEVERITY_HARMFUL - permeability_mod = 0.4 - stage_prob = 2 - var/restcure = 0 - -/datum/disease/dna_retrovirus/New() - ..() - agent = "Virus class [pick("A","B","C","D","E","F")][pick("A","B","C","D","E","F")]-[rand(50,300)]" - if(prob(40)) - cures = list(/datum/reagent/medicine/mutadone) - else - restcure = 1 - -/datum/disease/dna_retrovirus/Copy() - var/datum/disease/dna_retrovirus/D = ..() - D.restcure = restcure - return D - -/datum/disease/dna_retrovirus/stage_act() - ..() - switch(stage) - if(1) - if(restcure) - if(affected_mob.lying && prob(30)) - to_chat(affected_mob, "You feel better.") - cure() - return - if (prob(8)) - to_chat(affected_mob, "Your head hurts.") - if (prob(9)) - to_chat(affected_mob, "You feel a tingling sensation in your chest.") - if (prob(9)) - to_chat(affected_mob, "You feel angry.") - if(2) - if(restcure) - if(affected_mob.lying && prob(20)) - to_chat(affected_mob, "You feel better.") - cure() - return - if (prob(8)) - to_chat(affected_mob, "Your skin feels loose.") - if (prob(10)) - to_chat(affected_mob, "You feel very strange.") - if (prob(4)) - to_chat(affected_mob, "You feel a stabbing pain in your head!") - affected_mob.Unconscious(40) - if (prob(4)) - to_chat(affected_mob, "Your stomach churns.") - if(3) - if(restcure) - if(affected_mob.lying && prob(20)) - to_chat(affected_mob, "You feel better.") - cure() - return - if (prob(10)) - to_chat(affected_mob, "Your entire body vibrates.") - - if (prob(35)) - if(prob(50)) - scramble_dna(affected_mob, 1, 0, rand(15,45)) - else - scramble_dna(affected_mob, 0, 1, rand(15,45)) - - if(4) - if(restcure) - if(affected_mob.lying && prob(5)) - to_chat(affected_mob, "You feel better.") - cure() - return - if (prob(60)) - if(prob(50)) - scramble_dna(affected_mob, 1, 0, rand(50,75)) - else +/datum/disease/dna_retrovirus + name = "Retrovirus" + max_stages = 4 + spread_text = "Contact" + spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS + cure_text = "Rest or an injection of mutadone" + cure_chance = 6 + agent = "" + viable_mobtypes = list(/mob/living/carbon/human) + desc = "A DNA-altering retrovirus that scrambles the structural and unique enzymes of a host constantly." + severity = DISEASE_SEVERITY_HARMFUL + permeability_mod = 0.4 + stage_prob = 2 + var/restcure = 0 + +/datum/disease/dna_retrovirus/New() + ..() + agent = "Virus class [pick("A","B","C","D","E","F")][pick("A","B","C","D","E","F")]-[rand(50,300)]" + if(prob(40)) + cures = list(/datum/reagent/medicine/mutadone) + else + restcure = 1 + +/datum/disease/dna_retrovirus/Copy() + var/datum/disease/dna_retrovirus/D = ..() + D.restcure = restcure + return D + +/datum/disease/dna_retrovirus/stage_act() + ..() + switch(stage) + if(1) + if(restcure) + if(affected_mob.lying && prob(30)) + to_chat(affected_mob, "You feel better.") + cure() + return + if (prob(8)) + to_chat(affected_mob, "Your head hurts.") + if (prob(9)) + to_chat(affected_mob, "You feel a tingling sensation in your chest.") + if (prob(9)) + to_chat(affected_mob, "You feel angry.") + if(2) + if(restcure) + if(affected_mob.lying && prob(20)) + to_chat(affected_mob, "You feel better.") + cure() + return + if (prob(8)) + to_chat(affected_mob, "Your skin feels loose.") + if (prob(10)) + to_chat(affected_mob, "You feel very strange.") + if (prob(4)) + to_chat(affected_mob, "You feel a stabbing pain in your head!") + affected_mob.Unconscious(40) + if (prob(4)) + to_chat(affected_mob, "Your stomach churns.") + if(3) + if(restcure) + if(affected_mob.lying && prob(20)) + to_chat(affected_mob, "You feel better.") + cure() + return + if (prob(10)) + to_chat(affected_mob, "Your entire body vibrates.") + + if (prob(35)) + if(prob(50)) + scramble_dna(affected_mob, 1, 0, rand(15,45)) + else + scramble_dna(affected_mob, 0, 1, rand(15,45)) + + if(4) + if(restcure) + if(affected_mob.lying && prob(5)) + to_chat(affected_mob, "You feel better.") + cure() + return + if (prob(60)) + if(prob(50)) + scramble_dna(affected_mob, 1, 0, rand(50,75)) + else scramble_dna(affected_mob, 0, 1, rand(50,75)) \ No newline at end of file diff --git a/code/datums/diseases/rhumba_beat.dm b/code/datums/diseases/rhumba_beat.dm index da6e7da8df..1016f7b64d 100644 --- a/code/datums/diseases/rhumba_beat.dm +++ b/code/datums/diseases/rhumba_beat.dm @@ -1,45 +1,45 @@ -/datum/disease/rhumba_beat - name = "The Rhumba Beat" - max_stages = 5 - spread_text = "On contact" - spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS - cure_text = "Chick Chicky Boom!" - cures = list(/datum/reagent/toxin/plasma) - agent = "Unknown" - viable_mobtypes = list(/mob/living/carbon/human) - permeability_mod = 1 - severity = DISEASE_SEVERITY_BIOHAZARD - -/datum/disease/rhumba_beat/stage_act() - ..() - if(affected_mob.ckey == "rosham") - cure() - return - switch(stage) - if(2) - if(prob(45)) - affected_mob.adjustFireLoss(5) - affected_mob.updatehealth() - if(prob(1)) - to_chat(affected_mob, "You feel strange...") - if(3) - if(prob(5)) - to_chat(affected_mob, "You feel the urge to dance...") - else if(prob(5)) - affected_mob.emote("gasp") - else if(prob(10)) - to_chat(affected_mob, "You feel the need to chick chicky boom...") - if(4) - if(prob(20)) - if (prob(50)) - affected_mob.adjust_fire_stacks(2) - affected_mob.IgniteMob() - else - affected_mob.emote("gasp") - to_chat(affected_mob, "You feel a burning beat inside...") - if(5) - to_chat(affected_mob, "Your body is unable to contain the Rhumba Beat...") - if(prob(50)) - explosion(get_turf(affected_mob), -1, 0, 2, 3, 0, 2) // This is equivalent to a lvl 1 fireball - else - return +/datum/disease/rhumba_beat + name = "The Rhumba Beat" + max_stages = 5 + spread_text = "On contact" + spread_flags = DISEASE_SPREAD_BLOOD | DISEASE_SPREAD_CONTACT_SKIN | DISEASE_SPREAD_CONTACT_FLUIDS + cure_text = "Chick Chicky Boom!" + cures = list(/datum/reagent/toxin/plasma) + agent = "Unknown" + viable_mobtypes = list(/mob/living/carbon/human) + permeability_mod = 1 + severity = DISEASE_SEVERITY_BIOHAZARD + +/datum/disease/rhumba_beat/stage_act() + ..() + if(affected_mob.ckey == "rosham") + cure() + return + switch(stage) + if(2) + if(prob(45)) + affected_mob.adjustFireLoss(5) + affected_mob.updatehealth() + if(prob(1)) + to_chat(affected_mob, "You feel strange...") + if(3) + if(prob(5)) + to_chat(affected_mob, "You feel the urge to dance...") + else if(prob(5)) + affected_mob.emote("gasp") + else if(prob(10)) + to_chat(affected_mob, "You feel the need to chick chicky boom...") + if(4) + if(prob(20)) + if (prob(50)) + affected_mob.adjust_fire_stacks(2) + affected_mob.IgniteMob() + else + affected_mob.emote("gasp") + to_chat(affected_mob, "You feel a burning beat inside...") + if(5) + to_chat(affected_mob, "Your body is unable to contain the Rhumba Beat...") + if(prob(50)) + explosion(get_turf(affected_mob), -1, 0, 2, 3, 0, 2) // This is equivalent to a lvl 1 fireball + else + return diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm index 1c214c8516..bdb05346e4 100644 --- a/code/datums/diseases/transformation.dm +++ b/code/datums/diseases/transformation.dm @@ -1,327 +1,327 @@ -/datum/disease/transformation - name = "Transformation" - max_stages = 5 - spread_text = "Acute" - spread_flags = DISEASE_SPREAD_SPECIAL - cure_text = "A coder's love (theoretical)." - agent = "Shenanigans" - viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey, /mob/living/carbon/alien) - severity = DISEASE_SEVERITY_BIOHAZARD - stage_prob = 10 - visibility_flags = HIDDEN_SCANNER|HIDDEN_PANDEMIC - disease_flags = CURABLE - var/list/stage1 = list("You feel unremarkable.") - var/list/stage2 = list("You feel boring.") - var/list/stage3 = list("You feel utterly plain.") - var/list/stage4 = list("You feel white bread.") - var/list/stage5 = list("Oh the humanity!") - var/new_form = /mob/living/carbon/human - var/bantype - -/datum/disease/transformation/Copy() - var/datum/disease/transformation/D = ..() - D.stage1 = stage1.Copy() - D.stage2 = stage2.Copy() - D.stage3 = stage3.Copy() - D.stage4 = stage4.Copy() - D.stage5 = stage5.Copy() - D.new_form = D.new_form - return D - -/datum/disease/transformation/stage_act() - ..() - switch(stage) - if(1) - if (prob(stage_prob) && stage1) - to_chat(affected_mob, pick(stage1)) - if(2) - if (prob(stage_prob) && stage2) - to_chat(affected_mob, pick(stage2)) - if(3) - if (prob(stage_prob*2) && stage3) - to_chat(affected_mob, pick(stage3)) - if(4) - if (prob(stage_prob*2) && stage4) - to_chat(affected_mob, pick(stage4)) - if(5) - do_disease_transformation(affected_mob) - -/datum/disease/transformation/proc/do_disease_transformation(mob/living/affected_mob) - if(istype(affected_mob, /mob/living/carbon) && affected_mob.stat != DEAD) - if(stage5) - to_chat(affected_mob, pick(stage5)) - if(QDELETED(affected_mob)) - return - if(affected_mob.notransform) - return - affected_mob.notransform = 1 - for(var/obj/item/W in affected_mob.get_equipped_items(TRUE)) - affected_mob.dropItemToGround(W) - for(var/obj/item/I in affected_mob.held_items) - affected_mob.dropItemToGround(I) - var/mob/living/new_mob = new new_form(affected_mob.loc) - if(istype(new_mob)) - if(bantype && jobban_isbanned(affected_mob, bantype)) - replace_banned_player(new_mob) - new_mob.a_intent = INTENT_HARM - if(affected_mob.mind) - affected_mob.mind.transfer_to(new_mob) - else - affected_mob.transfer_ckey(new_mob) - - new_mob.name = affected_mob.real_name - new_mob.real_name = new_mob.name - qdel(affected_mob) - -/datum/disease/transformation/proc/replace_banned_player(var/mob/living/new_mob) // This can run well after the mob has been transferred, so need a handle on the new mob to kill it if needed. - set waitfor = FALSE - - var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [affected_mob.name]?", bantype, null, bantype, 50, affected_mob) - if(LAZYLEN(candidates)) - var/mob/dead/observer/C = pick(candidates) - to_chat(affected_mob, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!") - message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(affected_mob)]) to replace a jobbaned player.") - affected_mob.ghostize(0) - C.transfer_ckey(affected_mob) - else - to_chat(new_mob, "Your mob has been claimed by death! Appeal your job ban if you want to avoid this in the future!") - new_mob.death() - if (!QDELETED(new_mob)) - new_mob.ghostize(can_reenter_corpse = FALSE) - new_mob.key = null - -/datum/disease/transformation/jungle_fever - name = "Jungle Fever" - cure_text = "Death." - cures = list(/datum/reagent/medicine/adminordrazine) - spread_text = "Monkey Bites" - spread_flags = DISEASE_SPREAD_SPECIAL - viable_mobtypes = list(/mob/living/carbon/monkey, /mob/living/carbon/human) - permeability_mod = 1 - cure_chance = 1 - disease_flags = CAN_CARRY|CAN_RESIST - desc = "Monkeys with this disease will bite humans, causing humans to mutate into a monkey." - severity = DISEASE_SEVERITY_BIOHAZARD - stage_prob = 4 - visibility_flags = 0 - agent = "Kongey Vibrion M-909" - new_form = /mob/living/carbon/monkey - bantype = ROLE_MONKEY - - - stage1 = list() - stage2 = list() - stage3 = list() - stage4 = list("Your back hurts.", "You breathe through your mouth.", - "You have a craving for bananas.", "Your mind feels clouded.") - stage5 = list("You feel like monkeying around.") - -/datum/disease/transformation/jungle_fever/do_disease_transformation(mob/living/carbon/affected_mob) - if(affected_mob.mind && !is_monkey(affected_mob.mind)) - add_monkey(affected_mob.mind) - if(ishuman(affected_mob)) - var/mob/living/carbon/monkey/M = affected_mob.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE) - M.ventcrawler = VENTCRAWLER_ALWAYS - - -/datum/disease/transformation/jungle_fever/stage_act() - ..() - switch(stage) - if(2) - if(prob(2)) - to_chat(affected_mob, "Your [pick("back", "arm", "leg", "elbow", "head")] itches.") - if(3) - if(prob(4)) - to_chat(affected_mob, "You feel a stabbing pain in your head.") - affected_mob.confused += 10 - if(4) - if(prob(3)) - affected_mob.say(pick("Eeek, ook ook!", "Eee-eeek!", "Eeee!", "Ungh, ungh."), forced = "jungle fever") - -/datum/disease/transformation/jungle_fever/cure() - remove_monkey(affected_mob.mind) - ..() - -/datum/disease/transformation/jungle_fever/monkeymode - visibility_flags = HIDDEN_SCANNER|HIDDEN_PANDEMIC - disease_flags = CAN_CARRY //no vaccines! no cure! - -/datum/disease/transformation/jungle_fever/monkeymode/after_add() - if(affected_mob && !is_monkey_leader(affected_mob.mind)) - visibility_flags = NONE - - - -/datum/disease/transformation/robot - - name = "Robotic Transformation" - cure_text = "An injection of copper." - cures = list(/datum/reagent/copper) - cure_chance = 5 - agent = "R2D2 Nanomachines" - desc = "This disease, actually acute nanomachine infection, converts the victim into a cyborg." - severity = DISEASE_SEVERITY_BIOHAZARD - visibility_flags = 0 - stage1 = list() - stage2 = list("Your joints feel stiff.", "Beep...boop..") - stage3 = list("Your joints feel very stiff.", "Your skin feels loose.", "You can feel something move...inside.") - stage4 = list("Your skin feels very loose.", "You can feel... something...inside you.") - stage5 = list("Your skin feels as if it's about to burst off!") - new_form = /mob/living/silicon/robot - infectable_biotypes = list(MOB_ORGANIC, MOB_UNDEAD, MOB_ROBOTIC) - bantype = "Cyborg" - -/datum/disease/transformation/robot/stage_act() - ..() - switch(stage) - if(3) - if (prob(8)) - affected_mob.say(pick("Beep, boop", "beep, beep!", "Boop...bop"), forced = "robotic transformation") - if (prob(4)) - to_chat(affected_mob, "You feel a stabbing pain in your head.") - affected_mob.Unconscious(40) - if(4) - if (prob(20)) - affected_mob.say(pick("beep, beep!", "Boop bop boop beep.", "kkkiiiill mmme", "I wwwaaannntt tttoo dddiiieeee..."), forced = "robotic transformation") - - -/datum/disease/transformation/xeno - - name = "Xenomorph Transformation" - cure_text = "Spaceacillin & Glycerol" - cures = list(/datum/reagent/medicine/spaceacillin, /datum/reagent/glycerol) - cure_chance = 5 - agent = "Rip-LEY Alien Microbes" - desc = "This disease changes the victim into a xenomorph." - severity = DISEASE_SEVERITY_BIOHAZARD - visibility_flags = 0 - stage1 = list() - stage2 = list("Your throat feels scratchy.", "Kill...") - stage3 = list("Your throat feels very scratchy.", "Your skin feels tight.", "You can feel something move...inside.") - stage4 = list("Your skin feels very tight.", "Your blood boils!", "You can feel... something...inside you.") - stage5 = list("Your skin feels as if it's about to burst off!") - new_form = /mob/living/carbon/alien/humanoid/hunter - bantype = ROLE_ALIEN - -/datum/disease/transformation/xeno/stage_act() - ..() - switch(stage) - if(3) - if (prob(4)) - to_chat(affected_mob, "You feel a stabbing pain in your head.") - affected_mob.Unconscious(40) - if(4) - if (prob(20)) - affected_mob.say(pick("You look delicious.", "Going to... devour you...", "Hsssshhhhh!"), forced = "xenomorph transformation") - - -/datum/disease/transformation/slime - name = "Advanced Mutation Transformation" - cure_text = "frost oil" - cures = list(/datum/reagent/consumable/frostoil) - cure_chance = 80 - agent = "Advanced Mutation Toxin" - desc = "This highly concentrated extract converts anything into more of itself." - severity = DISEASE_SEVERITY_BIOHAZARD - visibility_flags = 0 - stage1 = list("You don't feel very well.") - stage2 = list("Your skin feels a little slimy.") - stage3 = list("Your appendages are melting away.", "Your limbs begin to lose their shape.") - stage4 = list("You are turning into a slime.") - stage5 = list("You have become a slime.") - new_form = /mob/living/simple_animal/slime/random - -/datum/disease/transformation/slime/stage_act() - ..() - switch(stage) - if(1) - if(ishuman(affected_mob) && affected_mob.dna) - if(affected_mob.dna.species.id == "slime" || affected_mob.dna.species.id == "stargazer" || affected_mob.dna.species.id == "lum") - stage = 5 - if(3) - if(ishuman(affected_mob)) - var/mob/living/carbon/human/human = affected_mob - if(human.dna.species.id != "slime" && affected_mob.dna.species.id != "stargazer" && affected_mob.dna.species.id != "lum") - human.set_species(/datum/species/jelly/slime) - -/datum/disease/transformation/corgi - name = "The Barkening" - cure_text = "Death" - cures = list(/datum/reagent/medicine/adminordrazine) - agent = "Fell Doge Majicks" - desc = "This disease transforms the victim into a corgi." - severity = DISEASE_SEVERITY_BIOHAZARD - visibility_flags = 0 - stage1 = list("BARK.") - stage2 = list("You feel the need to wear silly hats.") - stage3 = list("Must... eat... chocolate....", "YAP") - stage4 = list("Visions of washing machines assail your mind!") - stage5 = list("AUUUUUU!!!") - new_form = /mob/living/simple_animal/pet/dog/corgi - -/datum/disease/transformation/corgi/stage_act() - ..() - switch(stage) - if(3) - if (prob(8)) - affected_mob.say(pick("YAP", "Woof!"), forced = "corgi transformation") - if(4) - if (prob(20)) - affected_mob.say(pick("Bark!", "AUUUUUU"), forced = "corgi transformation") - -/datum/disease/transformation/morph - name = "Gluttony's Blessing" - cure_text = "nothing" - cures = list(/datum/reagent/medicine/adminordrazine) - agent = "Gluttony's Blessing" - desc = "A 'gift' from somewhere terrible." - stage_prob = 20 - severity = DISEASE_SEVERITY_BIOHAZARD - visibility_flags = 0 - stage1 = list("Your stomach rumbles.") - stage2 = list("Your skin feels saggy.") - stage3 = list("Your appendages are melting away.", "Your limbs begin to lose their shape.") - stage4 = list("You're ravenous.") - stage5 = list("You have become a morph.") - new_form = /mob/living/simple_animal/hostile/morph - infectable_biotypes = list(MOB_ORGANIC, MOB_INORGANIC, MOB_UNDEAD) //magic! - -/datum/disease/transformation/gondola - name = "Gondola Transformation" - cure_text = "Condensed Capsaicin, ingested or injected." //getting pepper sprayed doesn't help - cures = list(/datum/reagent/consumable/condensedcapsaicin) //beats the hippie crap right out of your system - cure_chance = 80 - stage_prob = 5 - agent = "Tranquility" - desc = "Consuming the flesh of a Gondola comes at a terrible price." - severity = DISEASE_SEVERITY_BIOHAZARD - visibility_flags = 0 - stage1 = list("You seem a little lighter in your step.") - stage2 = list("You catch yourself smiling for no reason.") - stage3 = list("A cruel sense of calm overcomes you.", "You can't feel your arms!", "You let go of the urge to hurt clowns.") - stage4 = list("You can't feel your arms. It does not bother you anymore.", "You forgive the clown for hurting you.") - stage5 = list("You have become a Gondola.") - new_form = /mob/living/simple_animal/pet/gondola - -/datum/disease/transformation/gondola/stage_act() - ..() - switch(stage) - if(2) - if (prob(5)) - affected_mob.emote("smile") - if (prob(20)) - affected_mob.reagents.add_reagent(/datum/reagent/pax, 5) - if(3) - if (prob(5)) - affected_mob.emote("smile") - if (prob(20)) - affected_mob.reagents.add_reagent(/datum/reagent/pax, 5) - if(4) - if (prob(5)) - affected_mob.emote("smile") - if (prob(20)) - affected_mob.reagents.add_reagent(/datum/reagent/pax, 5) - if (prob(2)) - to_chat(affected_mob, "You let go of what you were holding.") - var/obj/item/I = affected_mob.get_active_held_item() - affected_mob.dropItemToGround(I) +/datum/disease/transformation + name = "Transformation" + max_stages = 5 + spread_text = "Acute" + spread_flags = DISEASE_SPREAD_SPECIAL + cure_text = "A coder's love (theoretical)." + agent = "Shenanigans" + viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey, /mob/living/carbon/alien) + severity = DISEASE_SEVERITY_BIOHAZARD + stage_prob = 10 + visibility_flags = HIDDEN_SCANNER|HIDDEN_PANDEMIC + disease_flags = CURABLE + var/list/stage1 = list("You feel unremarkable.") + var/list/stage2 = list("You feel boring.") + var/list/stage3 = list("You feel utterly plain.") + var/list/stage4 = list("You feel white bread.") + var/list/stage5 = list("Oh the humanity!") + var/new_form = /mob/living/carbon/human + var/bantype + +/datum/disease/transformation/Copy() + var/datum/disease/transformation/D = ..() + D.stage1 = stage1.Copy() + D.stage2 = stage2.Copy() + D.stage3 = stage3.Copy() + D.stage4 = stage4.Copy() + D.stage5 = stage5.Copy() + D.new_form = D.new_form + return D + +/datum/disease/transformation/stage_act() + ..() + switch(stage) + if(1) + if (prob(stage_prob) && stage1) + to_chat(affected_mob, pick(stage1)) + if(2) + if (prob(stage_prob) && stage2) + to_chat(affected_mob, pick(stage2)) + if(3) + if (prob(stage_prob*2) && stage3) + to_chat(affected_mob, pick(stage3)) + if(4) + if (prob(stage_prob*2) && stage4) + to_chat(affected_mob, pick(stage4)) + if(5) + do_disease_transformation(affected_mob) + +/datum/disease/transformation/proc/do_disease_transformation(mob/living/affected_mob) + if(istype(affected_mob, /mob/living/carbon) && affected_mob.stat != DEAD) + if(stage5) + to_chat(affected_mob, pick(stage5)) + if(QDELETED(affected_mob)) + return + if(affected_mob.notransform) + return + affected_mob.notransform = 1 + for(var/obj/item/W in affected_mob.get_equipped_items(TRUE)) + affected_mob.dropItemToGround(W) + for(var/obj/item/I in affected_mob.held_items) + affected_mob.dropItemToGround(I) + var/mob/living/new_mob = new new_form(affected_mob.loc) + if(istype(new_mob)) + if(bantype && jobban_isbanned(affected_mob, bantype)) + replace_banned_player(new_mob) + new_mob.a_intent = INTENT_HARM + if(affected_mob.mind) + affected_mob.mind.transfer_to(new_mob) + else + affected_mob.transfer_ckey(new_mob) + + new_mob.name = affected_mob.real_name + new_mob.real_name = new_mob.name + qdel(affected_mob) + +/datum/disease/transformation/proc/replace_banned_player(var/mob/living/new_mob) // This can run well after the mob has been transferred, so need a handle on the new mob to kill it if needed. + set waitfor = FALSE + + var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [affected_mob.name]?", bantype, null, bantype, 50, affected_mob) + if(LAZYLEN(candidates)) + var/mob/dead/observer/C = pick(candidates) + to_chat(affected_mob, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!") + message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(affected_mob)]) to replace a jobbaned player.") + affected_mob.ghostize(0) + C.transfer_ckey(affected_mob) + else + to_chat(new_mob, "Your mob has been claimed by death! Appeal your job ban if you want to avoid this in the future!") + new_mob.death() + if (!QDELETED(new_mob)) + new_mob.ghostize(can_reenter_corpse = FALSE) + new_mob.key = null + +/datum/disease/transformation/jungle_fever + name = "Jungle Fever" + cure_text = "Death." + cures = list(/datum/reagent/medicine/adminordrazine) + spread_text = "Monkey Bites" + spread_flags = DISEASE_SPREAD_SPECIAL + viable_mobtypes = list(/mob/living/carbon/monkey, /mob/living/carbon/human) + permeability_mod = 1 + cure_chance = 1 + disease_flags = CAN_CARRY|CAN_RESIST + desc = "Monkeys with this disease will bite humans, causing humans to mutate into a monkey." + severity = DISEASE_SEVERITY_BIOHAZARD + stage_prob = 4 + visibility_flags = 0 + agent = "Kongey Vibrion M-909" + new_form = /mob/living/carbon/monkey + bantype = ROLE_MONKEY + + + stage1 = list() + stage2 = list() + stage3 = list() + stage4 = list("Your back hurts.", "You breathe through your mouth.", + "You have a craving for bananas.", "Your mind feels clouded.") + stage5 = list("You feel like monkeying around.") + +/datum/disease/transformation/jungle_fever/do_disease_transformation(mob/living/carbon/affected_mob) + if(affected_mob.mind && !is_monkey(affected_mob.mind)) + add_monkey(affected_mob.mind) + if(ishuman(affected_mob)) + var/mob/living/carbon/monkey/M = affected_mob.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE) + M.ventcrawler = VENTCRAWLER_ALWAYS + + +/datum/disease/transformation/jungle_fever/stage_act() + ..() + switch(stage) + if(2) + if(prob(2)) + to_chat(affected_mob, "Your [pick("back", "arm", "leg", "elbow", "head")] itches.") + if(3) + if(prob(4)) + to_chat(affected_mob, "You feel a stabbing pain in your head.") + affected_mob.confused += 10 + if(4) + if(prob(3)) + affected_mob.say(pick("Eeek, ook ook!", "Eee-eeek!", "Eeee!", "Ungh, ungh."), forced = "jungle fever") + +/datum/disease/transformation/jungle_fever/cure() + remove_monkey(affected_mob.mind) + ..() + +/datum/disease/transformation/jungle_fever/monkeymode + visibility_flags = HIDDEN_SCANNER|HIDDEN_PANDEMIC + disease_flags = CAN_CARRY //no vaccines! no cure! + +/datum/disease/transformation/jungle_fever/monkeymode/after_add() + if(affected_mob && !is_monkey_leader(affected_mob.mind)) + visibility_flags = NONE + + + +/datum/disease/transformation/robot + + name = "Robotic Transformation" + cure_text = "An injection of copper." + cures = list(/datum/reagent/copper) + cure_chance = 5 + agent = "R2D2 Nanomachines" + desc = "This disease, actually acute nanomachine infection, converts the victim into a cyborg." + severity = DISEASE_SEVERITY_BIOHAZARD + visibility_flags = 0 + stage1 = list() + stage2 = list("Your joints feel stiff.", "Beep...boop..") + stage3 = list("Your joints feel very stiff.", "Your skin feels loose.", "You can feel something move...inside.") + stage4 = list("Your skin feels very loose.", "You can feel... something...inside you.") + stage5 = list("Your skin feels as if it's about to burst off!") + new_form = /mob/living/silicon/robot + infectable_biotypes = list(MOB_ORGANIC, MOB_UNDEAD, MOB_ROBOTIC) + bantype = "Cyborg" + +/datum/disease/transformation/robot/stage_act() + ..() + switch(stage) + if(3) + if (prob(8)) + affected_mob.say(pick("Beep, boop", "beep, beep!", "Boop...bop"), forced = "robotic transformation") + if (prob(4)) + to_chat(affected_mob, "You feel a stabbing pain in your head.") + affected_mob.Unconscious(40) + if(4) + if (prob(20)) + affected_mob.say(pick("beep, beep!", "Boop bop boop beep.", "kkkiiiill mmme", "I wwwaaannntt tttoo dddiiieeee..."), forced = "robotic transformation") + + +/datum/disease/transformation/xeno + + name = "Xenomorph Transformation" + cure_text = "Spaceacillin & Glycerol" + cures = list(/datum/reagent/medicine/spaceacillin, /datum/reagent/glycerol) + cure_chance = 5 + agent = "Rip-LEY Alien Microbes" + desc = "This disease changes the victim into a xenomorph." + severity = DISEASE_SEVERITY_BIOHAZARD + visibility_flags = 0 + stage1 = list() + stage2 = list("Your throat feels scratchy.", "Kill...") + stage3 = list("Your throat feels very scratchy.", "Your skin feels tight.", "You can feel something move...inside.") + stage4 = list("Your skin feels very tight.", "Your blood boils!", "You can feel... something...inside you.") + stage5 = list("Your skin feels as if it's about to burst off!") + new_form = /mob/living/carbon/alien/humanoid/hunter + bantype = ROLE_ALIEN + +/datum/disease/transformation/xeno/stage_act() + ..() + switch(stage) + if(3) + if (prob(4)) + to_chat(affected_mob, "You feel a stabbing pain in your head.") + affected_mob.Unconscious(40) + if(4) + if (prob(20)) + affected_mob.say(pick("You look delicious.", "Going to... devour you...", "Hsssshhhhh!"), forced = "xenomorph transformation") + + +/datum/disease/transformation/slime + name = "Advanced Mutation Transformation" + cure_text = "frost oil" + cures = list(/datum/reagent/consumable/frostoil) + cure_chance = 80 + agent = "Advanced Mutation Toxin" + desc = "This highly concentrated extract converts anything into more of itself." + severity = DISEASE_SEVERITY_BIOHAZARD + visibility_flags = 0 + stage1 = list("You don't feel very well.") + stage2 = list("Your skin feels a little slimy.") + stage3 = list("Your appendages are melting away.", "Your limbs begin to lose their shape.") + stage4 = list("You are turning into a slime.") + stage5 = list("You have become a slime.") + new_form = /mob/living/simple_animal/slime/random + +/datum/disease/transformation/slime/stage_act() + ..() + switch(stage) + if(1) + if(ishuman(affected_mob) && affected_mob.dna) + if(affected_mob.dna.species.id == "slime" || affected_mob.dna.species.id == "stargazer" || affected_mob.dna.species.id == "lum") + stage = 5 + if(3) + if(ishuman(affected_mob)) + var/mob/living/carbon/human/human = affected_mob + if(human.dna.species.id != "slime" && affected_mob.dna.species.id != "stargazer" && affected_mob.dna.species.id != "lum") + human.set_species(/datum/species/jelly/slime) + +/datum/disease/transformation/corgi + name = "The Barkening" + cure_text = "Death" + cures = list(/datum/reagent/medicine/adminordrazine) + agent = "Fell Doge Majicks" + desc = "This disease transforms the victim into a corgi." + severity = DISEASE_SEVERITY_BIOHAZARD + visibility_flags = 0 + stage1 = list("BARK.") + stage2 = list("You feel the need to wear silly hats.") + stage3 = list("Must... eat... chocolate....", "YAP") + stage4 = list("Visions of washing machines assail your mind!") + stage5 = list("AUUUUUU!!!") + new_form = /mob/living/simple_animal/pet/dog/corgi + +/datum/disease/transformation/corgi/stage_act() + ..() + switch(stage) + if(3) + if (prob(8)) + affected_mob.say(pick("YAP", "Woof!"), forced = "corgi transformation") + if(4) + if (prob(20)) + affected_mob.say(pick("Bark!", "AUUUUUU"), forced = "corgi transformation") + +/datum/disease/transformation/morph + name = "Gluttony's Blessing" + cure_text = "nothing" + cures = list(/datum/reagent/medicine/adminordrazine) + agent = "Gluttony's Blessing" + desc = "A 'gift' from somewhere terrible." + stage_prob = 20 + severity = DISEASE_SEVERITY_BIOHAZARD + visibility_flags = 0 + stage1 = list("Your stomach rumbles.") + stage2 = list("Your skin feels saggy.") + stage3 = list("Your appendages are melting away.", "Your limbs begin to lose their shape.") + stage4 = list("You're ravenous.") + stage5 = list("You have become a morph.") + new_form = /mob/living/simple_animal/hostile/morph + infectable_biotypes = list(MOB_ORGANIC, MOB_INORGANIC, MOB_UNDEAD) //magic! + +/datum/disease/transformation/gondola + name = "Gondola Transformation" + cure_text = "Condensed Capsaicin, ingested or injected." //getting pepper sprayed doesn't help + cures = list(/datum/reagent/consumable/condensedcapsaicin) //beats the hippie crap right out of your system + cure_chance = 80 + stage_prob = 5 + agent = "Tranquility" + desc = "Consuming the flesh of a Gondola comes at a terrible price." + severity = DISEASE_SEVERITY_BIOHAZARD + visibility_flags = 0 + stage1 = list("You seem a little lighter in your step.") + stage2 = list("You catch yourself smiling for no reason.") + stage3 = list("A cruel sense of calm overcomes you.", "You can't feel your arms!", "You let go of the urge to hurt clowns.") + stage4 = list("You can't feel your arms. It does not bother you anymore.", "You forgive the clown for hurting you.") + stage5 = list("You have become a Gondola.") + new_form = /mob/living/simple_animal/pet/gondola + +/datum/disease/transformation/gondola/stage_act() + ..() + switch(stage) + if(2) + if (prob(5)) + affected_mob.emote("smile") + if (prob(20)) + affected_mob.reagents.add_reagent(/datum/reagent/pax, 5) + if(3) + if (prob(5)) + affected_mob.emote("smile") + if (prob(20)) + affected_mob.reagents.add_reagent(/datum/reagent/pax, 5) + if(4) + if (prob(5)) + affected_mob.emote("smile") + if (prob(20)) + affected_mob.reagents.add_reagent(/datum/reagent/pax, 5) + if (prob(2)) + to_chat(affected_mob, "You let go of what you were holding.") + var/obj/item/I = affected_mob.get_active_held_item() + affected_mob.dropItemToGround(I) diff --git a/code/datums/diseases/wizarditis.dm b/code/datums/diseases/wizarditis.dm index 244cc819d8..230a074bb1 100644 --- a/code/datums/diseases/wizarditis.dm +++ b/code/datums/diseases/wizarditis.dm @@ -1,117 +1,117 @@ -/datum/disease/wizarditis - name = "Wizarditis" - max_stages = 4 - spread_text = "Airborne" - cure_text = "The Manly Dorf" - cures = list(/datum/reagent/consumable/ethanol/manly_dorf) - cure_chance = 100 - agent = "Rincewindus Vulgaris" - viable_mobtypes = list(/mob/living/carbon/human) - disease_flags = CAN_CARRY|CAN_RESIST|CURABLE - permeability_mod = 0.75 - desc = "Some speculate that this virus is the cause of the Space Wizard Federation's existence. Subjects affected show the signs of mental retardation, yelling obscure sentences or total gibberish. On late stages subjects sometime express the feelings of inner power, and, cite, 'the ability to control the forces of cosmos themselves!' A gulp of strong, manly spirits usually reverts them to normal, humanlike, condition." - severity = DISEASE_SEVERITY_HARMFUL - required_organs = list(/obj/item/bodypart/head) - -/* -BIRUZ BENNAR -SCYAR NILA - teleport -NEC CANTIO - dis techno -EI NATH - shocking grasp -AULIE OXIN FIERA - knock -TARCOL MINTI ZHERI - forcewall -STI KALY - blind -*/ - -/datum/disease/wizarditis/stage_act() - ..() - - switch(stage) - if(2) - if(prob(1)&&prob(50)) - affected_mob.say(pick("You shall not pass!", "Expeliarmus!", "By Merlins beard!", "Feel the power of the Dark Side!"), forced = "wizarditis") - if(prob(1)&&prob(50)) - to_chat(affected_mob, "You feel [pick("that you don't have enough mana", "that the winds of magic are gone", "an urge to summon familiar")].") - - - if(3) - if(prob(1)&&prob(50)) - affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!", "STI KALY!", "TARCOL MINTI ZHERI!"), forced = "wizarditis") - if(prob(1)&&prob(50)) - to_chat(affected_mob, "You feel [pick("the magic bubbling in your veins","that this location gives you a +1 to INT","an urge to summon familiar")].") - - if(4) - - if(prob(1)) - affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!","STI KALY!","EI NATH!"), forced = "wizarditis") - return - if(prob(1)&&prob(50)) - to_chat(affected_mob, "You feel [pick("the tidal wave of raw power building inside","that this location gives you a +2 to INT and +1 to WIS","an urge to teleport")].") - spawn_wizard_clothes(50) - if(prob(1)&&prob(1)) - teleport() - return - - - -/datum/disease/wizarditis/proc/spawn_wizard_clothes(chance = 0) - if(ishuman(affected_mob)) - var/mob/living/carbon/human/H = affected_mob - if(prob(chance)) - if(!istype(H.head, /obj/item/clothing/head/wizard)) - if(!H.dropItemToGround(H.head)) - qdel(H.head) - H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(H), SLOT_HEAD) - return - if(prob(chance)) - if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe)) - if(!H.dropItemToGround(H.wear_suit)) - qdel(H.wear_suit) - H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(H), SLOT_WEAR_SUIT) - return - if(prob(chance)) - if(!istype(H.shoes, /obj/item/clothing/shoes/sandal/magic)) - if(!H.dropItemToGround(H.shoes)) - qdel(H.shoes) - H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(H), SLOT_SHOES) - return - else - var/mob/living/carbon/H = affected_mob - if(prob(chance)) - var/obj/item/staff/S = new(H) - if(!H.put_in_hands(S)) - qdel(S) - - -/datum/disease/wizarditis/proc/teleport() - var/list/theareas = get_areas_in_range(80, affected_mob) - for(var/area/space/S in theareas) - theareas -= S - - if(!theareas||!theareas.len) - return - - var/area/thearea = pick(theareas) - - var/list/L = list() - for(var/turf/T in get_area_turfs(thearea.type)) - if(T.z != affected_mob.z) - continue - if(T.name == "space") - continue - if(!T.density) - var/clear = 1 - for(var/obj/O in T) - if(O.density) - clear = 0 - break - if(clear) - L+=T - - if(!L) - return - - affected_mob.say("SCYAR NILA [uppertext(thearea.name)]!", forced = "wizarditis teleport") - affected_mob.forceMove(pick(L)) - - return +/datum/disease/wizarditis + name = "Wizarditis" + max_stages = 4 + spread_text = "Airborne" + cure_text = "The Manly Dorf" + cures = list(/datum/reagent/consumable/ethanol/manly_dorf) + cure_chance = 100 + agent = "Rincewindus Vulgaris" + viable_mobtypes = list(/mob/living/carbon/human) + disease_flags = CAN_CARRY|CAN_RESIST|CURABLE + permeability_mod = 0.75 + desc = "Some speculate that this virus is the cause of the Space Wizard Federation's existence. Subjects affected show the signs of mental retardation, yelling obscure sentences or total gibberish. On late stages subjects sometime express the feelings of inner power, and, cite, 'the ability to control the forces of cosmos themselves!' A gulp of strong, manly spirits usually reverts them to normal, humanlike, condition." + severity = DISEASE_SEVERITY_HARMFUL + required_organs = list(/obj/item/bodypart/head) + +/* +BIRUZ BENNAR +SCYAR NILA - teleport +NEC CANTIO - dis techno +EI NATH - shocking grasp +AULIE OXIN FIERA - knock +TARCOL MINTI ZHERI - forcewall +STI KALY - blind +*/ + +/datum/disease/wizarditis/stage_act() + ..() + + switch(stage) + if(2) + if(prob(1)&&prob(50)) + affected_mob.say(pick("You shall not pass!", "Expeliarmus!", "By Merlins beard!", "Feel the power of the Dark Side!"), forced = "wizarditis") + if(prob(1)&&prob(50)) + to_chat(affected_mob, "You feel [pick("that you don't have enough mana", "that the winds of magic are gone", "an urge to summon familiar")].") + + + if(3) + if(prob(1)&&prob(50)) + affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!", "STI KALY!", "TARCOL MINTI ZHERI!"), forced = "wizarditis") + if(prob(1)&&prob(50)) + to_chat(affected_mob, "You feel [pick("the magic bubbling in your veins","that this location gives you a +1 to INT","an urge to summon familiar")].") + + if(4) + + if(prob(1)) + affected_mob.say(pick("NEC CANTIO!","AULIE OXIN FIERA!","STI KALY!","EI NATH!"), forced = "wizarditis") + return + if(prob(1)&&prob(50)) + to_chat(affected_mob, "You feel [pick("the tidal wave of raw power building inside","that this location gives you a +2 to INT and +1 to WIS","an urge to teleport")].") + spawn_wizard_clothes(50) + if(prob(1)&&prob(1)) + teleport() + return + + + +/datum/disease/wizarditis/proc/spawn_wizard_clothes(chance = 0) + if(ishuman(affected_mob)) + var/mob/living/carbon/human/H = affected_mob + if(prob(chance)) + if(!istype(H.head, /obj/item/clothing/head/wizard)) + if(!H.dropItemToGround(H.head)) + qdel(H.head) + H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(H), SLOT_HEAD) + return + if(prob(chance)) + if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe)) + if(!H.dropItemToGround(H.wear_suit)) + qdel(H.wear_suit) + H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(H), SLOT_WEAR_SUIT) + return + if(prob(chance)) + if(!istype(H.shoes, /obj/item/clothing/shoes/sandal/magic)) + if(!H.dropItemToGround(H.shoes)) + qdel(H.shoes) + H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(H), SLOT_SHOES) + return + else + var/mob/living/carbon/H = affected_mob + if(prob(chance)) + var/obj/item/staff/S = new(H) + if(!H.put_in_hands(S)) + qdel(S) + + +/datum/disease/wizarditis/proc/teleport() + var/list/theareas = get_areas_in_range(80, affected_mob) + for(var/area/space/S in theareas) + theareas -= S + + if(!theareas||!theareas.len) + return + + var/area/thearea = pick(theareas) + + var/list/L = list() + for(var/turf/T in get_area_turfs(thearea.type)) + if(T.z != affected_mob.z) + continue + if(T.name == "space") + continue + if(!T.density) + var/clear = 1 + for(var/obj/O in T) + if(O.density) + clear = 0 + break + if(clear) + L+=T + + if(!L) + return + + affected_mob.say("SCYAR NILA [uppertext(thearea.name)]!", forced = "wizarditis teleport") + affected_mob.forceMove(pick(L)) + + return diff --git a/code/datums/dna.dm b/code/datums/dna.dm index ccc5d97cf8..67dbbdfef7 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -1,435 +1,435 @@ - -/////////////////////////// DNA DATUM -/datum/dna - var/unique_enzymes - var/struc_enzymes - var/uni_identity - var/blood_type - var/datum/species/species = new /datum/species/human //The type of mutant race the player is if applicable (i.e. potato-man) - var/list/features = list("FFF") //first value is mutant color - var/real_name //Stores the real name of the person who originally got this dna datum. Used primarely for changelings, - var/nameless = FALSE - var/custom_species //siiiiigh I guess this is important - var/list/mutations = list() //All mutations are from now on here - var/list/temporary_mutations = list() //Timers for temporary mutations - var/list/previous = list() //For temporary name/ui/ue/blood_type modifications - var/mob/living/holder - var/delete_species = TRUE //Set to FALSE when a body is scanned by a cloner to fix #38875 - -/datum/dna/New(mob/living/new_holder) - if(istype(new_holder)) - holder = new_holder - -/datum/dna/Destroy() - if(iscarbon(holder)) - var/mob/living/carbon/cholder = holder - if(cholder.dna == src) - cholder.dna = null - holder = null - - if(delete_species) - QDEL_NULL(species) - - mutations.Cut() //This only references mutations, just dereference. - temporary_mutations.Cut() //^ - previous.Cut() //^ - - return ..() - -/datum/dna/proc/transfer_identity(mob/living/carbon/destination, transfer_SE = 0) - if(!istype(destination)) - return - destination.dna.unique_enzymes = unique_enzymes - destination.dna.uni_identity = uni_identity - destination.dna.blood_type = blood_type - destination.dna.features = features.Copy() - destination.set_species(species.type, icon_update=0) - destination.dna.real_name = real_name - destination.dna.nameless = nameless - destination.dna.custom_species = custom_species - destination.dna.temporary_mutations = temporary_mutations.Copy() - if(ishuman(destination)) - var/mob/living/carbon/human/H = destination - H.give_genitals(TRUE)//This gives the body the genitals of this DNA. Used for any transformations based on DNA - destination.flavor_text = destination.dna.features["flavor_text"] //Update the flavor_text to use new dna text - if(transfer_SE) - destination.dna.struc_enzymes = struc_enzymes - -/datum/dna/proc/copy_dna(datum/dna/new_dna) - new_dna.unique_enzymes = unique_enzymes - new_dna.struc_enzymes = struc_enzymes - new_dna.uni_identity = uni_identity - new_dna.blood_type = blood_type - new_dna.features = features.Copy() - new_dna.species = new species.type - new_dna.real_name = real_name - new_dna.nameless = nameless - new_dna.custom_species = custom_species - new_dna.mutations = mutations.Copy() - -/datum/dna/proc/add_mutation(mutation_name) - var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name] - HM.on_acquiring(holder) - -/datum/dna/proc/remove_mutation(mutation_name) - var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name] - HM.on_losing(holder) - -/datum/dna/proc/check_mutation(mutation_name) - var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name] - return mutations.Find(HM) - -/datum/dna/proc/remove_all_mutations() - remove_mutation_group(mutations) - -/datum/dna/proc/remove_mutation_group(list/group) - if(!group) - return - for(var/datum/mutation/human/HM in group) - HM.force_lose(holder) - -/datum/dna/proc/generate_uni_identity() - . = "" - var/list/L = new /list(DNA_UNI_IDENTITY_BLOCKS) - - L[DNA_GENDER_BLOCK] = construct_block((holder.gender!=MALE)+1, 2) - if(ishuman(holder)) - var/mob/living/carbon/human/H = holder - if(!GLOB.hair_styles_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/hair,GLOB.hair_styles_list, GLOB.hair_styles_male_list, GLOB.hair_styles_female_list) - L[DNA_HAIR_STYLE_BLOCK] = construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len) - L[DNA_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.hair_color) - if(!GLOB.facial_hair_styles_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list) - L[DNA_FACIAL_HAIR_STYLE_BLOCK] = construct_block(GLOB.facial_hair_styles_list.Find(H.facial_hair_style), GLOB.facial_hair_styles_list.len) - L[DNA_FACIAL_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.facial_hair_color) - L[DNA_SKIN_TONE_BLOCK] = construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len) - L[DNA_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.eye_color) - L[DNA_COLOR_ONE_BLOCK] = sanitize_hexcolor(features["mcolor"]) - L[DNA_COLOR_TWO_BLOCK] = sanitize_hexcolor(features["mcolor2"]) - L[DNA_COLOR_THREE_BLOCK] = sanitize_hexcolor(features["mcolor3"]) - if(!GLOB.mam_tails_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails, GLOB.mam_tails_list) - L[DNA_MUTANTTAIL_BLOCK] = construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len) - if(!GLOB.mam_ears_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_ears, GLOB.mam_ears_list) - L[DNA_MUTANTEAR_BLOCK] = construct_block(GLOB.mam_ears_list.Find(features["mam_ears"]), GLOB.mam_ears_list.len) - if(!GLOB.mam_body_markings_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_body_markings, GLOB.mam_body_markings_list) - L[DNA_MUTANTMARKING_BLOCK] = construct_block(GLOB.mam_body_markings_list.Find(features["mam_body_markings"]), GLOB.mam_body_markings_list.len) - if(!GLOB.taur_list.len) - init_sprite_accessory_subtypes(/datum/sprite_accessory/taur, GLOB.taur_list) - L[DNA_TAUR_BLOCK] = construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len) - - for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++) - if(L[i]) - . += L[i] - else - . += random_string(DNA_BLOCK_SIZE,GLOB.hex_characters) - return . - -/datum/dna/proc/generate_struc_enzymes() - var/list/sorting = new /list(DNA_STRUC_ENZYMES_BLOCKS) - var/result = "" - for(var/datum/mutation/human/A in GLOB.good_mutations + GLOB.bad_mutations + GLOB.not_good_mutations) - if(A.name == RACEMUT && ismonkey(holder)) - sorting[A.dna_block] = num2hex(A.lowest_value + rand(0, 256 * 6), DNA_BLOCK_SIZE) - mutations |= A - else - sorting[A.dna_block] = random_string(DNA_BLOCK_SIZE, list("0","1","2","3","4","5","6")) - - for(var/B in sorting) - result += B - return result - -/datum/dna/proc/generate_unique_enzymes() - . = "" - if(istype(holder)) - real_name = holder.real_name - . += md5(holder.real_name) - else - . += random_string(DNA_UNIQUE_ENZYMES_LEN, GLOB.hex_characters) - return . - -/datum/dna/proc/update_ui_block(blocknumber) - if(!blocknumber || !ishuman(holder)) - return - var/mob/living/carbon/human/H = holder - switch(blocknumber) - if(DNA_HAIR_COLOR_BLOCK) - setblock(uni_identity, blocknumber, sanitize_hexcolor(H.hair_color)) - if(DNA_FACIAL_HAIR_COLOR_BLOCK) - setblock(uni_identity, blocknumber, sanitize_hexcolor(H.facial_hair_color)) - if(DNA_SKIN_TONE_BLOCK) - setblock(uni_identity, blocknumber, construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len)) - if(DNA_EYE_COLOR_BLOCK) - setblock(uni_identity, blocknumber, sanitize_hexcolor(H.eye_color)) - if(DNA_GENDER_BLOCK) - setblock(uni_identity, blocknumber, construct_block((H.gender!=MALE)+1, 2)) - if(DNA_FACIAL_HAIR_STYLE_BLOCK) - setblock(uni_identity, blocknumber, construct_block(GLOB.facial_hair_styles_list.Find(H.facial_hair_style), GLOB.facial_hair_styles_list.len)) - if(DNA_HAIR_STYLE_BLOCK) - setblock(uni_identity, blocknumber, construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len)) - if(DNA_COLOR_ONE_BLOCK) - sanitize_hexcolor(features["mcolor"]) - if(DNA_COLOR_TWO_BLOCK) - sanitize_hexcolor(features["mcolor2"]) - if(DNA_COLOR_THREE_BLOCK) - sanitize_hexcolor(features["mcolor3"]) - if(DNA_MUTANTTAIL_BLOCK) - construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len) - if(DNA_MUTANTEAR_BLOCK) - construct_block(GLOB.mam_ears_list.Find(features["mam_ears"]), GLOB.mam_ears_list.len) - if(DNA_MUTANTMARKING_BLOCK) - construct_block(GLOB.mam_body_markings_list.Find(features["mam_body_markings"]), GLOB.mam_body_markings_list.len) - if(DNA_TAUR_BLOCK) - construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len) - -/datum/dna/proc/is_same_as(datum/dna/D) - if(uni_identity == D.uni_identity && struc_enzymes == D.struc_enzymes && real_name == D.real_name && nameless == D.nameless && custom_species == D.custom_species) - if(species.type == D.species.type && features == D.features && blood_type == D.blood_type) - return 1 - return 0 - -//used to update dna UI, UE, and dna.real_name. -/datum/dna/proc/update_dna_identity() - uni_identity = generate_uni_identity() - unique_enzymes = generate_unique_enzymes() - -/datum/dna/proc/initialize_dna(newblood_type) - if(newblood_type) - blood_type = newblood_type - unique_enzymes = generate_unique_enzymes() - uni_identity = generate_uni_identity() - struc_enzymes = generate_struc_enzymes() - features = random_features() - - -/datum/dna/stored //subtype used by brain mob's stored_dna - -/datum/dna/stored/add_mutation(mutation_name) //no mutation changes on stored dna. - return - -/datum/dna/stored/remove_mutation(mutation_name) - return - -/datum/dna/stored/check_mutation(mutation_name) - return - -/datum/dna/stored/remove_all_mutations() - return - -/datum/dna/stored/remove_mutation_group(list/group) - return - -/////////////////////////// DNA MOB-PROCS ////////////////////// - -/mob/proc/set_species(datum/species/mrace, icon_update = 1) - return - -/mob/living/brain/set_species(datum/species/mrace, icon_update = 1) - if(mrace) - if(ispath(mrace)) - stored_dna.species = new mrace() - else - stored_dna.species = mrace //not calling any species update procs since we're a brain, not a monkey/human - - -/mob/living/carbon/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE) - if(mrace && has_dna()) - var/datum/species/new_race - if(ispath(mrace)) - new_race = new mrace - else if(istype(mrace)) - new_race = mrace - else - return - dna.species.on_species_loss(src, new_race, pref_load) - var/datum/species/old_species = dna.species - dna.species = new_race - dna.species.on_species_gain(src, old_species, pref_load) - -/mob/living/carbon/human/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE) - ..() - if(icon_update) - update_body() - update_hair() - update_mutations_overlay()// no lizard with human hulk overlay please. - - -/mob/proc/has_dna() - return - -/mob/living/carbon/has_dna() - return dna - - -/mob/living/carbon/human/proc/hardset_dna(ui, se, newreal_name, newblood_type, datum/species/mrace, newfeatures) - - if(newfeatures) - dna.features = newfeatures - flavor_text = dna.features["flavor_text"] //Update the flavor_text to use new dna text - - if(mrace) - var/datum/species/newrace = new mrace.type - newrace.copy_properties_from(mrace) - set_species(newrace, icon_update=0) - - if(newreal_name) - real_name = newreal_name - dna.generate_unique_enzymes() - - if(newblood_type) - dna.blood_type = newblood_type - - if(ui) - dna.uni_identity = ui - updateappearance(icon_update=0) - - if(se) - dna.struc_enzymes = se - domutcheck() - - if(mrace || newfeatures || ui) - update_body() - update_hair() - update_body_parts() - update_mutations_overlay() - - -/mob/living/carbon/proc/create_dna() - dna = new /datum/dna(src) - if(!dna.species) - var/rando_race = pick(GLOB.roundstart_races) - dna.species = new rando_race() - -//proc used to update the mob's appearance after its dna UI has been changed -/mob/living/carbon/proc/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0) - if(!has_dna()) - return - gender = (deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? FEMALE : MALE - -/mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0) - ..() - var/structure = dna.uni_identity - hair_color = sanitize_hexcolor(getblock(structure, DNA_HAIR_COLOR_BLOCK)) - facial_hair_color = sanitize_hexcolor(getblock(structure, DNA_FACIAL_HAIR_COLOR_BLOCK)) - skin_tone = GLOB.skin_tones[deconstruct_block(getblock(structure, DNA_SKIN_TONE_BLOCK), GLOB.skin_tones.len)] - eye_color = sanitize_hexcolor(getblock(structure, DNA_EYE_COLOR_BLOCK)) - facial_hair_style = GLOB.facial_hair_styles_list[deconstruct_block(getblock(structure, DNA_FACIAL_HAIR_STYLE_BLOCK), GLOB.facial_hair_styles_list.len)] - hair_style = GLOB.hair_styles_list[deconstruct_block(getblock(structure, DNA_HAIR_STYLE_BLOCK), GLOB.hair_styles_list.len)] - if(icon_update) - update_body() - update_hair() - if(mutcolor_update) - update_body_parts() - if(mutations_overlay_update) - update_mutations_overlay() - - -/mob/proc/domutcheck() - return - -/mob/living/carbon/domutcheck(force_powers=0) //Set force_powers to 1 to bypass the power chance - if(!has_dna()) - return - - for(var/datum/mutation/human/A in GLOB.good_mutations | GLOB.bad_mutations | GLOB.not_good_mutations) - if(ismob(A.check_block(src, force_powers))) - return //we got monkeyized/humanized, this mob will be deleted, no need to continue. - - update_mutations_overlay() - - - -/////////////////////////// DNA HELPER-PROCS ////////////////////////////// -/proc/getleftblocks(input,blocknumber,blocksize) - if(blocknumber > 1) - return copytext(input,1,((blocksize*blocknumber)-(blocksize-1))) - -/proc/getrightblocks(input,blocknumber,blocksize) - if(blocknumber < (length(input)/blocksize)) - return copytext(input,blocksize*blocknumber+1,length(input)+1) - -/proc/getblock(input, blocknumber, blocksize=DNA_BLOCK_SIZE) - return copytext(input, blocksize*(blocknumber-1)+1, (blocksize*blocknumber)+1) - -/proc/setblock(istring, blocknumber, replacement, blocksize=DNA_BLOCK_SIZE) - if(!istring || !blocknumber || !replacement || !blocksize) - return 0 - return getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize) - -/mob/living/carbon/proc/randmut(list/candidates, difficulty = 2) - if(!has_dna()) - return - var/datum/mutation/human/num = pick(candidates) - . = num.force_give(src) - -/mob/living/carbon/proc/randmutb() - if(!has_dna()) - return - var/datum/mutation/human/HM = pick((GLOB.bad_mutations | GLOB.not_good_mutations) - GLOB.mutations_list[RACEMUT]) - . = HM.force_give(src) - -/mob/living/carbon/proc/randmutg() - if(!has_dna()) - return - var/datum/mutation/human/HM = pick(GLOB.good_mutations) - . = HM.force_give(src) - -/mob/living/carbon/proc/randmutvg() - if(!has_dna()) - return - var/datum/mutation/human/HM = pick((GLOB.good_mutations) - GLOB.mutations_list[HULK] - GLOB.mutations_list[DWARFISM]) - . = HM.force_give(src) - -/mob/living/carbon/proc/randmuti() - if(!has_dna()) - return - var/num = rand(1, DNA_UNI_IDENTITY_BLOCKS) - var/newdna = setblock(dna.uni_identity, num, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters)) - dna.uni_identity = newdna - updateappearance(mutations_overlay_update=1) - -/mob/living/carbon/proc/clean_dna() - if(!has_dna()) - return - dna.remove_all_mutations() - -/mob/living/carbon/proc/clean_randmut(list/candidates, difficulty = 2) - clean_dna() - randmut(candidates, difficulty) - -/proc/scramble_dna(mob/living/carbon/M, ui=FALSE, se=FALSE, probability) - if(!M.has_dna()) - return 0 - if(se) - for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++) - if(prob(probability)) - M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters)) - M.domutcheck() - if(ui) - for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++) - if(prob(probability)) - M.dna.uni_identity = setblock(M.dna.uni_identity, i, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters)) - M.updateappearance(mutations_overlay_update=1) - return 1 - -//value in range 1 to values. values must be greater than 0 -//all arguments assumed to be positive integers -/proc/construct_block(value, values, blocksize=DNA_BLOCK_SIZE) - var/width = round((16**blocksize)/values) - if(value < 1) - value = 1 - value = (value * width) - rand(1,width) - return num2hex(value, blocksize) - -//value is hex -/proc/deconstruct_block(value, values, blocksize=DNA_BLOCK_SIZE) - var/width = round((16**blocksize)/values) - value = round(hex2num(value) / width) + 1 - if(value > values) - value = values - return value - -/////////////////////////// DNA HELPER-PROCS + +/////////////////////////// DNA DATUM +/datum/dna + var/unique_enzymes + var/struc_enzymes + var/uni_identity + var/blood_type + var/datum/species/species = new /datum/species/human //The type of mutant race the player is if applicable (i.e. potato-man) + var/list/features = list("FFF") //first value is mutant color + var/real_name //Stores the real name of the person who originally got this dna datum. Used primarely for changelings, + var/nameless = FALSE + var/custom_species //siiiiigh I guess this is important + var/list/mutations = list() //All mutations are from now on here + var/list/temporary_mutations = list() //Timers for temporary mutations + var/list/previous = list() //For temporary name/ui/ue/blood_type modifications + var/mob/living/holder + var/delete_species = TRUE //Set to FALSE when a body is scanned by a cloner to fix #38875 + +/datum/dna/New(mob/living/new_holder) + if(istype(new_holder)) + holder = new_holder + +/datum/dna/Destroy() + if(iscarbon(holder)) + var/mob/living/carbon/cholder = holder + if(cholder.dna == src) + cholder.dna = null + holder = null + + if(delete_species) + QDEL_NULL(species) + + mutations.Cut() //This only references mutations, just dereference. + temporary_mutations.Cut() //^ + previous.Cut() //^ + + return ..() + +/datum/dna/proc/transfer_identity(mob/living/carbon/destination, transfer_SE = 0) + if(!istype(destination)) + return + destination.dna.unique_enzymes = unique_enzymes + destination.dna.uni_identity = uni_identity + destination.dna.blood_type = blood_type + destination.dna.features = features.Copy() + destination.set_species(species.type, icon_update=0) + destination.dna.real_name = real_name + destination.dna.nameless = nameless + destination.dna.custom_species = custom_species + destination.dna.temporary_mutations = temporary_mutations.Copy() + if(ishuman(destination)) + var/mob/living/carbon/human/H = destination + H.give_genitals(TRUE)//This gives the body the genitals of this DNA. Used for any transformations based on DNA + destination.flavor_text = destination.dna.features["flavor_text"] //Update the flavor_text to use new dna text + if(transfer_SE) + destination.dna.struc_enzymes = struc_enzymes + +/datum/dna/proc/copy_dna(datum/dna/new_dna) + new_dna.unique_enzymes = unique_enzymes + new_dna.struc_enzymes = struc_enzymes + new_dna.uni_identity = uni_identity + new_dna.blood_type = blood_type + new_dna.features = features.Copy() + new_dna.species = new species.type + new_dna.real_name = real_name + new_dna.nameless = nameless + new_dna.custom_species = custom_species + new_dna.mutations = mutations.Copy() + +/datum/dna/proc/add_mutation(mutation_name) + var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name] + HM.on_acquiring(holder) + +/datum/dna/proc/remove_mutation(mutation_name) + var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name] + HM.on_losing(holder) + +/datum/dna/proc/check_mutation(mutation_name) + var/datum/mutation/human/HM = GLOB.mutations_list[mutation_name] + return mutations.Find(HM) + +/datum/dna/proc/remove_all_mutations() + remove_mutation_group(mutations) + +/datum/dna/proc/remove_mutation_group(list/group) + if(!group) + return + for(var/datum/mutation/human/HM in group) + HM.force_lose(holder) + +/datum/dna/proc/generate_uni_identity() + . = "" + var/list/L = new /list(DNA_UNI_IDENTITY_BLOCKS) + + L[DNA_GENDER_BLOCK] = construct_block((holder.gender!=MALE)+1, 2) + if(ishuman(holder)) + var/mob/living/carbon/human/H = holder + if(!GLOB.hair_styles_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/hair,GLOB.hair_styles_list, GLOB.hair_styles_male_list, GLOB.hair_styles_female_list) + L[DNA_HAIR_STYLE_BLOCK] = construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len) + L[DNA_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.hair_color) + if(!GLOB.facial_hair_styles_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair, GLOB.facial_hair_styles_list, GLOB.facial_hair_styles_male_list, GLOB.facial_hair_styles_female_list) + L[DNA_FACIAL_HAIR_STYLE_BLOCK] = construct_block(GLOB.facial_hair_styles_list.Find(H.facial_hair_style), GLOB.facial_hair_styles_list.len) + L[DNA_FACIAL_HAIR_COLOR_BLOCK] = sanitize_hexcolor(H.facial_hair_color) + L[DNA_SKIN_TONE_BLOCK] = construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len) + L[DNA_EYE_COLOR_BLOCK] = sanitize_hexcolor(H.eye_color) + L[DNA_COLOR_ONE_BLOCK] = sanitize_hexcolor(features["mcolor"]) + L[DNA_COLOR_TWO_BLOCK] = sanitize_hexcolor(features["mcolor2"]) + L[DNA_COLOR_THREE_BLOCK] = sanitize_hexcolor(features["mcolor3"]) + if(!GLOB.mam_tails_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails, GLOB.mam_tails_list) + L[DNA_MUTANTTAIL_BLOCK] = construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len) + if(!GLOB.mam_ears_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_ears, GLOB.mam_ears_list) + L[DNA_MUTANTEAR_BLOCK] = construct_block(GLOB.mam_ears_list.Find(features["mam_ears"]), GLOB.mam_ears_list.len) + if(!GLOB.mam_body_markings_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_body_markings, GLOB.mam_body_markings_list) + L[DNA_MUTANTMARKING_BLOCK] = construct_block(GLOB.mam_body_markings_list.Find(features["mam_body_markings"]), GLOB.mam_body_markings_list.len) + if(!GLOB.taur_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/taur, GLOB.taur_list) + L[DNA_TAUR_BLOCK] = construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len) + + for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++) + if(L[i]) + . += L[i] + else + . += random_string(DNA_BLOCK_SIZE,GLOB.hex_characters) + return . + +/datum/dna/proc/generate_struc_enzymes() + var/list/sorting = new /list(DNA_STRUC_ENZYMES_BLOCKS) + var/result = "" + for(var/datum/mutation/human/A in GLOB.good_mutations + GLOB.bad_mutations + GLOB.not_good_mutations) + if(A.name == RACEMUT && ismonkey(holder)) + sorting[A.dna_block] = num2hex(A.lowest_value + rand(0, 256 * 6), DNA_BLOCK_SIZE) + mutations |= A + else + sorting[A.dna_block] = random_string(DNA_BLOCK_SIZE, list("0","1","2","3","4","5","6")) + + for(var/B in sorting) + result += B + return result + +/datum/dna/proc/generate_unique_enzymes() + . = "" + if(istype(holder)) + real_name = holder.real_name + . += md5(holder.real_name) + else + . += random_string(DNA_UNIQUE_ENZYMES_LEN, GLOB.hex_characters) + return . + +/datum/dna/proc/update_ui_block(blocknumber) + if(!blocknumber || !ishuman(holder)) + return + var/mob/living/carbon/human/H = holder + switch(blocknumber) + if(DNA_HAIR_COLOR_BLOCK) + setblock(uni_identity, blocknumber, sanitize_hexcolor(H.hair_color)) + if(DNA_FACIAL_HAIR_COLOR_BLOCK) + setblock(uni_identity, blocknumber, sanitize_hexcolor(H.facial_hair_color)) + if(DNA_SKIN_TONE_BLOCK) + setblock(uni_identity, blocknumber, construct_block(GLOB.skin_tones.Find(H.skin_tone), GLOB.skin_tones.len)) + if(DNA_EYE_COLOR_BLOCK) + setblock(uni_identity, blocknumber, sanitize_hexcolor(H.eye_color)) + if(DNA_GENDER_BLOCK) + setblock(uni_identity, blocknumber, construct_block((H.gender!=MALE)+1, 2)) + if(DNA_FACIAL_HAIR_STYLE_BLOCK) + setblock(uni_identity, blocknumber, construct_block(GLOB.facial_hair_styles_list.Find(H.facial_hair_style), GLOB.facial_hair_styles_list.len)) + if(DNA_HAIR_STYLE_BLOCK) + setblock(uni_identity, blocknumber, construct_block(GLOB.hair_styles_list.Find(H.hair_style), GLOB.hair_styles_list.len)) + if(DNA_COLOR_ONE_BLOCK) + sanitize_hexcolor(features["mcolor"]) + if(DNA_COLOR_TWO_BLOCK) + sanitize_hexcolor(features["mcolor2"]) + if(DNA_COLOR_THREE_BLOCK) + sanitize_hexcolor(features["mcolor3"]) + if(DNA_MUTANTTAIL_BLOCK) + construct_block(GLOB.mam_tails_list.Find(features["mam_tail"]), GLOB.mam_tails_list.len) + if(DNA_MUTANTEAR_BLOCK) + construct_block(GLOB.mam_ears_list.Find(features["mam_ears"]), GLOB.mam_ears_list.len) + if(DNA_MUTANTMARKING_BLOCK) + construct_block(GLOB.mam_body_markings_list.Find(features["mam_body_markings"]), GLOB.mam_body_markings_list.len) + if(DNA_TAUR_BLOCK) + construct_block(GLOB.taur_list.Find(features["taur"]), GLOB.taur_list.len) + +/datum/dna/proc/is_same_as(datum/dna/D) + if(uni_identity == D.uni_identity && struc_enzymes == D.struc_enzymes && real_name == D.real_name && nameless == D.nameless && custom_species == D.custom_species) + if(species.type == D.species.type && features == D.features && blood_type == D.blood_type) + return 1 + return 0 + +//used to update dna UI, UE, and dna.real_name. +/datum/dna/proc/update_dna_identity() + uni_identity = generate_uni_identity() + unique_enzymes = generate_unique_enzymes() + +/datum/dna/proc/initialize_dna(newblood_type) + if(newblood_type) + blood_type = newblood_type + unique_enzymes = generate_unique_enzymes() + uni_identity = generate_uni_identity() + struc_enzymes = generate_struc_enzymes() + features = random_features() + + +/datum/dna/stored //subtype used by brain mob's stored_dna + +/datum/dna/stored/add_mutation(mutation_name) //no mutation changes on stored dna. + return + +/datum/dna/stored/remove_mutation(mutation_name) + return + +/datum/dna/stored/check_mutation(mutation_name) + return + +/datum/dna/stored/remove_all_mutations() + return + +/datum/dna/stored/remove_mutation_group(list/group) + return + +/////////////////////////// DNA MOB-PROCS ////////////////////// + +/mob/proc/set_species(datum/species/mrace, icon_update = 1) + return + +/mob/living/brain/set_species(datum/species/mrace, icon_update = 1) + if(mrace) + if(ispath(mrace)) + stored_dna.species = new mrace() + else + stored_dna.species = mrace //not calling any species update procs since we're a brain, not a monkey/human + + +/mob/living/carbon/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE) + if(mrace && has_dna()) + var/datum/species/new_race + if(ispath(mrace)) + new_race = new mrace + else if(istype(mrace)) + new_race = mrace + else + return + dna.species.on_species_loss(src, new_race, pref_load) + var/datum/species/old_species = dna.species + dna.species = new_race + dna.species.on_species_gain(src, old_species, pref_load) + +/mob/living/carbon/human/set_species(datum/species/mrace, icon_update = TRUE, pref_load = FALSE) + ..() + if(icon_update) + update_body() + update_hair() + update_mutations_overlay()// no lizard with human hulk overlay please. + + +/mob/proc/has_dna() + return + +/mob/living/carbon/has_dna() + return dna + + +/mob/living/carbon/human/proc/hardset_dna(ui, se, newreal_name, newblood_type, datum/species/mrace, newfeatures) + + if(newfeatures) + dna.features = newfeatures + flavor_text = dna.features["flavor_text"] //Update the flavor_text to use new dna text + + if(mrace) + var/datum/species/newrace = new mrace.type + newrace.copy_properties_from(mrace) + set_species(newrace, icon_update=0) + + if(newreal_name) + real_name = newreal_name + dna.generate_unique_enzymes() + + if(newblood_type) + dna.blood_type = newblood_type + + if(ui) + dna.uni_identity = ui + updateappearance(icon_update=0) + + if(se) + dna.struc_enzymes = se + domutcheck() + + if(mrace || newfeatures || ui) + update_body() + update_hair() + update_body_parts() + update_mutations_overlay() + + +/mob/living/carbon/proc/create_dna() + dna = new /datum/dna(src) + if(!dna.species) + var/rando_race = pick(GLOB.roundstart_races) + dna.species = new rando_race() + +//proc used to update the mob's appearance after its dna UI has been changed +/mob/living/carbon/proc/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0) + if(!has_dna()) + return + gender = (deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? FEMALE : MALE + +/mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0) + ..() + var/structure = dna.uni_identity + hair_color = sanitize_hexcolor(getblock(structure, DNA_HAIR_COLOR_BLOCK)) + facial_hair_color = sanitize_hexcolor(getblock(structure, DNA_FACIAL_HAIR_COLOR_BLOCK)) + skin_tone = GLOB.skin_tones[deconstruct_block(getblock(structure, DNA_SKIN_TONE_BLOCK), GLOB.skin_tones.len)] + eye_color = sanitize_hexcolor(getblock(structure, DNA_EYE_COLOR_BLOCK)) + facial_hair_style = GLOB.facial_hair_styles_list[deconstruct_block(getblock(structure, DNA_FACIAL_HAIR_STYLE_BLOCK), GLOB.facial_hair_styles_list.len)] + hair_style = GLOB.hair_styles_list[deconstruct_block(getblock(structure, DNA_HAIR_STYLE_BLOCK), GLOB.hair_styles_list.len)] + if(icon_update) + update_body() + update_hair() + if(mutcolor_update) + update_body_parts() + if(mutations_overlay_update) + update_mutations_overlay() + + +/mob/proc/domutcheck() + return + +/mob/living/carbon/domutcheck(force_powers=0) //Set force_powers to 1 to bypass the power chance + if(!has_dna()) + return + + for(var/datum/mutation/human/A in GLOB.good_mutations | GLOB.bad_mutations | GLOB.not_good_mutations) + if(ismob(A.check_block(src, force_powers))) + return //we got monkeyized/humanized, this mob will be deleted, no need to continue. + + update_mutations_overlay() + + + +/////////////////////////// DNA HELPER-PROCS ////////////////////////////// +/proc/getleftblocks(input,blocknumber,blocksize) + if(blocknumber > 1) + return copytext(input,1,((blocksize*blocknumber)-(blocksize-1))) + +/proc/getrightblocks(input,blocknumber,blocksize) + if(blocknumber < (length(input)/blocksize)) + return copytext(input,blocksize*blocknumber+1,length(input)+1) + +/proc/getblock(input, blocknumber, blocksize=DNA_BLOCK_SIZE) + return copytext(input, blocksize*(blocknumber-1)+1, (blocksize*blocknumber)+1) + +/proc/setblock(istring, blocknumber, replacement, blocksize=DNA_BLOCK_SIZE) + if(!istring || !blocknumber || !replacement || !blocksize) + return 0 + return getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize) + +/mob/living/carbon/proc/randmut(list/candidates, difficulty = 2) + if(!has_dna()) + return + var/datum/mutation/human/num = pick(candidates) + . = num.force_give(src) + +/mob/living/carbon/proc/randmutb() + if(!has_dna()) + return + var/datum/mutation/human/HM = pick((GLOB.bad_mutations | GLOB.not_good_mutations) - GLOB.mutations_list[RACEMUT]) + . = HM.force_give(src) + +/mob/living/carbon/proc/randmutg() + if(!has_dna()) + return + var/datum/mutation/human/HM = pick(GLOB.good_mutations) + . = HM.force_give(src) + +/mob/living/carbon/proc/randmutvg() + if(!has_dna()) + return + var/datum/mutation/human/HM = pick((GLOB.good_mutations) - GLOB.mutations_list[HULK] - GLOB.mutations_list[DWARFISM]) + . = HM.force_give(src) + +/mob/living/carbon/proc/randmuti() + if(!has_dna()) + return + var/num = rand(1, DNA_UNI_IDENTITY_BLOCKS) + var/newdna = setblock(dna.uni_identity, num, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters)) + dna.uni_identity = newdna + updateappearance(mutations_overlay_update=1) + +/mob/living/carbon/proc/clean_dna() + if(!has_dna()) + return + dna.remove_all_mutations() + +/mob/living/carbon/proc/clean_randmut(list/candidates, difficulty = 2) + clean_dna() + randmut(candidates, difficulty) + +/proc/scramble_dna(mob/living/carbon/M, ui=FALSE, se=FALSE, probability) + if(!M.has_dna()) + return 0 + if(se) + for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++) + if(prob(probability)) + M.dna.struc_enzymes = setblock(M.dna.struc_enzymes, i, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters)) + M.domutcheck() + if(ui) + for(var/i=1, i<=DNA_UNI_IDENTITY_BLOCKS, i++) + if(prob(probability)) + M.dna.uni_identity = setblock(M.dna.uni_identity, i, random_string(DNA_BLOCK_SIZE, GLOB.hex_characters)) + M.updateappearance(mutations_overlay_update=1) + return 1 + +//value in range 1 to values. values must be greater than 0 +//all arguments assumed to be positive integers +/proc/construct_block(value, values, blocksize=DNA_BLOCK_SIZE) + var/width = round((16**blocksize)/values) + if(value < 1) + value = 1 + value = (value * width) - rand(1,width) + return num2hex(value, blocksize) + +//value is hex +/proc/deconstruct_block(value, values, blocksize=DNA_BLOCK_SIZE) + var/width = round((16**blocksize)/values) + value = round(hex2num(value) / width) + 1 + if(value > values) + value = values + return value + +/////////////////////////// DNA HELPER-PROCS diff --git a/code/datums/forced_movement.dm b/code/datums/forced_movement.dm index 3cdf2b1fd8..33ea4a177b 100644 --- a/code/datums/forced_movement.dm +++ b/code/datums/forced_movement.dm @@ -1,90 +1,90 @@ -//Just new and forget -/datum/forced_movement - var/atom/movable/victim - var/atom/target - var/last_processed - var/steps_per_tick - var/allow_climbing - var/datum/callback/on_step - var/moved_at_all = FALSE - //as fast as ssfastprocess -/datum/forced_movement/New(atom/movable/_victim, atom/_target, _steps_per_tick = 0.5, _allow_climbing = FALSE, datum/callback/_on_step = null) - victim = _victim - target = _target - steps_per_tick = _steps_per_tick - allow_climbing = _allow_climbing - on_step = _on_step - - . = ..() - - if(_victim && _target && _steps_per_tick && !_victim.force_moving) - last_processed = world.time - _victim.force_moving = src - START_PROCESSING(SSfastprocess, src) - else - qdel(src) //if you want to overwrite the current forced movement, call qdel(victim.force_moving) before creating this - -/datum/forced_movement/Destroy() - if(victim.force_moving == src) - victim.force_moving = null - if(moved_at_all) - victim.forceMove(victim.loc) //get the side effects of moving here that require us to currently not be force_moving aka reslipping on ice - STOP_PROCESSING(SSfastprocess, src) - victim = null - target = null - return ..() - -/datum/forced_movement/process() - if(QDELETED(victim) || !victim.loc || QDELETED(target) || !target.loc) - qdel(src) - return - var/steps_to_take = round(steps_per_tick * (world.time - last_processed)) - if(steps_to_take) - for(var/i in 1 to steps_to_take) - if(TryMove()) - moved_at_all = TRUE - if(on_step) - on_step.InvokeAsync() - else - qdel(src) - return - last_processed = world.time - -/datum/forced_movement/proc/TryMove(recursive = FALSE) - var/atom/movable/vic = victim //sanic - var/atom/tar = target - - if(!recursive) - . = step_towards(vic, tar) - - //shit way for getting around corners - if(!.) - if(tar.x > vic.x) - if(step(vic, EAST)) - . = TRUE - else if(tar.x < vic.x) - if(step(vic, WEST)) - . = TRUE - - if(!.) - if(tar.y > vic.y) - if(step(vic, NORTH)) - . = TRUE - else if(tar.y < vic.y) - if(step(vic, SOUTH)) - . = TRUE - - if(!.) - if(recursive) - return FALSE - else - . = TryMove(TRUE) - - . = . && (vic.loc != tar.loc) - -/mob/Bump(atom/A) - . = ..() - if(force_moving && force_moving.allow_climbing && isstructure(A)) - var/obj/structure/S = A - if(S.climbable) - S.do_climb(src) +//Just new and forget +/datum/forced_movement + var/atom/movable/victim + var/atom/target + var/last_processed + var/steps_per_tick + var/allow_climbing + var/datum/callback/on_step + var/moved_at_all = FALSE + //as fast as ssfastprocess +/datum/forced_movement/New(atom/movable/_victim, atom/_target, _steps_per_tick = 0.5, _allow_climbing = FALSE, datum/callback/_on_step = null) + victim = _victim + target = _target + steps_per_tick = _steps_per_tick + allow_climbing = _allow_climbing + on_step = _on_step + + . = ..() + + if(_victim && _target && _steps_per_tick && !_victim.force_moving) + last_processed = world.time + _victim.force_moving = src + START_PROCESSING(SSfastprocess, src) + else + qdel(src) //if you want to overwrite the current forced movement, call qdel(victim.force_moving) before creating this + +/datum/forced_movement/Destroy() + if(victim.force_moving == src) + victim.force_moving = null + if(moved_at_all) + victim.forceMove(victim.loc) //get the side effects of moving here that require us to currently not be force_moving aka reslipping on ice + STOP_PROCESSING(SSfastprocess, src) + victim = null + target = null + return ..() + +/datum/forced_movement/process() + if(QDELETED(victim) || !victim.loc || QDELETED(target) || !target.loc) + qdel(src) + return + var/steps_to_take = round(steps_per_tick * (world.time - last_processed)) + if(steps_to_take) + for(var/i in 1 to steps_to_take) + if(TryMove()) + moved_at_all = TRUE + if(on_step) + on_step.InvokeAsync() + else + qdel(src) + return + last_processed = world.time + +/datum/forced_movement/proc/TryMove(recursive = FALSE) + var/atom/movable/vic = victim //sanic + var/atom/tar = target + + if(!recursive) + . = step_towards(vic, tar) + + //shit way for getting around corners + if(!.) + if(tar.x > vic.x) + if(step(vic, EAST)) + . = TRUE + else if(tar.x < vic.x) + if(step(vic, WEST)) + . = TRUE + + if(!.) + if(tar.y > vic.y) + if(step(vic, NORTH)) + . = TRUE + else if(tar.y < vic.y) + if(step(vic, SOUTH)) + . = TRUE + + if(!.) + if(recursive) + return FALSE + else + . = TryMove(TRUE) + + . = . && (vic.loc != tar.loc) + +/mob/Bump(atom/A) + . = ..() + if(force_moving && force_moving.allow_climbing && isstructure(A)) + var/obj/structure/S = A + if(S.climbable) + S.do_climb(src) diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm index c73d359bf1..420602cc7f 100644 --- a/code/datums/helper_datums/getrev.dm +++ b/code/datums/helper_datums/getrev.dm @@ -1,122 +1,122 @@ -/datum/getrev - var/commit // git rev-parse HEAD - var/date - var/originmastercommit // git rev-parse origin/master - var/list/testmerge = list() - -/datum/getrev/New() - testmerge = world.TgsTestMerges() - var/datum/tgs_revision_information/revinfo = world.TgsRevision() - if(revinfo) - commit = revinfo.commit - originmastercommit = revinfo.origin_commit - else - commit = rustg_git_revparse("HEAD") - if(commit) - date = rustg_git_commit_date(commit) - originmastercommit = rustg_git_revparse("origin/master") - - // goes to DD log and config_error.txt - log_world(get_log_message()) - -/datum/getrev/proc/get_log_message() - var/list/msg = list() - msg += "Running /tg/ revision: [date]" - if(originmastercommit) - msg += "origin/master: [originmastercommit]" - - for(var/line in testmerge) - var/datum/tgs_revision_information/test_merge/tm = line - msg += "Test merge active of PR #[tm.number] commit [tm.commit]" - - if(commit && commit != originmastercommit) - msg += "HEAD: [commit]" - else if(!originmastercommit) - msg += "No commit information" - - return msg.Join("\n") - -/datum/getrev/proc/GetTestMergeInfo(header = TRUE) - if(!testmerge.len) - return "" - . = header ? "The following pull requests are currently test merged:
      " : "" - for(var/line in testmerge) - var/datum/tgs_revision_information/test_merge/tm = line - var/cm = tm.pull_request_commit - var/details = ": '" + html_encode(tm.title) + "' by " + html_encode(tm.author) + " at commit " + html_encode(copytext(cm, 1, min(length(cm), 11))) - if(details && findtext(details, "\[s\]") && (!usr || !usr.client.holder)) - continue - . += "#[tm.number][details]
      " - -/client/verb/showrevinfo() - set category = "OOC" - set name = "Show Server Revision" - set desc = "Check the current server code revision" - - var/list/msg = list("") - // Round ID - if(GLOB.round_id) - msg += "Round ID: [GLOB.round_id]" - - msg += "BYOND Version: [world.byond_version].[world.byond_build]" - if(DM_VERSION != world.byond_version || DM_BUILD != world.byond_build) - msg += "Compiled with BYOND Version: [DM_VERSION].[DM_BUILD]" - - // Revision information - var/datum/getrev/revdata = GLOB.revdata - msg += "Server revision compiled on: [revdata.date]" - var/pc = revdata.originmastercommit - if(pc) - msg += "Master commit: [pc]" - if(revdata.testmerge.len) - msg += revdata.GetTestMergeInfo() - if(revdata.commit && revdata.commit != revdata.originmastercommit) - msg += "Local commit: [revdata.commit]" - else if(!pc) - msg += "No commit information" - if(world.TgsAvailable()) - msg += "Server tools version: [world.TgsVersion()]" - - // Game mode odds - msg += "
      Current Informational Settings:" - msg += "Protect Authority Roles From Traitor: [CONFIG_GET(flag/protect_roles_from_antagonist)]" - msg += "Protect Assistant Role From Traitor: [CONFIG_GET(flag/protect_assistant_from_antagonist)]" - msg += "Enforce Human Authority: [CONFIG_GET(flag/enforce_human_authority)]" - msg += "Allow Latejoin Antagonists: [CONFIG_GET(flag/allow_latejoin_antagonists)]" - msg += "Enforce Continuous Rounds: [length(CONFIG_GET(keyed_list/continuous))] of [config.modes.len] roundtypes" - msg += "Allow Midround Antagonists: [length(CONFIG_GET(keyed_list/midround_antag))] of [config.modes.len] roundtypes" - if(CONFIG_GET(flag/show_game_type_odds)) - var/list/probabilities = CONFIG_GET(keyed_list/probability) - if(SSticker.IsRoundInProgress()) - var/prob_sum = 0 - var/current_odds_differ = FALSE - var/list/probs = list() - var/list/modes = config.gamemode_cache - var/list/min_pop = CONFIG_GET(keyed_list/min_pop) - var/list/max_pop = CONFIG_GET(keyed_list/max_pop) - for(var/mode in modes) - var/datum/game_mode/M = mode - var/ctag = initial(M.config_tag) - if(!(ctag in probabilities)) - continue - if((min_pop[ctag] && (min_pop[ctag] > SSticker.totalPlayersReady)) || (max_pop[ctag] && (max_pop[ctag] < SSticker.totalPlayersReady)) || (initial(M.required_players) > SSticker.totalPlayersReady)) - current_odds_differ = TRUE - continue - probs[ctag] = 1 - prob_sum += probabilities[ctag] - if(current_odds_differ) - msg += "Game Mode Odds for current round:" - for(var/ctag in probs) - if(probabilities[ctag] > 0) - var/percentage = round(probabilities[ctag] / prob_sum * 100, 0.1) - msg += "[ctag] [percentage]%" - - msg += "All Game Mode Odds:" - var/sum = 0 - for(var/ctag in probabilities) - sum += probabilities[ctag] - for(var/ctag in probabilities) - if(probabilities[ctag] > 0) - var/percentage = round(probabilities[ctag] / sum * 100, 0.1) - msg += "[ctag] [percentage]%" +/datum/getrev + var/commit // git rev-parse HEAD + var/date + var/originmastercommit // git rev-parse origin/master + var/list/testmerge = list() + +/datum/getrev/New() + testmerge = world.TgsTestMerges() + var/datum/tgs_revision_information/revinfo = world.TgsRevision() + if(revinfo) + commit = revinfo.commit + originmastercommit = revinfo.origin_commit + else + commit = rustg_git_revparse("HEAD") + if(commit) + date = rustg_git_commit_date(commit) + originmastercommit = rustg_git_revparse("origin/master") + + // goes to DD log and config_error.txt + log_world(get_log_message()) + +/datum/getrev/proc/get_log_message() + var/list/msg = list() + msg += "Running /tg/ revision: [date]" + if(originmastercommit) + msg += "origin/master: [originmastercommit]" + + for(var/line in testmerge) + var/datum/tgs_revision_information/test_merge/tm = line + msg += "Test merge active of PR #[tm.number] commit [tm.commit]" + + if(commit && commit != originmastercommit) + msg += "HEAD: [commit]" + else if(!originmastercommit) + msg += "No commit information" + + return msg.Join("\n") + +/datum/getrev/proc/GetTestMergeInfo(header = TRUE) + if(!testmerge.len) + return "" + . = header ? "The following pull requests are currently test merged:
      " : "" + for(var/line in testmerge) + var/datum/tgs_revision_information/test_merge/tm = line + var/cm = tm.pull_request_commit + var/details = ": '" + html_encode(tm.title) + "' by " + html_encode(tm.author) + " at commit " + html_encode(copytext(cm, 1, min(length(cm), 11))) + if(details && findtext(details, "\[s\]") && (!usr || !usr.client.holder)) + continue + . += "#[tm.number][details]
      " + +/client/verb/showrevinfo() + set category = "OOC" + set name = "Show Server Revision" + set desc = "Check the current server code revision" + + var/list/msg = list("") + // Round ID + if(GLOB.round_id) + msg += "Round ID: [GLOB.round_id]" + + msg += "BYOND Version: [world.byond_version].[world.byond_build]" + if(DM_VERSION != world.byond_version || DM_BUILD != world.byond_build) + msg += "Compiled with BYOND Version: [DM_VERSION].[DM_BUILD]" + + // Revision information + var/datum/getrev/revdata = GLOB.revdata + msg += "Server revision compiled on: [revdata.date]" + var/pc = revdata.originmastercommit + if(pc) + msg += "Master commit: [pc]" + if(revdata.testmerge.len) + msg += revdata.GetTestMergeInfo() + if(revdata.commit && revdata.commit != revdata.originmastercommit) + msg += "Local commit: [revdata.commit]" + else if(!pc) + msg += "No commit information" + if(world.TgsAvailable()) + msg += "Server tools version: [world.TgsVersion()]" + + // Game mode odds + msg += "
      Current Informational Settings:" + msg += "Protect Authority Roles From Traitor: [CONFIG_GET(flag/protect_roles_from_antagonist)]" + msg += "Protect Assistant Role From Traitor: [CONFIG_GET(flag/protect_assistant_from_antagonist)]" + msg += "Enforce Human Authority: [CONFIG_GET(flag/enforce_human_authority)]" + msg += "Allow Latejoin Antagonists: [CONFIG_GET(flag/allow_latejoin_antagonists)]" + msg += "Enforce Continuous Rounds: [length(CONFIG_GET(keyed_list/continuous))] of [config.modes.len] roundtypes" + msg += "Allow Midround Antagonists: [length(CONFIG_GET(keyed_list/midround_antag))] of [config.modes.len] roundtypes" + if(CONFIG_GET(flag/show_game_type_odds)) + var/list/probabilities = CONFIG_GET(keyed_list/probability) + if(SSticker.IsRoundInProgress()) + var/prob_sum = 0 + var/current_odds_differ = FALSE + var/list/probs = list() + var/list/modes = config.gamemode_cache + var/list/min_pop = CONFIG_GET(keyed_list/min_pop) + var/list/max_pop = CONFIG_GET(keyed_list/max_pop) + for(var/mode in modes) + var/datum/game_mode/M = mode + var/ctag = initial(M.config_tag) + if(!(ctag in probabilities)) + continue + if((min_pop[ctag] && (min_pop[ctag] > SSticker.totalPlayersReady)) || (max_pop[ctag] && (max_pop[ctag] < SSticker.totalPlayersReady)) || (initial(M.required_players) > SSticker.totalPlayersReady)) + current_odds_differ = TRUE + continue + probs[ctag] = 1 + prob_sum += probabilities[ctag] + if(current_odds_differ) + msg += "Game Mode Odds for current round:" + for(var/ctag in probs) + if(probabilities[ctag] > 0) + var/percentage = round(probabilities[ctag] / prob_sum * 100, 0.1) + msg += "[ctag] [percentage]%" + + msg += "All Game Mode Odds:" + var/sum = 0 + for(var/ctag in probabilities) + sum += probabilities[ctag] + for(var/ctag in probabilities) + if(probabilities[ctag] > 0) + var/percentage = round(probabilities[ctag] / sum * 100, 0.1) + msg += "[ctag] [percentage]%" to_chat(src, msg.Join("
      ")) \ No newline at end of file diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index 74f22b5ac0..1c2ce851fe 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -1,167 +1,167 @@ -// teleatom: atom to teleport -// destination: destination to teleport to -// precision: teleport precision (0 is most precise, the default) -// effectin: effect to show right before teleportation -// effectout: effect to show right after teleportation -// asoundin: soundfile to play before teleportation -// asoundout: soundfile to play after teleportation -// no_effects: disable the default effectin/effectout of sparks -// forceMove: if false, teleport will use Move() proc (dense objects will prevent teleportation) -// forced: whether or not to ignore no_teleport -/proc/do_teleport(atom/movable/teleatom, atom/destination, precision=null, forceMove = TRUE, datum/effect_system/effectin=null, datum/effect_system/effectout=null, asoundin=null, asoundout=null, no_effects=FALSE, channel=TELEPORT_CHANNEL_BLUESPACE, forced = FALSE) - // teleporting most effects just deletes them - var/static/list/delete_atoms = typecacheof(list( - /obj/effect, - )) - typecacheof(list( - /obj/effect/dummy/chameleon, - /obj/effect/wisp, - /obj/effect/mob_spawn - )) - if(delete_atoms[teleatom.type]) - qdel(teleatom) - return FALSE - - // argument handling - // if the precision is not specified, default to 0, but apply BoH penalties - if (isnull(precision)) - precision = 0 - - switch(channel) - if(TELEPORT_CHANNEL_BLUESPACE) - if(istype(teleatom, /obj/item/storage/backpack/holding)) - precision = rand(1,100) - - var/static/list/bag_cache = typecacheof(/obj/item/storage/backpack/holding) - var/list/bagholding = typecache_filter_list(teleatom.GetAllContents(), bag_cache) - if(bagholding.len) - precision = max(rand(1,100)*bagholding.len,100) - if(isliving(teleatom)) - var/mob/living/MM = teleatom - to_chat(MM, "The bluespace interface on your bag of holding interferes with the teleport!") - - // if effects are not specified and not explicitly disabled, sparks - if ((!effectin || !effectout) && !no_effects) - var/datum/effect_system/spark_spread/sparks = new - sparks.set_up(5, 1, teleatom) - if (!effectin) - effectin = sparks - if (!effectout) - effectout = sparks - if(TELEPORT_CHANNEL_QUANTUM) - // if effects are not specified and not explicitly disabled, rainbow sparks - if ((!effectin || !effectout) && !no_effects) - var/datum/effect_system/spark_spread/quantum/sparks = new - sparks.set_up(5, 1, teleatom) - if (!effectin) - effectin = sparks - if (!effectout) - effectout = sparks - - // perform the teleport - var/turf/curturf = get_turf(teleatom) - var/turf/destturf = get_teleport_turf(get_turf(destination), precision) - - if(!destturf || !curturf || destturf.is_transition_turf()) - return FALSE - - var/area/A = get_area(curturf) - var/area/B = get_area(destturf) - if(!forced && (A.noteleport || B.noteleport)) - return FALSE - - if(SEND_SIGNAL(destturf, COMSIG_ATOM_INTERCEPT_TELEPORT, channel, curturf, destturf)) - return FALSE - - tele_play_specials(teleatom, curturf, effectin, asoundin) - var/success = forceMove ? teleatom.forceMove(destturf) : teleatom.Move(destturf) - if (success) - log_game("[key_name(teleatom)] has teleported from [loc_name(curturf)] to [loc_name(destturf)]") - tele_play_specials(teleatom, destturf, effectout, asoundout) - if(ismegafauna(teleatom)) - message_admins("[teleatom] [ADMIN_FLW(teleatom)] has teleported from [ADMIN_VERBOSEJMP(curturf)] to [ADMIN_VERBOSEJMP(destturf)].") - SEND_SIGNAL(teleatom, COMSIG_MOVABLE_TELEPORTED, channel, curturf, destturf) - - if(ismob(teleatom)) - var/mob/M = teleatom - M.cancel_camera() - - return TRUE - -/proc/tele_play_specials(atom/movable/teleatom, atom/location, datum/effect_system/effect, sound) - if (location && !isobserver(teleatom)) - if (sound) - playsound(location, sound, 60, 1) - if (effect) - effect.attach(location) - effect.start() - -// Safe location finder -/proc/find_safe_turf(zlevel, list/zlevels, extended_safety_checks = FALSE) - if(!zlevels) - if (zlevel) - zlevels = list(zlevel) - else - zlevels = SSmapping.levels_by_trait(ZTRAIT_STATION) - var/cycles = 1000 - for(var/cycle in 1 to cycles) - // DRUNK DIALLING WOOOOOOOOO - var/x = rand(1, world.maxx) - var/y = rand(1, world.maxy) - var/z = pick(zlevels) - var/random_location = locate(x,y,z) - - if(!isfloorturf(random_location)) - continue - var/turf/open/floor/F = random_location - if(!F.air) - continue - - var/datum/gas_mixture/A = F.air - var/list/A_gases = A.gases - var/trace_gases - for(var/id in A_gases) - if(id in GLOB.hardcoded_gases) - continue - trace_gases = TRUE - break - - // Can most things breathe? - if(trace_gases) - continue - if(A_gases[/datum/gas/oxygen] >= 16) - continue - if(A_gases[/datum/gas/plasma]) - continue - if(A_gases[/datum/gas/carbon_dioxide] >= 10) - continue - - // Aim for goldilocks temperatures and pressure - if((A.temperature <= 270) || (A.temperature >= 360)) - continue - var/pressure = A.return_pressure() - if((pressure <= 20) || (pressure >= 550)) - continue - - if(extended_safety_checks) - if(islava(F)) //chasms aren't /floor, and so are pre-filtered - var/turf/open/lava/L = F - if(!L.is_safe()) - continue - - // DING! You have passed the gauntlet, and are "probably" safe. - return F - -/proc/get_teleport_turfs(turf/center, precision = 0) - if(!precision) - return list(center) - var/list/posturfs = list() - for(var/turf/T in range(precision,center)) - if(T.is_transition_turf()) - continue // Avoid picking these. - var/area/A = T.loc - if(!A.noteleport) - posturfs.Add(T) - return posturfs - -/proc/get_teleport_turf(turf/center, precision = 0) - return safepick(get_teleport_turfs(center, precision)) +// teleatom: atom to teleport +// destination: destination to teleport to +// precision: teleport precision (0 is most precise, the default) +// effectin: effect to show right before teleportation +// effectout: effect to show right after teleportation +// asoundin: soundfile to play before teleportation +// asoundout: soundfile to play after teleportation +// no_effects: disable the default effectin/effectout of sparks +// forceMove: if false, teleport will use Move() proc (dense objects will prevent teleportation) +// forced: whether or not to ignore no_teleport +/proc/do_teleport(atom/movable/teleatom, atom/destination, precision=null, forceMove = TRUE, datum/effect_system/effectin=null, datum/effect_system/effectout=null, asoundin=null, asoundout=null, no_effects=FALSE, channel=TELEPORT_CHANNEL_BLUESPACE, forced = FALSE) + // teleporting most effects just deletes them + var/static/list/delete_atoms = typecacheof(list( + /obj/effect, + )) - typecacheof(list( + /obj/effect/dummy/chameleon, + /obj/effect/wisp, + /obj/effect/mob_spawn + )) + if(delete_atoms[teleatom.type]) + qdel(teleatom) + return FALSE + + // argument handling + // if the precision is not specified, default to 0, but apply BoH penalties + if (isnull(precision)) + precision = 0 + + switch(channel) + if(TELEPORT_CHANNEL_BLUESPACE) + if(istype(teleatom, /obj/item/storage/backpack/holding)) + precision = rand(1,100) + + var/static/list/bag_cache = typecacheof(/obj/item/storage/backpack/holding) + var/list/bagholding = typecache_filter_list(teleatom.GetAllContents(), bag_cache) + if(bagholding.len) + precision = max(rand(1,100)*bagholding.len,100) + if(isliving(teleatom)) + var/mob/living/MM = teleatom + to_chat(MM, "The bluespace interface on your bag of holding interferes with the teleport!") + + // if effects are not specified and not explicitly disabled, sparks + if ((!effectin || !effectout) && !no_effects) + var/datum/effect_system/spark_spread/sparks = new + sparks.set_up(5, 1, teleatom) + if (!effectin) + effectin = sparks + if (!effectout) + effectout = sparks + if(TELEPORT_CHANNEL_QUANTUM) + // if effects are not specified and not explicitly disabled, rainbow sparks + if ((!effectin || !effectout) && !no_effects) + var/datum/effect_system/spark_spread/quantum/sparks = new + sparks.set_up(5, 1, teleatom) + if (!effectin) + effectin = sparks + if (!effectout) + effectout = sparks + + // perform the teleport + var/turf/curturf = get_turf(teleatom) + var/turf/destturf = get_teleport_turf(get_turf(destination), precision) + + if(!destturf || !curturf || destturf.is_transition_turf()) + return FALSE + + var/area/A = get_area(curturf) + var/area/B = get_area(destturf) + if(!forced && (A.noteleport || B.noteleport)) + return FALSE + + if(SEND_SIGNAL(destturf, COMSIG_ATOM_INTERCEPT_TELEPORT, channel, curturf, destturf)) + return FALSE + + tele_play_specials(teleatom, curturf, effectin, asoundin) + var/success = forceMove ? teleatom.forceMove(destturf) : teleatom.Move(destturf) + if (success) + log_game("[key_name(teleatom)] has teleported from [loc_name(curturf)] to [loc_name(destturf)]") + tele_play_specials(teleatom, destturf, effectout, asoundout) + if(ismegafauna(teleatom)) + message_admins("[teleatom] [ADMIN_FLW(teleatom)] has teleported from [ADMIN_VERBOSEJMP(curturf)] to [ADMIN_VERBOSEJMP(destturf)].") + SEND_SIGNAL(teleatom, COMSIG_MOVABLE_TELEPORTED, channel, curturf, destturf) + + if(ismob(teleatom)) + var/mob/M = teleatom + M.cancel_camera() + + return TRUE + +/proc/tele_play_specials(atom/movable/teleatom, atom/location, datum/effect_system/effect, sound) + if (location && !isobserver(teleatom)) + if (sound) + playsound(location, sound, 60, 1) + if (effect) + effect.attach(location) + effect.start() + +// Safe location finder +/proc/find_safe_turf(zlevel, list/zlevels, extended_safety_checks = FALSE) + if(!zlevels) + if (zlevel) + zlevels = list(zlevel) + else + zlevels = SSmapping.levels_by_trait(ZTRAIT_STATION) + var/cycles = 1000 + for(var/cycle in 1 to cycles) + // DRUNK DIALLING WOOOOOOOOO + var/x = rand(1, world.maxx) + var/y = rand(1, world.maxy) + var/z = pick(zlevels) + var/random_location = locate(x,y,z) + + if(!isfloorturf(random_location)) + continue + var/turf/open/floor/F = random_location + if(!F.air) + continue + + var/datum/gas_mixture/A = F.air + var/list/A_gases = A.gases + var/trace_gases + for(var/id in A_gases) + if(id in GLOB.hardcoded_gases) + continue + trace_gases = TRUE + break + + // Can most things breathe? + if(trace_gases) + continue + if(A_gases[/datum/gas/oxygen] >= 16) + continue + if(A_gases[/datum/gas/plasma]) + continue + if(A_gases[/datum/gas/carbon_dioxide] >= 10) + continue + + // Aim for goldilocks temperatures and pressure + if((A.temperature <= 270) || (A.temperature >= 360)) + continue + var/pressure = A.return_pressure() + if((pressure <= 20) || (pressure >= 550)) + continue + + if(extended_safety_checks) + if(islava(F)) //chasms aren't /floor, and so are pre-filtered + var/turf/open/lava/L = F + if(!L.is_safe()) + continue + + // DING! You have passed the gauntlet, and are "probably" safe. + return F + +/proc/get_teleport_turfs(turf/center, precision = 0) + if(!precision) + return list(center) + var/list/posturfs = list() + for(var/turf/T in range(precision,center)) + if(T.is_transition_turf()) + continue // Avoid picking these. + var/area/A = T.loc + if(!A.noteleport) + posturfs.Add(T) + return posturfs + +/proc/get_teleport_turf(turf/center, precision = 0) + return safepick(get_teleport_turfs(center, precision)) diff --git a/code/datums/helper_datums/topic_input.dm b/code/datums/helper_datums/topic_input.dm index 3e43905f1f..d07aec067e 100644 --- a/code/datums/helper_datums/topic_input.dm +++ b/code/datums/helper_datums/topic_input.dm @@ -1,62 +1,62 @@ -/datum/topic_input - var/href - var/list/href_list - -/datum/topic_input/New(thref,list/thref_list) - href = thref - href_list = thref_list.Copy() - return - -/datum/topic_input/proc/get(i) - return listgetindex(href_list,i) - -/datum/topic_input/proc/getAndLocate(i) - var/t = get(i) - if(t) - t = locate(t) - if (istext(t)) - t = null - return t || null - -/datum/topic_input/proc/getNum(i) - var/t = get(i) - if(t) - t = text2num(t) - return isnum(t) ? t : null - -/datum/topic_input/proc/getObj(i) - var/t = getAndLocate(i) - return isobj(t) ? t : null - -/datum/topic_input/proc/getMob(i) - var/t = getAndLocate(i) - return ismob(t) ? t : null - -/datum/topic_input/proc/getTurf(i) - var/t = getAndLocate(i) - return isturf(t) ? t : null - -/datum/topic_input/proc/getAtom(i) - return getType(i, /atom) - -/datum/topic_input/proc/getArea(i) - var/t = getAndLocate(i) - return isarea(t) ? t : null - -/datum/topic_input/proc/getStr(i)//params should always be text, but... - var/t = get(i) - return istext(t) ? t : null - -/datum/topic_input/proc/getType(i,type) - var/t = getAndLocate(i) - return istype(t,type) ? t : null - -/datum/topic_input/proc/getPath(i) - var/t = get(i) - if(t) - t = text2path(t) - return ispath(t) ? t : null - -/datum/topic_input/proc/getList(i) - var/t = getAndLocate(i) - return islist(t) ? t : null +/datum/topic_input + var/href + var/list/href_list + +/datum/topic_input/New(thref,list/thref_list) + href = thref + href_list = thref_list.Copy() + return + +/datum/topic_input/proc/get(i) + return listgetindex(href_list,i) + +/datum/topic_input/proc/getAndLocate(i) + var/t = get(i) + if(t) + t = locate(t) + if (istext(t)) + t = null + return t || null + +/datum/topic_input/proc/getNum(i) + var/t = get(i) + if(t) + t = text2num(t) + return isnum(t) ? t : null + +/datum/topic_input/proc/getObj(i) + var/t = getAndLocate(i) + return isobj(t) ? t : null + +/datum/topic_input/proc/getMob(i) + var/t = getAndLocate(i) + return ismob(t) ? t : null + +/datum/topic_input/proc/getTurf(i) + var/t = getAndLocate(i) + return isturf(t) ? t : null + +/datum/topic_input/proc/getAtom(i) + return getType(i, /atom) + +/datum/topic_input/proc/getArea(i) + var/t = getAndLocate(i) + return isarea(t) ? t : null + +/datum/topic_input/proc/getStr(i)//params should always be text, but... + var/t = get(i) + return istext(t) ? t : null + +/datum/topic_input/proc/getType(i,type) + var/t = getAndLocate(i) + return istype(t,type) ? t : null + +/datum/topic_input/proc/getPath(i) + var/t = get(i) + if(t) + t = text2path(t) + return ispath(t) ? t : null + +/datum/topic_input/proc/getList(i) + var/t = getAndLocate(i) + return islist(t) ? t : null diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm index 4923609db8..5a4600432d 100644 --- a/code/datums/holocall.dm +++ b/code/datums/holocall.dm @@ -1,352 +1,352 @@ -#define HOLOPAD_MAX_DIAL_TIME 200 - -#define HOLORECORD_DELAY "delay" -#define HOLORECORD_SAY "say" -#define HOLORECORD_SOUND "sound" -#define HOLORECORD_LANGUAGE "lang" -#define HOLORECORD_PRESET "preset" -#define HOLORECORD_RENAME "rename" - -#define HOLORECORD_MAX_LENGTH 200 - -/mob/camera/aiEye/remote/holo/setLoc() - . = ..() - var/obj/machinery/holopad/H = origin - H.move_hologram(eye_user, loc) - -//this datum manages it's own references - -/datum/holocall - var/mob/living/user //the one that called - var/obj/machinery/holopad/calling_holopad //the one that sent the call - var/obj/machinery/holopad/connected_holopad //the one that answered the call (may be null) - var/list/dialed_holopads //all things called, will be cleared out to just connected_holopad once answered - - var/mob/camera/aiEye/remote/holo/eye //user's eye, once connected - var/obj/effect/overlay/holo_pad_hologram/hologram //user's hologram, once connected - var/datum/action/innate/end_holocall/hangup //hangup action - - var/call_start_time - -//creates a holocall made by `caller` from `calling_pad` to `callees` -/datum/holocall/New(mob/living/caller, obj/machinery/holopad/calling_pad, list/callees) - call_start_time = world.time - user = caller - calling_pad.outgoing_call = src - calling_holopad = calling_pad - dialed_holopads = list() - - for(var/I in callees) - var/obj/machinery/holopad/H = I - if(!QDELETED(H) && H.is_operational()) - dialed_holopads += H - H.say("Incoming call.") - LAZYADD(H.holo_calls, src) - - if(!dialed_holopads.len) - calling_pad.say("Connection failure.") - qdel(src) - return - - testing("Holocall started") - -//cleans up ALL references :) -/datum/holocall/Destroy() - QDEL_NULL(hangup) - - var/user_good = !QDELETED(user) - if(user_good) - user.reset_perspective() - user.remote_control = null - - if(!QDELETED(eye)) - QDEL_NULL(eye) - - if(connected_holopad && !QDELETED(hologram)) - hologram = null - connected_holopad.clear_holo(user) - - user = null - - //Hologram survived holopad destro - if(!QDELETED(hologram)) - hologram.HC = null - QDEL_NULL(hologram) - - for(var/I in dialed_holopads) - var/obj/machinery/holopad/H = I - LAZYREMOVE(H.holo_calls, src) - dialed_holopads.Cut() - - if(calling_holopad) - calling_holopad.outgoing_call = null - calling_holopad.SetLightsAndPower() - calling_holopad = null - if(connected_holopad) - connected_holopad.SetLightsAndPower() - connected_holopad = null - - testing("Holocall destroyed") - - return ..() - -//Gracefully disconnects a holopad `H` from a call. Pads not in the call are ignored. Notifies participants of the disconnection -/datum/holocall/proc/Disconnect(obj/machinery/holopad/H) - testing("Holocall disconnect") - if(H == connected_holopad) - var/area/A = get_area(connected_holopad) - calling_holopad.say("[A] holopad disconnected.") - else if(H == calling_holopad && connected_holopad) - connected_holopad.say("[user] disconnected.") - - ConnectionFailure(H, TRUE) - -//Forcefully disconnects a holopad `H` from a call. Pads not in the call are ignored. -/datum/holocall/proc/ConnectionFailure(obj/machinery/holopad/H, graceful = FALSE) - testing("Holocall connection failure: graceful [graceful]") - if(H == connected_holopad || H == calling_holopad) - if(!graceful && H != calling_holopad) - calling_holopad.say("Connection failure.") - qdel(src) - return - - LAZYREMOVE(H.holo_calls, src) - dialed_holopads -= H - if(!dialed_holopads.len) - if(graceful) - calling_holopad.say("Call rejected.") - testing("No recipients, terminating") - qdel(src) - -//Answers a call made to a holopad `H` which cannot be the calling holopad. Pads not in the call are ignored -/datum/holocall/proc/Answer(obj/machinery/holopad/H) - testing("Holocall answer") - if(H == calling_holopad) - CRASH("How cute, a holopad tried to answer itself.") - - if(!(H in dialed_holopads)) - return - - if(connected_holopad) - CRASH("Multi-connection holocall") - - for(var/I in dialed_holopads) - if(I == H) - continue - Disconnect(I) - - for(var/I in H.holo_calls) - var/datum/holocall/HC = I - if(HC != src) - HC.Disconnect(H) - - connected_holopad = H - - if(!Check()) - return - - hologram = H.activate_holo(user) - hologram.HC = src - - //eyeobj code is horrid, this is the best copypasta I could make - eye = new - eye.origin = H - eye.eye_initialized = TRUE - eye.eye_user = user - eye.name = "Camera Eye ([user.name])" - user.remote_control = eye - user.reset_perspective(eye) - eye.setLoc(H.loc) - - hangup = new(eye, src) - hangup.Grant(user) - -//Checks the validity of a holocall and qdels itself if it's not. Returns TRUE if valid, FALSE otherwise -/datum/holocall/proc/Check() - for(var/I in dialed_holopads) - var/obj/machinery/holopad/H = I - if(!H.is_operational()) - ConnectionFailure(H) - - if(QDELETED(src)) - return FALSE - - . = !QDELETED(user) && !user.incapacitated() && !QDELETED(calling_holopad) && calling_holopad.is_operational() && user.loc == calling_holopad.loc - - if(.) - if(!connected_holopad) - . = world.time < (call_start_time + HOLOPAD_MAX_DIAL_TIME) - if(!.) - calling_holopad.say("No answer received.") - calling_holopad.temp = "" - - if(!.) - testing("Holocall Check fail") - qdel(src) - -/datum/action/innate/end_holocall - name = "End Holocall" - icon_icon = 'icons/mob/actions/actions_silicon.dmi' - button_icon_state = "camera_off" - var/datum/holocall/hcall - -/datum/action/innate/end_holocall/New(Target, datum/holocall/HC) - ..() - hcall = HC - -/datum/action/innate/end_holocall/Activate() - hcall.Disconnect(hcall.calling_holopad) - - -//RECORDS -/datum/holorecord - var/caller_name = "Unknown" //Caller name - var/image/caller_image - var/list/entries = list() - var/language = /datum/language/common //Initial language, can be changed by HOLORECORD_LANGUAGE entries - -/datum/holorecord/proc/set_caller_image(mob/user) - var/olddir = user.dir - user.setDir(SOUTH) - caller_image = image(user) - user.setDir(olddir) - -/obj/item/disk/holodisk - name = "holorecord disk" - desc = "Stores recorder holocalls." - icon_state = "holodisk" - obj_flags = UNIQUE_RENAME - materials = list(MAT_METAL = 100, MAT_GLASS = 100) - var/datum/holorecord/record - //Preset variables - var/preset_image_type - var/preset_record_text - -/obj/item/disk/holodisk/Initialize(mapload) - . = ..() - if(preset_record_text) - build_record() - -/obj/item/disk/holodisk/Destroy() - QDEL_NULL(record) - return ..() - -/obj/item/disk/holodisk/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/disk/holodisk)) - var/obj/item/disk/holodisk/holodiskOriginal = W - if (holodiskOriginal.record) - if (!record) - record = new - record.caller_name = holodiskOriginal.record.caller_name - record.caller_image = holodiskOriginal.record.caller_image - record.entries = holodiskOriginal.record.entries.Copy() - record.language = holodiskOriginal.record.language - to_chat(user, "You copy the record from [holodiskOriginal] to [src] by connecting the ports!") - name = holodiskOriginal.name - else - to_chat(user, "[holodiskOriginal] has no record on it!") - ..() - -/obj/item/disk/holodisk/proc/build_record() - record = new - var/list/lines = splittext(preset_record_text,"\n") - for(var/line in lines) - var/prepared_line = trim(line) - if(!length(prepared_line)) - continue - var/splitpoint = findtext(prepared_line," ") - if(!splitpoint) - continue - var/command = copytext(prepared_line,1,splitpoint) - var/value = copytext(prepared_line,splitpoint+1) - switch(command) - if("DELAY") - var/delay_value = text2num(value) - if(!delay_value) - continue - record.entries += list(list(HOLORECORD_DELAY,delay_value)) - if("NAME") - if(!record.caller_name) - record.caller_name = value - else - record.entries += list(list(HOLORECORD_RENAME,value)) - if("SAY") - record.entries += list(list(HOLORECORD_SAY,value)) - if("SOUND") - record.entries += list(list(HOLORECORD_SOUND,value)) - if("LANGUAGE") - var/lang_type = text2path(value) - if(ispath(lang_type,/datum/language)) - record.entries += list(list(HOLORECORD_LANGUAGE,lang_type)) - if("PRESET") - var/preset_type = text2path(value) - if(ispath(preset_type,/datum/preset_holoimage)) - record.entries += list(list(HOLORECORD_PRESET,preset_type)) - if(!preset_image_type) - record.caller_image = image('icons/mob/animal.dmi',"old") - else - var/datum/preset_holoimage/H = new preset_image_type - record.caller_image = H.build_image() - -//These build caller image from outfit and some additional data, for use by mappers for ruin holorecords -/datum/preset_holoimage - var/nonhuman_mobtype //Fill this if you just want something nonhuman - var/outfit_type - var/species_type = /datum/species/human - -/datum/preset_holoimage/proc/build_image() - if(nonhuman_mobtype) - var/mob/living/L = nonhuman_mobtype - . = image(initial(L.icon),initial(L.icon_state)) - else - var/mob/living/carbon/human/dummy/mannequin = generate_or_wait_for_human_dummy("HOLODISK_PRESET") - if(species_type) - mannequin.set_species(species_type) - if(outfit_type) - mannequin.equipOutfit(outfit_type,TRUE) - mannequin.setDir(SOUTH) - COMPILE_OVERLAYS(mannequin) - . = image(mannequin) - unset_busy_human_dummy("HOLODISK_PRESET") - -/obj/item/disk/holodisk/example - preset_image_type = /datum/preset_holoimage/clown - preset_record_text = {" - NAME Clown - DELAY 10 - SAY Why did the chaplain cross the maint ? - DELAY 20 - SAY He wanted to get to the other side! - SOUND clownstep - DELAY 30 - LANGUAGE /datum/language/narsie - SAY Helped him get there! - DELAY 10 - SAY ALSO IM SECRETLY A GORILLA - DELAY 10 - PRESET /datum/preset_holoimage/gorilla - NAME Gorilla - LANGUAGE /datum/language/common - SAY OOGA - DELAY 20"} - -/datum/preset_holoimage/engineer - outfit_type = /datum/outfit/job/engineer/gloved/rig - -/datum/preset_holoimage/researcher - outfit_type = /datum/outfit/job/scientist - -/datum/preset_holoimage/captain - outfit_type = /datum/outfit/job/captain - -/datum/preset_holoimage/nanotrasenprivatesecurity - outfit_type = /datum/outfit/nanotrasensoldiercorpse2 - -/datum/preset_holoimage/gorilla - nonhuman_mobtype = /mob/living/simple_animal/hostile/gorilla - -/datum/preset_holoimage/corgi - nonhuman_mobtype = /mob/living/simple_animal/pet/dog/corgi - -/datum/preset_holoimage/clown - outfit_type = /datum/outfit/job/clown +#define HOLOPAD_MAX_DIAL_TIME 200 + +#define HOLORECORD_DELAY "delay" +#define HOLORECORD_SAY "say" +#define HOLORECORD_SOUND "sound" +#define HOLORECORD_LANGUAGE "lang" +#define HOLORECORD_PRESET "preset" +#define HOLORECORD_RENAME "rename" + +#define HOLORECORD_MAX_LENGTH 200 + +/mob/camera/aiEye/remote/holo/setLoc() + . = ..() + var/obj/machinery/holopad/H = origin + H.move_hologram(eye_user, loc) + +//this datum manages it's own references + +/datum/holocall + var/mob/living/user //the one that called + var/obj/machinery/holopad/calling_holopad //the one that sent the call + var/obj/machinery/holopad/connected_holopad //the one that answered the call (may be null) + var/list/dialed_holopads //all things called, will be cleared out to just connected_holopad once answered + + var/mob/camera/aiEye/remote/holo/eye //user's eye, once connected + var/obj/effect/overlay/holo_pad_hologram/hologram //user's hologram, once connected + var/datum/action/innate/end_holocall/hangup //hangup action + + var/call_start_time + +//creates a holocall made by `caller` from `calling_pad` to `callees` +/datum/holocall/New(mob/living/caller, obj/machinery/holopad/calling_pad, list/callees) + call_start_time = world.time + user = caller + calling_pad.outgoing_call = src + calling_holopad = calling_pad + dialed_holopads = list() + + for(var/I in callees) + var/obj/machinery/holopad/H = I + if(!QDELETED(H) && H.is_operational()) + dialed_holopads += H + H.say("Incoming call.") + LAZYADD(H.holo_calls, src) + + if(!dialed_holopads.len) + calling_pad.say("Connection failure.") + qdel(src) + return + + testing("Holocall started") + +//cleans up ALL references :) +/datum/holocall/Destroy() + QDEL_NULL(hangup) + + var/user_good = !QDELETED(user) + if(user_good) + user.reset_perspective() + user.remote_control = null + + if(!QDELETED(eye)) + QDEL_NULL(eye) + + if(connected_holopad && !QDELETED(hologram)) + hologram = null + connected_holopad.clear_holo(user) + + user = null + + //Hologram survived holopad destro + if(!QDELETED(hologram)) + hologram.HC = null + QDEL_NULL(hologram) + + for(var/I in dialed_holopads) + var/obj/machinery/holopad/H = I + LAZYREMOVE(H.holo_calls, src) + dialed_holopads.Cut() + + if(calling_holopad) + calling_holopad.outgoing_call = null + calling_holopad.SetLightsAndPower() + calling_holopad = null + if(connected_holopad) + connected_holopad.SetLightsAndPower() + connected_holopad = null + + testing("Holocall destroyed") + + return ..() + +//Gracefully disconnects a holopad `H` from a call. Pads not in the call are ignored. Notifies participants of the disconnection +/datum/holocall/proc/Disconnect(obj/machinery/holopad/H) + testing("Holocall disconnect") + if(H == connected_holopad) + var/area/A = get_area(connected_holopad) + calling_holopad.say("[A] holopad disconnected.") + else if(H == calling_holopad && connected_holopad) + connected_holopad.say("[user] disconnected.") + + ConnectionFailure(H, TRUE) + +//Forcefully disconnects a holopad `H` from a call. Pads not in the call are ignored. +/datum/holocall/proc/ConnectionFailure(obj/machinery/holopad/H, graceful = FALSE) + testing("Holocall connection failure: graceful [graceful]") + if(H == connected_holopad || H == calling_holopad) + if(!graceful && H != calling_holopad) + calling_holopad.say("Connection failure.") + qdel(src) + return + + LAZYREMOVE(H.holo_calls, src) + dialed_holopads -= H + if(!dialed_holopads.len) + if(graceful) + calling_holopad.say("Call rejected.") + testing("No recipients, terminating") + qdel(src) + +//Answers a call made to a holopad `H` which cannot be the calling holopad. Pads not in the call are ignored +/datum/holocall/proc/Answer(obj/machinery/holopad/H) + testing("Holocall answer") + if(H == calling_holopad) + CRASH("How cute, a holopad tried to answer itself.") + + if(!(H in dialed_holopads)) + return + + if(connected_holopad) + CRASH("Multi-connection holocall") + + for(var/I in dialed_holopads) + if(I == H) + continue + Disconnect(I) + + for(var/I in H.holo_calls) + var/datum/holocall/HC = I + if(HC != src) + HC.Disconnect(H) + + connected_holopad = H + + if(!Check()) + return + + hologram = H.activate_holo(user) + hologram.HC = src + + //eyeobj code is horrid, this is the best copypasta I could make + eye = new + eye.origin = H + eye.eye_initialized = TRUE + eye.eye_user = user + eye.name = "Camera Eye ([user.name])" + user.remote_control = eye + user.reset_perspective(eye) + eye.setLoc(H.loc) + + hangup = new(eye, src) + hangup.Grant(user) + +//Checks the validity of a holocall and qdels itself if it's not. Returns TRUE if valid, FALSE otherwise +/datum/holocall/proc/Check() + for(var/I in dialed_holopads) + var/obj/machinery/holopad/H = I + if(!H.is_operational()) + ConnectionFailure(H) + + if(QDELETED(src)) + return FALSE + + . = !QDELETED(user) && !user.incapacitated() && !QDELETED(calling_holopad) && calling_holopad.is_operational() && user.loc == calling_holopad.loc + + if(.) + if(!connected_holopad) + . = world.time < (call_start_time + HOLOPAD_MAX_DIAL_TIME) + if(!.) + calling_holopad.say("No answer received.") + calling_holopad.temp = "" + + if(!.) + testing("Holocall Check fail") + qdel(src) + +/datum/action/innate/end_holocall + name = "End Holocall" + icon_icon = 'icons/mob/actions/actions_silicon.dmi' + button_icon_state = "camera_off" + var/datum/holocall/hcall + +/datum/action/innate/end_holocall/New(Target, datum/holocall/HC) + ..() + hcall = HC + +/datum/action/innate/end_holocall/Activate() + hcall.Disconnect(hcall.calling_holopad) + + +//RECORDS +/datum/holorecord + var/caller_name = "Unknown" //Caller name + var/image/caller_image + var/list/entries = list() + var/language = /datum/language/common //Initial language, can be changed by HOLORECORD_LANGUAGE entries + +/datum/holorecord/proc/set_caller_image(mob/user) + var/olddir = user.dir + user.setDir(SOUTH) + caller_image = image(user) + user.setDir(olddir) + +/obj/item/disk/holodisk + name = "holorecord disk" + desc = "Stores recorder holocalls." + icon_state = "holodisk" + obj_flags = UNIQUE_RENAME + materials = list(MAT_METAL = 100, MAT_GLASS = 100) + var/datum/holorecord/record + //Preset variables + var/preset_image_type + var/preset_record_text + +/obj/item/disk/holodisk/Initialize(mapload) + . = ..() + if(preset_record_text) + build_record() + +/obj/item/disk/holodisk/Destroy() + QDEL_NULL(record) + return ..() + +/obj/item/disk/holodisk/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/disk/holodisk)) + var/obj/item/disk/holodisk/holodiskOriginal = W + if (holodiskOriginal.record) + if (!record) + record = new + record.caller_name = holodiskOriginal.record.caller_name + record.caller_image = holodiskOriginal.record.caller_image + record.entries = holodiskOriginal.record.entries.Copy() + record.language = holodiskOriginal.record.language + to_chat(user, "You copy the record from [holodiskOriginal] to [src] by connecting the ports!") + name = holodiskOriginal.name + else + to_chat(user, "[holodiskOriginal] has no record on it!") + ..() + +/obj/item/disk/holodisk/proc/build_record() + record = new + var/list/lines = splittext(preset_record_text,"\n") + for(var/line in lines) + var/prepared_line = trim(line) + if(!length(prepared_line)) + continue + var/splitpoint = findtext(prepared_line," ") + if(!splitpoint) + continue + var/command = copytext(prepared_line,1,splitpoint) + var/value = copytext(prepared_line,splitpoint+1) + switch(command) + if("DELAY") + var/delay_value = text2num(value) + if(!delay_value) + continue + record.entries += list(list(HOLORECORD_DELAY,delay_value)) + if("NAME") + if(!record.caller_name) + record.caller_name = value + else + record.entries += list(list(HOLORECORD_RENAME,value)) + if("SAY") + record.entries += list(list(HOLORECORD_SAY,value)) + if("SOUND") + record.entries += list(list(HOLORECORD_SOUND,value)) + if("LANGUAGE") + var/lang_type = text2path(value) + if(ispath(lang_type,/datum/language)) + record.entries += list(list(HOLORECORD_LANGUAGE,lang_type)) + if("PRESET") + var/preset_type = text2path(value) + if(ispath(preset_type,/datum/preset_holoimage)) + record.entries += list(list(HOLORECORD_PRESET,preset_type)) + if(!preset_image_type) + record.caller_image = image('icons/mob/animal.dmi',"old") + else + var/datum/preset_holoimage/H = new preset_image_type + record.caller_image = H.build_image() + +//These build caller image from outfit and some additional data, for use by mappers for ruin holorecords +/datum/preset_holoimage + var/nonhuman_mobtype //Fill this if you just want something nonhuman + var/outfit_type + var/species_type = /datum/species/human + +/datum/preset_holoimage/proc/build_image() + if(nonhuman_mobtype) + var/mob/living/L = nonhuman_mobtype + . = image(initial(L.icon),initial(L.icon_state)) + else + var/mob/living/carbon/human/dummy/mannequin = generate_or_wait_for_human_dummy("HOLODISK_PRESET") + if(species_type) + mannequin.set_species(species_type) + if(outfit_type) + mannequin.equipOutfit(outfit_type,TRUE) + mannequin.setDir(SOUTH) + COMPILE_OVERLAYS(mannequin) + . = image(mannequin) + unset_busy_human_dummy("HOLODISK_PRESET") + +/obj/item/disk/holodisk/example + preset_image_type = /datum/preset_holoimage/clown + preset_record_text = {" + NAME Clown + DELAY 10 + SAY Why did the chaplain cross the maint ? + DELAY 20 + SAY He wanted to get to the other side! + SOUND clownstep + DELAY 30 + LANGUAGE /datum/language/narsie + SAY Helped him get there! + DELAY 10 + SAY ALSO IM SECRETLY A GORILLA + DELAY 10 + PRESET /datum/preset_holoimage/gorilla + NAME Gorilla + LANGUAGE /datum/language/common + SAY OOGA + DELAY 20"} + +/datum/preset_holoimage/engineer + outfit_type = /datum/outfit/job/engineer/gloved/rig + +/datum/preset_holoimage/researcher + outfit_type = /datum/outfit/job/scientist + +/datum/preset_holoimage/captain + outfit_type = /datum/outfit/job/captain + +/datum/preset_holoimage/nanotrasenprivatesecurity + outfit_type = /datum/outfit/nanotrasensoldiercorpse2 + +/datum/preset_holoimage/gorilla + nonhuman_mobtype = /mob/living/simple_animal/hostile/gorilla + +/datum/preset_holoimage/corgi + nonhuman_mobtype = /mob/living/simple_animal/pet/dog/corgi + +/datum/preset_holoimage/clown + outfit_type = /datum/outfit/job/clown diff --git a/code/datums/hud.dm b/code/datums/hud.dm index 169b08dc98..e2d9bc579f 100644 --- a/code/datums/hud.dm +++ b/code/datums/hud.dm @@ -1,130 +1,130 @@ -/* HUD DATUMS */ - -GLOBAL_LIST_EMPTY(all_huds) - -//GLOBAL HUD LIST -GLOBAL_LIST_INIT(huds, list( - DATA_HUD_SECURITY_BASIC = new/datum/atom_hud/data/human/security/basic(), - DATA_HUD_SECURITY_ADVANCED = new/datum/atom_hud/data/human/security/advanced(), - DATA_HUD_MEDICAL_BASIC = new/datum/atom_hud/data/human/medical/basic(), - DATA_HUD_MEDICAL_ADVANCED = new/datum/atom_hud/data/human/medical/advanced(), - DATA_HUD_DIAGNOSTIC_BASIC = new/datum/atom_hud/data/diagnostic/basic(), - DATA_HUD_DIAGNOSTIC_ADVANCED = new/datum/atom_hud/data/diagnostic/advanced(), - DATA_HUD_ABDUCTOR = new/datum/atom_hud/abductor(), - DATA_HUD_SENTIENT_DISEASE = new/datum/atom_hud/sentient_disease(), - DATA_HUD_AI_DETECT = new/datum/atom_hud/ai_detector(), - ANTAG_HUD_CULT = new/datum/atom_hud/antag(), - ANTAG_HUD_REV = new/datum/atom_hud/antag(), - ANTAG_HUD_OPS = new/datum/atom_hud/antag(), - ANTAG_HUD_WIZ = new/datum/atom_hud/antag(), - ANTAG_HUD_SHADOW = new/datum/atom_hud/antag(), - ANTAG_HUD_TRAITOR = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_NINJA = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_CHANGELING = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_ABDUCTOR = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_DEVIL = new/datum/atom_hud/antag(), - ANTAG_HUD_SINTOUCHED = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_SOULLESS = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_CLOCKWORK = new/datum/atom_hud/antag(), - ANTAG_HUD_BROTHER = new/datum/atom_hud/antag/hidden(), - ANTAG_HUD_BLOODSUCKER = new/datum/atom_hud/antag/bloodsucker() - )) - -/datum/atom_hud - var/list/atom/hudatoms = list() //list of all atoms which display this hud - var/list/mob/hudusers = list() //list with all mobs who can see the hud - var/list/hud_icons = list() //these will be the indexes for the atom's hud_list - - var/list/next_time_allowed = list() //mobs associated with the next time this hud can be added to them - var/list/queued_to_see = list() //mobs that have triggered the cooldown and are queued to see the hud, but do not yet - -/datum/atom_hud/New() - GLOB.all_huds += src - -/datum/atom_hud/Destroy() - for(var/v in hudusers) - remove_hud_from(v) - for(var/v in hudatoms) - remove_from_hud(v) - GLOB.all_huds -= src - return ..() - -/datum/atom_hud/proc/remove_hud_from(mob/M) - if(!M || !hudusers[M]) - return - if (!--hudusers[M]) - hudusers -= M - if(queued_to_see[M]) - queued_to_see -= M - else - for(var/atom/A in hudatoms) - remove_from_single_hud(M, A) - -/datum/atom_hud/proc/remove_from_hud(atom/A) - if(!A) - return FALSE - for(var/mob/M in hudusers) - remove_from_single_hud(M, A) - hudatoms -= A - return TRUE - -/datum/atom_hud/proc/remove_from_single_hud(mob/M, atom/A) //unsafe, no sanity apart from client - if(!M || !M.client || !A) - return - for(var/i in hud_icons) - M.client.images -= A.hud_list[i] - -/datum/atom_hud/proc/add_hud_to(mob/M) - if(!M) - return - if(!hudusers[M]) - hudusers[M] = 1 - if(next_time_allowed[M] > world.time) - if(!queued_to_see[M]) - addtimer(CALLBACK(src, .proc/show_hud_images_after_cooldown, M), next_time_allowed[M] - world.time) - queued_to_see[M] = TRUE - else - next_time_allowed[M] = world.time + ADD_HUD_TO_COOLDOWN - for(var/atom/A in hudatoms) - add_to_single_hud(M, A) - else - hudusers[M]++ - -/datum/atom_hud/proc/show_hud_images_after_cooldown(M) - if(queued_to_see[M]) - queued_to_see -= M - next_time_allowed[M] = world.time + ADD_HUD_TO_COOLDOWN - for(var/atom/A in hudatoms) - add_to_single_hud(M, A) - -/datum/atom_hud/proc/add_to_hud(atom/A) - if(!A) - return FALSE - hudatoms |= A - for(var/mob/M in hudusers) - if(!queued_to_see[M]) - add_to_single_hud(M, A) - return TRUE - -/datum/atom_hud/proc/add_to_single_hud(mob/M, atom/A) //unsafe, no sanity apart from client - if(!M || !M.client || !A) - return - for(var/i in hud_icons) - if(A.hud_list[i]) - M.client.images |= A.hud_list[i] - -//MOB PROCS -/mob/proc/reload_huds() - for(var/datum/atom_hud/hud in GLOB.all_huds) - if(hud && hud.hudusers[src]) - for(var/atom/A in hud.hudatoms) - hud.add_to_single_hud(src, A) - -/mob/dead/new_player/reload_huds() - return - -/mob/proc/add_click_catcher() - client.screen += client.void - -/mob/dead/new_player/add_click_catcher() - return +/* HUD DATUMS */ + +GLOBAL_LIST_EMPTY(all_huds) + +//GLOBAL HUD LIST +GLOBAL_LIST_INIT(huds, list( + DATA_HUD_SECURITY_BASIC = new/datum/atom_hud/data/human/security/basic(), + DATA_HUD_SECURITY_ADVANCED = new/datum/atom_hud/data/human/security/advanced(), + DATA_HUD_MEDICAL_BASIC = new/datum/atom_hud/data/human/medical/basic(), + DATA_HUD_MEDICAL_ADVANCED = new/datum/atom_hud/data/human/medical/advanced(), + DATA_HUD_DIAGNOSTIC_BASIC = new/datum/atom_hud/data/diagnostic/basic(), + DATA_HUD_DIAGNOSTIC_ADVANCED = new/datum/atom_hud/data/diagnostic/advanced(), + DATA_HUD_ABDUCTOR = new/datum/atom_hud/abductor(), + DATA_HUD_SENTIENT_DISEASE = new/datum/atom_hud/sentient_disease(), + DATA_HUD_AI_DETECT = new/datum/atom_hud/ai_detector(), + ANTAG_HUD_CULT = new/datum/atom_hud/antag(), + ANTAG_HUD_REV = new/datum/atom_hud/antag(), + ANTAG_HUD_OPS = new/datum/atom_hud/antag(), + ANTAG_HUD_WIZ = new/datum/atom_hud/antag(), + ANTAG_HUD_SHADOW = new/datum/atom_hud/antag(), + ANTAG_HUD_TRAITOR = new/datum/atom_hud/antag/hidden(), + ANTAG_HUD_NINJA = new/datum/atom_hud/antag/hidden(), + ANTAG_HUD_CHANGELING = new/datum/atom_hud/antag/hidden(), + ANTAG_HUD_ABDUCTOR = new/datum/atom_hud/antag/hidden(), + ANTAG_HUD_DEVIL = new/datum/atom_hud/antag(), + ANTAG_HUD_SINTOUCHED = new/datum/atom_hud/antag/hidden(), + ANTAG_HUD_SOULLESS = new/datum/atom_hud/antag/hidden(), + ANTAG_HUD_CLOCKWORK = new/datum/atom_hud/antag(), + ANTAG_HUD_BROTHER = new/datum/atom_hud/antag/hidden(), + ANTAG_HUD_BLOODSUCKER = new/datum/atom_hud/antag/bloodsucker() + )) + +/datum/atom_hud + var/list/atom/hudatoms = list() //list of all atoms which display this hud + var/list/mob/hudusers = list() //list with all mobs who can see the hud + var/list/hud_icons = list() //these will be the indexes for the atom's hud_list + + var/list/next_time_allowed = list() //mobs associated with the next time this hud can be added to them + var/list/queued_to_see = list() //mobs that have triggered the cooldown and are queued to see the hud, but do not yet + +/datum/atom_hud/New() + GLOB.all_huds += src + +/datum/atom_hud/Destroy() + for(var/v in hudusers) + remove_hud_from(v) + for(var/v in hudatoms) + remove_from_hud(v) + GLOB.all_huds -= src + return ..() + +/datum/atom_hud/proc/remove_hud_from(mob/M) + if(!M || !hudusers[M]) + return + if (!--hudusers[M]) + hudusers -= M + if(queued_to_see[M]) + queued_to_see -= M + else + for(var/atom/A in hudatoms) + remove_from_single_hud(M, A) + +/datum/atom_hud/proc/remove_from_hud(atom/A) + if(!A) + return FALSE + for(var/mob/M in hudusers) + remove_from_single_hud(M, A) + hudatoms -= A + return TRUE + +/datum/atom_hud/proc/remove_from_single_hud(mob/M, atom/A) //unsafe, no sanity apart from client + if(!M || !M.client || !A) + return + for(var/i in hud_icons) + M.client.images -= A.hud_list[i] + +/datum/atom_hud/proc/add_hud_to(mob/M) + if(!M) + return + if(!hudusers[M]) + hudusers[M] = 1 + if(next_time_allowed[M] > world.time) + if(!queued_to_see[M]) + addtimer(CALLBACK(src, .proc/show_hud_images_after_cooldown, M), next_time_allowed[M] - world.time) + queued_to_see[M] = TRUE + else + next_time_allowed[M] = world.time + ADD_HUD_TO_COOLDOWN + for(var/atom/A in hudatoms) + add_to_single_hud(M, A) + else + hudusers[M]++ + +/datum/atom_hud/proc/show_hud_images_after_cooldown(M) + if(queued_to_see[M]) + queued_to_see -= M + next_time_allowed[M] = world.time + ADD_HUD_TO_COOLDOWN + for(var/atom/A in hudatoms) + add_to_single_hud(M, A) + +/datum/atom_hud/proc/add_to_hud(atom/A) + if(!A) + return FALSE + hudatoms |= A + for(var/mob/M in hudusers) + if(!queued_to_see[M]) + add_to_single_hud(M, A) + return TRUE + +/datum/atom_hud/proc/add_to_single_hud(mob/M, atom/A) //unsafe, no sanity apart from client + if(!M || !M.client || !A) + return + for(var/i in hud_icons) + if(A.hud_list[i]) + M.client.images |= A.hud_list[i] + +//MOB PROCS +/mob/proc/reload_huds() + for(var/datum/atom_hud/hud in GLOB.all_huds) + if(hud && hud.hudusers[src]) + for(var/atom/A in hud.hudatoms) + hud.add_to_single_hud(src, A) + +/mob/dead/new_player/reload_huds() + return + +/mob/proc/add_click_catcher() + client.screen += client.void + +/mob/dead/new_player/add_click_catcher() + return diff --git a/code/datums/map_config.dm b/code/datums/map_config.dm index c859f8127d..5fcd1ae93c 100644 --- a/code/datums/map_config.dm +++ b/code/datums/map_config.dm @@ -1,163 +1,163 @@ -//used for holding information about unique properties of maps -//feed it json files that match the datum layout -//defaults to box -// -Cyberboss - -/datum/map_config - // Metadata - var/config_filename = "_maps/boxstation.json" - var/defaulted = TRUE // set to FALSE by LoadConfig() succeeding - // Config from maps.txt - var/config_max_users = 0 - var/config_min_users = 0 - var/voteweight = 1 - var/max_round_search_span = 0 //If this is nonzero, then if the map has been played more than max_rounds_played within the search span (max determined by define in persistence.dm), this map won't be available. - var/max_rounds_played = 0 - - // Config actually from the JSON - should default to Box - var/map_name = "Box Station" - var/map_path = "map_files/BoxStation" - var/map_file = "BoxStation.dmm" - - var/traits = null - var/space_ruin_levels = 2 - var/space_empty_levels = 1 - - var/minetype = "lavaland" - - var/maptype = MAP_TYPE_STATION //This should be used to adjust ingame behavior depending on the specific type of map being played. For instance, if an overmap were added, it'd be appropriate for it to only generate with a MAP_TYPE_SHIP - - var/announcertype = "standard" //Determines the announcer the map uses. standard uses the default announcer, classic, but has a random chance to use other similarly-themed announcers, like medibot - - var/allow_custom_shuttles = TRUE - var/shuttles = list( - "cargo" = "cargo_box", - "ferry" = "ferry_fancy", - "whiteship" = "whiteship_box", - "emergency" = "emergency_box") - - var/year_offset = 540 //The offset of ingame year from the actual IRL year. You know you want to make a map that takes place in the 90's. Don't lie. - -/proc/load_map_config(filename = "data/next_map.json", default_to_box, delete_after, error_if_missing = TRUE) - var/datum/map_config/config = new - if (default_to_box) - return config - if (!config.LoadConfig(filename, error_if_missing)) - qdel(config) - config = new /datum/map_config // Fall back to Box - if (delete_after) - fdel(filename) - return config - -#define CHECK_EXISTS(X) if(!istext(json[X])) { log_world("[##X] missing from json!"); return; } -/datum/map_config/proc/LoadConfig(filename, error_if_missing) - if(!fexists(filename)) - if(error_if_missing) - log_world("map_config not found: [filename]") - return - - var/json = file(filename) - if(!json) - log_world("Could not open map_config: [filename]") - return - - json = file2text(json) - if(!json) - log_world("map_config is not text: [filename]") - return - - json = json_decode(json) - if(!json) - log_world("map_config is not json: [filename]") - return - - config_filename = filename - - CHECK_EXISTS("map_name") - map_name = json["map_name"] - CHECK_EXISTS("map_path") - map_path = json["map_path"] - - map_file = json["map_file"] - // "map_file": "BoxStation.dmm" - if (istext(map_file)) - if (!fexists("_maps/[map_path]/[map_file]")) - log_world("Map file ([map_path]/[map_file]) does not exist!") - return - // "map_file": ["Lower.dmm", "Upper.dmm"] - else if (islist(map_file)) - for (var/file in map_file) - if (!fexists("_maps/[map_path]/[file]")) - log_world("Map file ([map_path]/[file]) does not exist!") - return - else - log_world("map_file missing from json!") - return - - if (islist(json["shuttles"])) - var/list/L = json["shuttles"] - for(var/key in L) - var/value = L[key] - shuttles[key] = value - else if ("shuttles" in json) - log_world("map_config shuttles is not a list!") - return - - traits = json["traits"] - // "traits": [{"Linkage": "Cross"}, {"Space Ruins": true}] - if (islist(traits)) - // "Station" is set by default, but it's assumed if you're setting - // traits you want to customize which level is cross-linked - for (var/level in traits) - if (!(ZTRAIT_STATION in level)) - level[ZTRAIT_STATION] = TRUE - // "traits": null or absent -> default - else if (!isnull(traits)) - log_world("map_config traits is not a list!") - return - - var/temp = json["space_ruin_levels"] - if (isnum(temp)) - space_ruin_levels = temp - else if (!isnull(temp)) - log_world("map_config space_ruin_levels is not a number!") - return - - temp = json["space_empty_levels"] - if (isnum(temp)) - space_empty_levels = temp - else if (!isnull(temp)) - log_world("map_config space_empty_levels is not a number!") - return - - temp = json["year_offset"] - if (isnum(temp)) - year_offset = temp - else if (!isnull(temp)) - log_world("map_config year_offset is not a number!") - return - - if ("minetype" in json) - minetype = json["minetype"] - - if ("maptype" in json) - maptype = json["maptype"] - - if ("announcertype" in json) - announcertype = json["announcertype"] - - allow_custom_shuttles = json["allow_custom_shuttles"] != FALSE - - defaulted = FALSE - return TRUE -#undef CHECK_EXISTS - -/datum/map_config/proc/GetFullMapPaths() - if (istext(map_file)) - return list("_maps/[map_path]/[map_file]") - . = list() - for (var/file in map_file) - . += "_maps/[map_path]/[file]" - -/datum/map_config/proc/MakeNextMap() - return config_filename == "data/next_map.json" || fcopy(config_filename, "data/next_map.json") +//used for holding information about unique properties of maps +//feed it json files that match the datum layout +//defaults to box +// -Cyberboss + +/datum/map_config + // Metadata + var/config_filename = "_maps/boxstation.json" + var/defaulted = TRUE // set to FALSE by LoadConfig() succeeding + // Config from maps.txt + var/config_max_users = 0 + var/config_min_users = 0 + var/voteweight = 1 + var/max_round_search_span = 0 //If this is nonzero, then if the map has been played more than max_rounds_played within the search span (max determined by define in persistence.dm), this map won't be available. + var/max_rounds_played = 0 + + // Config actually from the JSON - should default to Box + var/map_name = "Box Station" + var/map_path = "map_files/BoxStation" + var/map_file = "BoxStation.dmm" + + var/traits = null + var/space_ruin_levels = 2 + var/space_empty_levels = 1 + + var/minetype = "lavaland" + + var/maptype = MAP_TYPE_STATION //This should be used to adjust ingame behavior depending on the specific type of map being played. For instance, if an overmap were added, it'd be appropriate for it to only generate with a MAP_TYPE_SHIP + + var/announcertype = "standard" //Determines the announcer the map uses. standard uses the default announcer, classic, but has a random chance to use other similarly-themed announcers, like medibot + + var/allow_custom_shuttles = TRUE + var/shuttles = list( + "cargo" = "cargo_box", + "ferry" = "ferry_fancy", + "whiteship" = "whiteship_box", + "emergency" = "emergency_box") + + var/year_offset = 540 //The offset of ingame year from the actual IRL year. You know you want to make a map that takes place in the 90's. Don't lie. + +/proc/load_map_config(filename = "data/next_map.json", default_to_box, delete_after, error_if_missing = TRUE) + var/datum/map_config/config = new + if (default_to_box) + return config + if (!config.LoadConfig(filename, error_if_missing)) + qdel(config) + config = new /datum/map_config // Fall back to Box + if (delete_after) + fdel(filename) + return config + +#define CHECK_EXISTS(X) if(!istext(json[X])) { log_world("[##X] missing from json!"); return; } +/datum/map_config/proc/LoadConfig(filename, error_if_missing) + if(!fexists(filename)) + if(error_if_missing) + log_world("map_config not found: [filename]") + return + + var/json = file(filename) + if(!json) + log_world("Could not open map_config: [filename]") + return + + json = file2text(json) + if(!json) + log_world("map_config is not text: [filename]") + return + + json = json_decode(json) + if(!json) + log_world("map_config is not json: [filename]") + return + + config_filename = filename + + CHECK_EXISTS("map_name") + map_name = json["map_name"] + CHECK_EXISTS("map_path") + map_path = json["map_path"] + + map_file = json["map_file"] + // "map_file": "BoxStation.dmm" + if (istext(map_file)) + if (!fexists("_maps/[map_path]/[map_file]")) + log_world("Map file ([map_path]/[map_file]) does not exist!") + return + // "map_file": ["Lower.dmm", "Upper.dmm"] + else if (islist(map_file)) + for (var/file in map_file) + if (!fexists("_maps/[map_path]/[file]")) + log_world("Map file ([map_path]/[file]) does not exist!") + return + else + log_world("map_file missing from json!") + return + + if (islist(json["shuttles"])) + var/list/L = json["shuttles"] + for(var/key in L) + var/value = L[key] + shuttles[key] = value + else if ("shuttles" in json) + log_world("map_config shuttles is not a list!") + return + + traits = json["traits"] + // "traits": [{"Linkage": "Cross"}, {"Space Ruins": true}] + if (islist(traits)) + // "Station" is set by default, but it's assumed if you're setting + // traits you want to customize which level is cross-linked + for (var/level in traits) + if (!(ZTRAIT_STATION in level)) + level[ZTRAIT_STATION] = TRUE + // "traits": null or absent -> default + else if (!isnull(traits)) + log_world("map_config traits is not a list!") + return + + var/temp = json["space_ruin_levels"] + if (isnum(temp)) + space_ruin_levels = temp + else if (!isnull(temp)) + log_world("map_config space_ruin_levels is not a number!") + return + + temp = json["space_empty_levels"] + if (isnum(temp)) + space_empty_levels = temp + else if (!isnull(temp)) + log_world("map_config space_empty_levels is not a number!") + return + + temp = json["year_offset"] + if (isnum(temp)) + year_offset = temp + else if (!isnull(temp)) + log_world("map_config year_offset is not a number!") + return + + if ("minetype" in json) + minetype = json["minetype"] + + if ("maptype" in json) + maptype = json["maptype"] + + if ("announcertype" in json) + announcertype = json["announcertype"] + + allow_custom_shuttles = json["allow_custom_shuttles"] != FALSE + + defaulted = FALSE + return TRUE +#undef CHECK_EXISTS + +/datum/map_config/proc/GetFullMapPaths() + if (istext(map_file)) + return list("_maps/[map_path]/[map_file]") + . = list() + for (var/file in map_file) + . += "_maps/[map_path]/[file]" + +/datum/map_config/proc/MakeNextMap() + return config_filename == "data/next_map.json" || fcopy(config_filename, "data/next_map.json") diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 8ae45ff720..42f18b8ebb 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1,780 +1,780 @@ -/* Note from Carnie: - The way datum/mind stuff works has been changed a lot. - Minds now represent IC characters rather than following a client around constantly. - - Guidelines for using minds properly: - - - Never mind.transfer_to(ghost). The var/current and var/original of a mind must always be of type mob/living! - ghost.mind is however used as a reference to the ghost's corpse - - - When creating a new mob for an existing IC character (e.g. cloning a dead guy or borging a brain of a human) - the existing mind of the old mob should be transfered to the new mob like so: - - mind.transfer_to(new_mob) - - - You must not assign key= or ckey= after transfer_to() since the transfer_to transfers the client for you. - By setting key or ckey explicitly after transferring the mind with transfer_to you will cause bugs like DCing - the player. - - - IMPORTANT NOTE 2, if you want a player to become a ghost, use mob.ghostize() It does all the hard work for you. - - - When creating a new mob which will be a new IC character (e.g. putting a shade in a construct or randomly selecting - a ghost to become a xeno during an event), use this mob proc. - - mob.transfer_ckey(new_mob) - - The Login proc will handle making a new mind for that mobtype (including setting up stuff like mind.name). Simple! - However if you want that mind to have any special properties like being a traitor etc you will have to do that - yourself. - -*/ - -/datum/mind - var/key - var/name //replaces mob/var/original_name - var/mob/living/current - var/active = 0 - - var/memory - - var/assigned_role - var/special_role - var/list/restricted_roles = list() - - var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button. - - var/linglink - var/datum/martial_art/martial_art - var/static/default_martial_art = new/datum/martial_art - var/miming = 0 // Mime's vow of silence - var/list/antag_datums - var/antag_hud_icon_state = null //this mind's ANTAG_HUD should have this icon_state - var/datum/atom_hud/antag/antag_hud = null //this mind's antag HUD - var/damnation_type = 0 - var/datum/mind/soulOwner //who owns the soul. Under normal circumstances, this will point to src - var/hasSoul = TRUE // If false, renders the character unable to sell their soul. - var/isholy = FALSE //is this person a chaplain or admin role allowed to use bibles - - var/mob/living/enslaved_to //If this mind's master is another mob (i.e. adamantine golems) - var/datum/language_holder/language_holder - var/unconvertable = FALSE - var/late_joiner = FALSE - - var/force_escaped = FALSE // Set by Into The Sunset command of the shuttle manipulator - - var/list/learned_recipes //List of learned recipe TYPES. - -/datum/mind/New(var/key) - src.key = key - soulOwner = src - martial_art = default_martial_art - -/datum/mind/Destroy() - SSticker.minds -= src - if(islist(antag_datums)) - for(var/i in antag_datums) - var/datum/antagonist/antag_datum = i - if(antag_datum.delete_on_mind_deletion) - qdel(i) - antag_datums = null - return ..() - -/datum/mind/proc/get_language_holder() - if(!language_holder) - var/datum/language_holder/L = current.get_language_holder(shadow=FALSE) - language_holder = L.copy(src) - - return language_holder - -/datum/mind/proc/transfer_to(mob/new_character, var/force_key_move = 0) - var/old_character = current - var/signals = SEND_SIGNAL(new_character, COMSIG_MOB_PRE_PLAYER_CHANGE, new_character, old_character) | SEND_SIGNAL(src, COMSIG_PRE_MIND_TRANSFER, new_character, old_character) - if(signals & COMPONENT_STOP_MIND_TRANSFER) - return - if(current) // remove ourself from our old body's mind variable - current.mind = null - SStgui.on_transfer(current, new_character) - if(iscarbon(current)) - var/mob/living/carbon/C = current - if(C.combatmode) - C.toggle_combat_mode(TRUE, TRUE) - if(!language_holder) - var/datum/language_holder/mob_holder = new_character.get_language_holder(shadow = FALSE) - language_holder = mob_holder.copy(src) - - if(key) - if(new_character.key != key) //if we're transferring into a body with a key associated which is not ours - new_character.ghostize(TRUE, TRUE) //we'll need to ghostize so that key isn't mobless. - else - key = new_character.key - - if(new_character.mind) //disassociate any mind currently in our new body's mind variable - new_character.mind.current = null - - var/datum/atom_hud/antag/hud_to_transfer = antag_hud//we need this because leave_hud() will clear this list - var/mob/living/old_current = current - if(current) - current.transfer_observers_to(new_character) //transfer anyone observing the old character to the new one - current = new_character //associate ourself with our new body - new_character.mind = src //and associate our new body with ourself - for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body - var/datum/antagonist/A = a - A.on_body_transfer(old_current, current) - if(iscarbon(new_character)) - var/mob/living/carbon/C = new_character - C.last_mind = src - transfer_antag_huds(hud_to_transfer) //inherit the antag HUD - transfer_actions(new_character) - transfer_martial_arts(new_character) - if(active || force_key_move) - new_character.key = key //now transfer the key to link the client to our new body - -//CIT CHANGE - makes arousal update when transfering bodies - if(isliving(new_character)) //New humans and such are by default enabled arousal. Let's always use the new mind's prefs. - var/mob/living/L = new_character - if(L.client && L.client.prefs) - L.canbearoused = L.client.prefs.arousable //Technically this should make taking over a character mean the body gain the new minds setting... - L.update_arousal_hud() //Removes the old icon - if (L.client.prefs.auto_ooc) - if (L.client.prefs.chat_toggles & CHAT_OOC) - L.client.prefs.chat_toggles ^= CHAT_OOC - - SEND_SIGNAL(src, COMSIG_MIND_TRANSFER, new_character, old_character) - SEND_SIGNAL(new_character, COMSIG_MOB_ON_NEW_MIND) - -/datum/mind/proc/store_memory(new_text) - if((length(memory) + length(new_text)) <= MAX_MESSAGE_LEN) - memory += "[new_text]
      " - -/datum/mind/proc/wipe_memory() - memory = null - -// Datum antag mind procs -/datum/mind/proc/add_antag_datum(datum_type_or_instance, team) - if(!datum_type_or_instance) - return - var/datum/antagonist/A - if(!ispath(datum_type_or_instance)) - A = datum_type_or_instance - if(!istype(A)) - return - else - A = new datum_type_or_instance() - //Choose snowflake variation if antagonist handles it - var/datum/antagonist/S = A.specialization(src) - if(S && S != A) - qdel(A) - A = S - if(!A.can_be_owned(src)) - qdel(A) - return - A.owner = src - LAZYADD(antag_datums, A) - A.create_team(team) - var/datum/team/antag_team = A.get_team() - if(antag_team) - antag_team.add_member(src) - A.on_gain() - return A - -/datum/mind/proc/remove_antag_datum(datum_type) - if(!datum_type) - return - var/datum/antagonist/A = has_antag_datum(datum_type) - if(A) - A.on_removal() - return TRUE - - -/datum/mind/proc/remove_all_antag_datums() //For the Lazy amongst us. - for(var/a in antag_datums) - var/datum/antagonist/A = a - A.on_removal() - -/datum/mind/proc/has_antag_datum(datum_type, check_subtypes = TRUE) - if(!datum_type) - return - . = FALSE - for(var/a in antag_datums) - var/datum/antagonist/A = a - if(check_subtypes && istype(A, datum_type)) - return A - else if(A.type == datum_type) - return A - -/* - Removes antag type's references from a mind. - objectives, uplinks, powers etc are all handled. -*/ - -/datum/mind/proc/remove_changeling() - var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling) - if(C) - remove_antag_datum(/datum/antagonist/changeling) - special_role = null - -/datum/mind/proc/remove_traitor() - remove_antag_datum(/datum/antagonist/traitor) - -/datum/mind/proc/remove_brother() - if(src in SSticker.mode.brothers) - remove_antag_datum(/datum/antagonist/brother) - SSticker.mode.update_brother_icons_removed(src) - -/datum/mind/proc/remove_nukeop() - var/datum/antagonist/nukeop/nuke = has_antag_datum(/datum/antagonist/nukeop,TRUE) - if(nuke) - remove_antag_datum(nuke.type) - special_role = null - -/datum/mind/proc/remove_wizard() - remove_antag_datum(/datum/antagonist/wizard) - special_role = null - -/datum/mind/proc/remove_cultist() - if(src in SSticker.mode.cult) - SSticker.mode.remove_cultist(src, 0, 0) - special_role = null - remove_antag_equip() - -/datum/mind/proc/remove_rev() - var/datum/antagonist/rev/rev = has_antag_datum(/datum/antagonist/rev) - if(rev) - remove_antag_datum(rev.type) - special_role = null - - -/datum/mind/proc/remove_antag_equip() - var/list/Mob_Contents = current.get_contents() - for(var/obj/item/I in Mob_Contents) - var/datum/component/uplink/O = I.GetComponent(/datum/component/uplink) -//Todo make this reset signal - if(O) - O.unlock_code = null - -/datum/mind/proc/remove_all_antag() //For the Lazy amongst us. - remove_changeling() - remove_traitor() - remove_nukeop() - remove_wizard() - remove_cultist() - remove_rev() - SSticker.mode.update_cult_icons_removed(src) - -/datum/mind/proc/equip_traitor(employer = "The Syndicate", silent = FALSE, datum/antagonist/uplink_owner) - if(!current) - return - var/mob/living/carbon/human/traitor_mob = current - if (!istype(traitor_mob)) - return - - var/list/all_contents = traitor_mob.GetAllContents() - var/obj/item/pda/PDA = locate() in all_contents - var/obj/item/radio/R = locate() in all_contents - var/obj/item/pen/P - - if (PDA) // Prioritize PDA pen, otherwise the pocket protector pens will be chosen, which causes numerous ahelps about missing uplink - P = locate() in PDA - if (!P) // If we couldn't find a pen in the PDA, or we didn't even have a PDA, do it the old way - P = locate() in all_contents - if(!P) // I do not have a pen. - var/obj/item/pen/inowhaveapen - if(istype(traitor_mob.back,/obj/item/storage)) //ok buddy you better have a backpack! - inowhaveapen = new /obj/item/pen(traitor_mob.back) - else - inowhaveapen = new /obj/item/pen(traitor_mob.loc) - traitor_mob.put_in_hands(inowhaveapen) // I hope you don't have arms and your traitor pen gets stolen for all this trouble you've caused. - P = inowhaveapen - - var/obj/item/uplink_loc - - if(traitor_mob.client && traitor_mob.client.prefs) - switch(traitor_mob.client.prefs.uplink_spawn_loc) - if(UPLINK_PDA) - uplink_loc = PDA - if(!uplink_loc) - uplink_loc = R - if(!uplink_loc) - uplink_loc = P - if(UPLINK_RADIO) - uplink_loc = R - if(!uplink_loc) - uplink_loc = PDA - if(!uplink_loc) - uplink_loc = P - if(UPLINK_PEN) - uplink_loc = P - if(!uplink_loc) - uplink_loc = PDA - if(!uplink_loc) - uplink_loc = R - - if (!uplink_loc) - if(!silent) - to_chat(traitor_mob, "Unfortunately, [employer] wasn't able to get you an Uplink.") - . = 0 - else - . = uplink_loc - var/datum/component/uplink/U = uplink_loc.AddComponent(/datum/component/uplink, traitor_mob.key) - if(!U) - CRASH("Uplink creation failed.") - U.setup_unlock_code() - if(!silent) - if(uplink_loc == R) - to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(U.unlock_code)] to unlock its hidden features.") - else if(uplink_loc == PDA) - to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[U.unlock_code]\" into the ringtone select to unlock its hidden features.") - else if(uplink_loc == P) - to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [U.unlock_code] from its starting position to unlock its hidden features.") - - if(uplink_owner) - uplink_owner.antag_memory += U.unlock_note + "
      " - else - traitor_mob.mind.store_memory(U.unlock_note) - -//Link a new mobs mind to the creator of said mob. They will join any team they are currently on, and will only switch teams when their creator does. - -/datum/mind/proc/enslave_mind_to_creator(mob/living/creator) - if(iscultist(creator)) - SSticker.mode.add_cultist(src) - - else if(is_revolutionary(creator)) - var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev,TRUE) - converter.add_revolutionary(src,FALSE) - - else if(is_servant_of_ratvar(creator)) - add_servant_of_ratvar(current) - - else if(is_nuclear_operative(creator)) - var/datum/antagonist/nukeop/converter = creator.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE) - var/datum/antagonist/nukeop/N = new() - N.send_to_spawnpoint = FALSE - N.nukeop_outfit = null - add_antag_datum(N,converter.nuke_team) - - - enslaved_to = creator - - current.faction |= creator.faction - creator.faction |= current.faction - - if(creator.mind.special_role) - message_admins("[ADMIN_LOOKUPFLW(current)] has been created by [ADMIN_LOOKUPFLW(creator)], an antagonist.") - to_chat(current, "Despite your creators current allegiances, your true master remains [creator.real_name]. If their loyalties change, so do yours. This will never change unless your creator's body is destroyed.") - -/datum/mind/proc/show_memory(mob/recipient, window=1) - if(!recipient) - recipient = current - var/output = "[current.real_name]'s Memories:
      " - output += memory - - - var/list/all_objectives = list() - for(var/datum/antagonist/A in antag_datums) - output += A.antag_memory - all_objectives |= A.objectives - - if(all_objectives.len) - output += "Objectives:" - var/obj_count = 1 - for(var/datum/objective/objective in all_objectives) - output += "
      Objective #[obj_count++]: [objective.explanation_text]" - var/list/datum/mind/other_owners = objective.get_owners() - src - if(other_owners.len) - output += "
        " - for(var/datum/mind/M in other_owners) - output += "
      • Conspirator: [M.name]
      • " - output += "
      " - - if(window) - recipient << browse(output,"window=memory") - else if(all_objectives.len || memory) - to_chat(recipient, "[output]") - -/datum/mind/Topic(href, href_list) - if(!check_rights(R_ADMIN)) - return - - var/self_antagging = usr == current - - if(href_list["add_antag"]) - add_antag_wrapper(text2path(href_list["add_antag"]),usr) - if(href_list["remove_antag"]) - var/datum/antagonist/A = locate(href_list["remove_antag"]) in antag_datums - if(!istype(A)) - to_chat(usr,"Invalid antagonist ref to be removed.") - return - A.admin_remove(usr) - - if (href_list["role_edit"]) - var/new_role = input("Select new role", "Assigned role", assigned_role) as null|anything in get_all_jobs() - if (!new_role) - return - assigned_role = new_role - - else if (href_list["memory_edit"]) - var/new_memo = copytext(sanitize(input("Write new memory", "Memory", memory) as null|message),1,MAX_MESSAGE_LEN) - if (isnull(new_memo)) - return - memory = new_memo - - else if (href_list["obj_edit"] || href_list["obj_add"]) - var/objective_pos //Edited objectives need to keep same order in antag objective list - var/def_value - var/datum/antagonist/target_antag - var/datum/objective/old_objective //The old objective we're replacing/editing - var/datum/objective/new_objective //New objective we're be adding - - if(href_list["obj_edit"]) - for(var/datum/antagonist/A in antag_datums) - old_objective = locate(href_list["obj_edit"]) in A.objectives - if(old_objective) - target_antag = A - objective_pos = A.objectives.Find(old_objective) - break - if(!old_objective) - to_chat(usr,"Invalid objective.") - return - - else - if(href_list["target_antag"]) - var/datum/antagonist/X = locate(href_list["target_antag"]) in antag_datums - if(X) - target_antag = X - if(!target_antag) - switch(antag_datums.len) - if(0) - target_antag = add_antag_datum(/datum/antagonist/custom) - if(1) - target_antag = antag_datums[1] - else - var/datum/antagonist/target = input("Which antagonist gets the objective:", "Antagonist", "(new custom antag)") as null|anything in antag_datums + "(new custom antag)" - if (QDELETED(target)) - return - else if(target == "(new custom antag)") - target_antag = add_antag_datum(/datum/antagonist/custom) - else - target_antag = target - - var/static/list/choices - if(!choices) - choices = list() - - var/list/allowed_types = list( - /datum/objective/assassinate, - /datum/objective/maroon, - /datum/objective/debrain, - /datum/objective/protect, - /datum/objective/destroy, - /datum/objective/hijack, - /datum/objective/escape, - /datum/objective/survive, - /datum/objective/martyr, - /datum/objective/steal, - /datum/objective/download, - /datum/objective/nuclear, - /datum/objective/capture, - /datum/objective/absorb, - /datum/objective/custom - ) - - for(var/T in allowed_types) - var/datum/objective/X = T - choices[initial(X.name)] = T - - if(old_objective) - if(old_objective.name in choices) - def_value = old_objective.name - - var/selected_type = input("Select objective type:", "Objective type", def_value) as null|anything in choices - selected_type = choices[selected_type] - if (!selected_type) - return - - if(!old_objective) - //Add new one - new_objective = new selected_type - new_objective.owner = src - new_objective.admin_edit(usr) - target_antag.objectives += new_objective - - message_admins("[key_name_admin(usr)] added a new objective for [current]: [new_objective.explanation_text]") - log_admin("[key_name(usr)] added a new objective for [current]: [new_objective.explanation_text]") - else - if(old_objective.type == selected_type) - //Edit the old - old_objective.admin_edit(usr) - new_objective = old_objective - else - //Replace the old - new_objective = new selected_type - new_objective.owner = src - new_objective.admin_edit(usr) - target_antag.objectives -= old_objective - target_antag.objectives.Insert(objective_pos, new_objective) - message_admins("[key_name_admin(usr)] edited [current]'s objective to [new_objective.explanation_text]") - log_admin("[key_name(usr)] edited [current]'s objective to [new_objective.explanation_text]") - - else if (href_list["obj_delete"]) - var/datum/objective/objective - - for(var/datum/antagonist/A in antag_datums) - objective = locate(href_list["obj_delete"]) in A.objectives - if(istype(objective)) - break - if(!objective) - to_chat(usr,"Invalid objective.") - return - qdel(objective) //TODO: Needs cleaning objective destroys (whatever that means) - message_admins("[key_name_admin(usr)] removed an objective for [current]: [objective.explanation_text]") - log_admin("[key_name(usr)] removed an objective for [current]: [objective.explanation_text]") - - else if(href_list["obj_completed"]) - var/datum/objective/objective - for(var/datum/antagonist/A in antag_datums) - objective = locate(href_list["obj_completed"]) in A.objectives - if(istype(objective)) - objective = objective - break - if(!objective) - to_chat(usr,"Invalid objective.") - return - objective.completed = !objective.completed - log_admin("[key_name(usr)] toggled the win state for [current]'s objective: [objective.explanation_text]") - - else if (href_list["silicon"]) - switch(href_list["silicon"]) - if("unemag") - var/mob/living/silicon/robot/R = current - if (istype(R)) - R.SetEmagged(0) - message_admins("[key_name_admin(usr)] has unemag'ed [R].") - log_admin("[key_name(usr)] has unemag'ed [R].") - - if("unemagcyborgs") - if(isAI(current)) - var/mob/living/silicon/ai/ai = current - for (var/mob/living/silicon/robot/R in ai.connected_robots) - R.SetEmagged(0) - message_admins("[key_name_admin(usr)] has unemag'ed [ai]'s Cyborgs.") - log_admin("[key_name(usr)] has unemag'ed [ai]'s Cyborgs.") - - else if (href_list["common"]) - switch(href_list["common"]) - if("undress") - for(var/obj/item/W in current) - current.dropItemToGround(W, TRUE) //The 1 forces all items to drop, since this is an admin undress. - if("takeuplink") - take_uplink() - memory = null//Remove any memory they may have had. - log_admin("[key_name(usr)] removed [current]'s uplink.") - if("crystals") - if(check_rights(R_FUN, 0)) - var/datum/component/uplink/U = find_syndicate_uplink() - if(U) - var/crystals = input("Amount of telecrystals for [key]","Syndicate uplink", U.telecrystals) as null | num - if(!isnull(crystals)) - U.telecrystals = crystals - message_admins("[key_name_admin(usr)] changed [current]'s telecrystal count to [crystals].") - log_admin("[key_name(usr)] changed [current]'s telecrystal count to [crystals].") - if("uplink") - if(!equip_traitor()) - to_chat(usr, "Equipping a syndicate failed!") - log_admin("[key_name(usr)] tried and failed to give [current] an uplink.") - else - log_admin("[key_name(usr)] gave [current] an uplink.") - - else if (href_list["obj_announce"]) - announce_objectives() - - //Something in here might have changed your mob - if(self_antagging && (!usr || !usr.client) && current.client) - usr = current - traitor_panel() - -/datum/mind/proc/get_all_objectives() - var/list/all_objectives = list() - for(var/datum/antagonist/A in antag_datums) - all_objectives |= A.objectives - return all_objectives - -/datum/mind/proc/announce_objectives() - var/obj_count = 1 - to_chat(current, "Your current objectives:") - for(var/objective in get_all_objectives()) - var/datum/objective/O = objective - to_chat(current, "Objective #[obj_count]: [O.explanation_text]") - obj_count++ - -/datum/mind/proc/find_syndicate_uplink() - var/list/L = current.GetAllContents() - for (var/i in L) - var/atom/movable/I = i - . = I.GetComponent(/datum/component/uplink) - if(.) - break - -/datum/mind/proc/take_uplink() - qdel(find_syndicate_uplink()) - -/datum/mind/proc/make_Traitor() - if(!(has_antag_datum(/datum/antagonist/traitor))) - add_antag_datum(/datum/antagonist/traitor) - -/datum/mind/proc/make_Changeling() - var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling) - if(!C) - C = add_antag_datum(/datum/antagonist/changeling) - special_role = ROLE_CHANGELING - return C - -/datum/mind/proc/make_Wizard() - if(!has_antag_datum(/datum/antagonist/wizard)) - special_role = ROLE_WIZARD - assigned_role = ROLE_WIZARD - add_antag_datum(/datum/antagonist/wizard) - - -/datum/mind/proc/make_Cultist() - if(!has_antag_datum(/datum/antagonist/cult,TRUE)) - SSticker.mode.add_cultist(src,FALSE,equip=TRUE) - special_role = ROLE_CULTIST - to_chat(current, "You catch a glimpse of the Realm of Nar'Sie, The Geometer of Blood. You now see how flimsy your world is, you see that it should be open to the knowledge of Nar'Sie.") - to_chat(current, "Assist your new brethren in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back.") - -/datum/mind/proc/make_Rev() - var/datum/antagonist/rev/head/head = new() - head.give_flash = TRUE - head.give_hud = TRUE - add_antag_datum(head) - special_role = ROLE_REV_HEAD - -/datum/mind/proc/AddSpell(obj/effect/proc_holder/spell/S) - spell_list += S - S.action.Grant(current) - -/datum/mind/proc/owns_soul() - return soulOwner == src - -//To remove a specific spell from a mind -/datum/mind/proc/RemoveSpell(obj/effect/proc_holder/spell/spell) - if(!spell) - return - for(var/X in spell_list) - var/obj/effect/proc_holder/spell/S = X - if(istype(S, spell)) - spell_list -= S - qdel(S) - -/datum/mind/proc/RemoveAllSpells() - for(var/obj/effect/proc_holder/S in spell_list) - RemoveSpell(S) - -/datum/mind/proc/transfer_martial_arts(mob/living/new_character) - if(!ishuman(new_character)) - return - if(martial_art) - if(martial_art.base) //Is the martial art temporary? - martial_art.remove(new_character) - else - martial_art.teach(new_character) - -/datum/mind/proc/transfer_actions(mob/living/new_character) - if(current && current.actions) - for(var/datum/action/A in current.actions) - A.Grant(new_character) - transfer_mindbound_actions(new_character) - -/datum/mind/proc/transfer_mindbound_actions(mob/living/new_character) - for(var/X in spell_list) - var/obj/effect/proc_holder/spell/S = X - S.action.Grant(new_character) - var/datum/antagonist/changeling/changeling = new_character.mind.has_antag_datum(/datum/antagonist/changeling) - if(changeling &&(ishuman(new_character) || ismonkey(new_character))) - for(var/P in changeling.purchasedpowers) - var/obj/effect/proc_holder/changeling/I = P - I.action.Grant(new_character) - -/datum/mind/proc/disrupt_spells(delay, list/exceptions = New()) - for(var/X in spell_list) - var/obj/effect/proc_holder/spell/S = X - for(var/type in exceptions) - if(istype(S, type)) - continue - S.charge_counter = delay - S.updateButtonIcon() - INVOKE_ASYNC(S, /obj/effect/proc_holder/spell.proc/start_recharge) - -/datum/mind/proc/get_ghost(even_if_they_cant_reenter) - for(var/mob/dead/observer/G in GLOB.dead_mob_list) - if(G.mind == src) - if(G.can_reenter_corpse || even_if_they_cant_reenter) - return G - break - -/datum/mind/proc/grab_ghost(force) - var/mob/dead/observer/G = get_ghost(even_if_they_cant_reenter = force) - . = G - if(G) - G.reenter_corpse() - - -/datum/mind/proc/has_objective(objective_type) - for(var/datum/antagonist/A in antag_datums) - for(var/O in A.objectives) - if(istype(O,objective_type)) - return TRUE - -/mob/proc/sync_mind() - mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist) - mind.active = 1 //indicates that the mind is currently synced with a client - -/datum/mind/proc/has_martialart(var/string) - if(martial_art && martial_art.id == string) - return martial_art - return FALSE - -/mob/dead/new_player/sync_mind() - return - -/mob/dead/observer/sync_mind() - return - -//Initialisation procs -/mob/proc/mind_initialize() - if(mind) - mind.key = key - - else - mind = new /datum/mind(key) - SSticker.minds += mind - SEND_SIGNAL(src, COMSIG_MOB_ON_NEW_MIND) - if(!mind.name) - mind.name = real_name - mind.current = src - -/mob/living/carbon/mind_initialize() - ..() - last_mind = mind - -//HUMAN -/mob/living/carbon/human/mind_initialize() - ..() - if(!mind.assigned_role) - mind.assigned_role = "Unassigned" //default - -//AI -/mob/living/silicon/ai/mind_initialize() - ..() - mind.assigned_role = "AI" - -//BORG -/mob/living/silicon/robot/mind_initialize() - ..() - mind.assigned_role = "Cyborg" - -//PAI -/mob/living/silicon/pai/mind_initialize() - ..() - mind.assigned_role = ROLE_PAI - mind.special_role = "" +/* Note from Carnie: + The way datum/mind stuff works has been changed a lot. + Minds now represent IC characters rather than following a client around constantly. + + Guidelines for using minds properly: + + - Never mind.transfer_to(ghost). The var/current and var/original of a mind must always be of type mob/living! + ghost.mind is however used as a reference to the ghost's corpse + + - When creating a new mob for an existing IC character (e.g. cloning a dead guy or borging a brain of a human) + the existing mind of the old mob should be transfered to the new mob like so: + + mind.transfer_to(new_mob) + + - You must not assign key= or ckey= after transfer_to() since the transfer_to transfers the client for you. + By setting key or ckey explicitly after transferring the mind with transfer_to you will cause bugs like DCing + the player. + + - IMPORTANT NOTE 2, if you want a player to become a ghost, use mob.ghostize() It does all the hard work for you. + + - When creating a new mob which will be a new IC character (e.g. putting a shade in a construct or randomly selecting + a ghost to become a xeno during an event), use this mob proc. + + mob.transfer_ckey(new_mob) + + The Login proc will handle making a new mind for that mobtype (including setting up stuff like mind.name). Simple! + However if you want that mind to have any special properties like being a traitor etc you will have to do that + yourself. + +*/ + +/datum/mind + var/key + var/name //replaces mob/var/original_name + var/mob/living/current + var/active = 0 + + var/memory + + var/assigned_role + var/special_role + var/list/restricted_roles = list() + + var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button. + + var/linglink + var/datum/martial_art/martial_art + var/static/default_martial_art = new/datum/martial_art + var/miming = 0 // Mime's vow of silence + var/list/antag_datums + var/antag_hud_icon_state = null //this mind's ANTAG_HUD should have this icon_state + var/datum/atom_hud/antag/antag_hud = null //this mind's antag HUD + var/damnation_type = 0 + var/datum/mind/soulOwner //who owns the soul. Under normal circumstances, this will point to src + var/hasSoul = TRUE // If false, renders the character unable to sell their soul. + var/isholy = FALSE //is this person a chaplain or admin role allowed to use bibles + + var/mob/living/enslaved_to //If this mind's master is another mob (i.e. adamantine golems) + var/datum/language_holder/language_holder + var/unconvertable = FALSE + var/late_joiner = FALSE + + var/force_escaped = FALSE // Set by Into The Sunset command of the shuttle manipulator + + var/list/learned_recipes //List of learned recipe TYPES. + +/datum/mind/New(var/key) + src.key = key + soulOwner = src + martial_art = default_martial_art + +/datum/mind/Destroy() + SSticker.minds -= src + if(islist(antag_datums)) + for(var/i in antag_datums) + var/datum/antagonist/antag_datum = i + if(antag_datum.delete_on_mind_deletion) + qdel(i) + antag_datums = null + return ..() + +/datum/mind/proc/get_language_holder() + if(!language_holder) + var/datum/language_holder/L = current.get_language_holder(shadow=FALSE) + language_holder = L.copy(src) + + return language_holder + +/datum/mind/proc/transfer_to(mob/new_character, var/force_key_move = 0) + var/old_character = current + var/signals = SEND_SIGNAL(new_character, COMSIG_MOB_PRE_PLAYER_CHANGE, new_character, old_character) | SEND_SIGNAL(src, COMSIG_PRE_MIND_TRANSFER, new_character, old_character) + if(signals & COMPONENT_STOP_MIND_TRANSFER) + return + if(current) // remove ourself from our old body's mind variable + current.mind = null + SStgui.on_transfer(current, new_character) + if(iscarbon(current)) + var/mob/living/carbon/C = current + if(C.combatmode) + C.toggle_combat_mode(TRUE, TRUE) + if(!language_holder) + var/datum/language_holder/mob_holder = new_character.get_language_holder(shadow = FALSE) + language_holder = mob_holder.copy(src) + + if(key) + if(new_character.key != key) //if we're transferring into a body with a key associated which is not ours + new_character.ghostize(TRUE, TRUE) //we'll need to ghostize so that key isn't mobless. + else + key = new_character.key + + if(new_character.mind) //disassociate any mind currently in our new body's mind variable + new_character.mind.current = null + + var/datum/atom_hud/antag/hud_to_transfer = antag_hud//we need this because leave_hud() will clear this list + var/mob/living/old_current = current + if(current) + current.transfer_observers_to(new_character) //transfer anyone observing the old character to the new one + current = new_character //associate ourself with our new body + new_character.mind = src //and associate our new body with ourself + for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body + var/datum/antagonist/A = a + A.on_body_transfer(old_current, current) + if(iscarbon(new_character)) + var/mob/living/carbon/C = new_character + C.last_mind = src + transfer_antag_huds(hud_to_transfer) //inherit the antag HUD + transfer_actions(new_character) + transfer_martial_arts(new_character) + if(active || force_key_move) + new_character.key = key //now transfer the key to link the client to our new body + +//CIT CHANGE - makes arousal update when transfering bodies + if(isliving(new_character)) //New humans and such are by default enabled arousal. Let's always use the new mind's prefs. + var/mob/living/L = new_character + if(L.client && L.client.prefs) + L.canbearoused = L.client.prefs.arousable //Technically this should make taking over a character mean the body gain the new minds setting... + L.update_arousal_hud() //Removes the old icon + if (L.client.prefs.auto_ooc) + if (L.client.prefs.chat_toggles & CHAT_OOC) + L.client.prefs.chat_toggles ^= CHAT_OOC + + SEND_SIGNAL(src, COMSIG_MIND_TRANSFER, new_character, old_character) + SEND_SIGNAL(new_character, COMSIG_MOB_ON_NEW_MIND) + +/datum/mind/proc/store_memory(new_text) + if((length(memory) + length(new_text)) <= MAX_MESSAGE_LEN) + memory += "[new_text]
      " + +/datum/mind/proc/wipe_memory() + memory = null + +// Datum antag mind procs +/datum/mind/proc/add_antag_datum(datum_type_or_instance, team) + if(!datum_type_or_instance) + return + var/datum/antagonist/A + if(!ispath(datum_type_or_instance)) + A = datum_type_or_instance + if(!istype(A)) + return + else + A = new datum_type_or_instance() + //Choose snowflake variation if antagonist handles it + var/datum/antagonist/S = A.specialization(src) + if(S && S != A) + qdel(A) + A = S + if(!A.can_be_owned(src)) + qdel(A) + return + A.owner = src + LAZYADD(antag_datums, A) + A.create_team(team) + var/datum/team/antag_team = A.get_team() + if(antag_team) + antag_team.add_member(src) + A.on_gain() + return A + +/datum/mind/proc/remove_antag_datum(datum_type) + if(!datum_type) + return + var/datum/antagonist/A = has_antag_datum(datum_type) + if(A) + A.on_removal() + return TRUE + + +/datum/mind/proc/remove_all_antag_datums() //For the Lazy amongst us. + for(var/a in antag_datums) + var/datum/antagonist/A = a + A.on_removal() + +/datum/mind/proc/has_antag_datum(datum_type, check_subtypes = TRUE) + if(!datum_type) + return + . = FALSE + for(var/a in antag_datums) + var/datum/antagonist/A = a + if(check_subtypes && istype(A, datum_type)) + return A + else if(A.type == datum_type) + return A + +/* + Removes antag type's references from a mind. + objectives, uplinks, powers etc are all handled. +*/ + +/datum/mind/proc/remove_changeling() + var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling) + if(C) + remove_antag_datum(/datum/antagonist/changeling) + special_role = null + +/datum/mind/proc/remove_traitor() + remove_antag_datum(/datum/antagonist/traitor) + +/datum/mind/proc/remove_brother() + if(src in SSticker.mode.brothers) + remove_antag_datum(/datum/antagonist/brother) + SSticker.mode.update_brother_icons_removed(src) + +/datum/mind/proc/remove_nukeop() + var/datum/antagonist/nukeop/nuke = has_antag_datum(/datum/antagonist/nukeop,TRUE) + if(nuke) + remove_antag_datum(nuke.type) + special_role = null + +/datum/mind/proc/remove_wizard() + remove_antag_datum(/datum/antagonist/wizard) + special_role = null + +/datum/mind/proc/remove_cultist() + if(src in SSticker.mode.cult) + SSticker.mode.remove_cultist(src, 0, 0) + special_role = null + remove_antag_equip() + +/datum/mind/proc/remove_rev() + var/datum/antagonist/rev/rev = has_antag_datum(/datum/antagonist/rev) + if(rev) + remove_antag_datum(rev.type) + special_role = null + + +/datum/mind/proc/remove_antag_equip() + var/list/Mob_Contents = current.get_contents() + for(var/obj/item/I in Mob_Contents) + var/datum/component/uplink/O = I.GetComponent(/datum/component/uplink) +//Todo make this reset signal + if(O) + O.unlock_code = null + +/datum/mind/proc/remove_all_antag() //For the Lazy amongst us. + remove_changeling() + remove_traitor() + remove_nukeop() + remove_wizard() + remove_cultist() + remove_rev() + SSticker.mode.update_cult_icons_removed(src) + +/datum/mind/proc/equip_traitor(employer = "The Syndicate", silent = FALSE, datum/antagonist/uplink_owner) + if(!current) + return + var/mob/living/carbon/human/traitor_mob = current + if (!istype(traitor_mob)) + return + + var/list/all_contents = traitor_mob.GetAllContents() + var/obj/item/pda/PDA = locate() in all_contents + var/obj/item/radio/R = locate() in all_contents + var/obj/item/pen/P + + if (PDA) // Prioritize PDA pen, otherwise the pocket protector pens will be chosen, which causes numerous ahelps about missing uplink + P = locate() in PDA + if (!P) // If we couldn't find a pen in the PDA, or we didn't even have a PDA, do it the old way + P = locate() in all_contents + if(!P) // I do not have a pen. + var/obj/item/pen/inowhaveapen + if(istype(traitor_mob.back,/obj/item/storage)) //ok buddy you better have a backpack! + inowhaveapen = new /obj/item/pen(traitor_mob.back) + else + inowhaveapen = new /obj/item/pen(traitor_mob.loc) + traitor_mob.put_in_hands(inowhaveapen) // I hope you don't have arms and your traitor pen gets stolen for all this trouble you've caused. + P = inowhaveapen + + var/obj/item/uplink_loc + + if(traitor_mob.client && traitor_mob.client.prefs) + switch(traitor_mob.client.prefs.uplink_spawn_loc) + if(UPLINK_PDA) + uplink_loc = PDA + if(!uplink_loc) + uplink_loc = R + if(!uplink_loc) + uplink_loc = P + if(UPLINK_RADIO) + uplink_loc = R + if(!uplink_loc) + uplink_loc = PDA + if(!uplink_loc) + uplink_loc = P + if(UPLINK_PEN) + uplink_loc = P + if(!uplink_loc) + uplink_loc = PDA + if(!uplink_loc) + uplink_loc = R + + if (!uplink_loc) + if(!silent) + to_chat(traitor_mob, "Unfortunately, [employer] wasn't able to get you an Uplink.") + . = 0 + else + . = uplink_loc + var/datum/component/uplink/U = uplink_loc.AddComponent(/datum/component/uplink, traitor_mob.key) + if(!U) + CRASH("Uplink creation failed.") + U.setup_unlock_code() + if(!silent) + if(uplink_loc == R) + to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [R.name]. Simply dial the frequency [format_frequency(U.unlock_code)] to unlock its hidden features.") + else if(uplink_loc == PDA) + to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [PDA.name]. Simply enter the code \"[U.unlock_code]\" into the ringtone select to unlock its hidden features.") + else if(uplink_loc == P) + to_chat(traitor_mob, "[employer] has cunningly disguised a Syndicate Uplink as your [P.name]. Simply twist the top of the pen [U.unlock_code] from its starting position to unlock its hidden features.") + + if(uplink_owner) + uplink_owner.antag_memory += U.unlock_note + "
      " + else + traitor_mob.mind.store_memory(U.unlock_note) + +//Link a new mobs mind to the creator of said mob. They will join any team they are currently on, and will only switch teams when their creator does. + +/datum/mind/proc/enslave_mind_to_creator(mob/living/creator) + if(iscultist(creator)) + SSticker.mode.add_cultist(src) + + else if(is_revolutionary(creator)) + var/datum/antagonist/rev/converter = creator.mind.has_antag_datum(/datum/antagonist/rev,TRUE) + converter.add_revolutionary(src,FALSE) + + else if(is_servant_of_ratvar(creator)) + add_servant_of_ratvar(current) + + else if(is_nuclear_operative(creator)) + var/datum/antagonist/nukeop/converter = creator.mind.has_antag_datum(/datum/antagonist/nukeop,TRUE) + var/datum/antagonist/nukeop/N = new() + N.send_to_spawnpoint = FALSE + N.nukeop_outfit = null + add_antag_datum(N,converter.nuke_team) + + + enslaved_to = creator + + current.faction |= creator.faction + creator.faction |= current.faction + + if(creator.mind.special_role) + message_admins("[ADMIN_LOOKUPFLW(current)] has been created by [ADMIN_LOOKUPFLW(creator)], an antagonist.") + to_chat(current, "Despite your creators current allegiances, your true master remains [creator.real_name]. If their loyalties change, so do yours. This will never change unless your creator's body is destroyed.") + +/datum/mind/proc/show_memory(mob/recipient, window=1) + if(!recipient) + recipient = current + var/output = "[current.real_name]'s Memories:
      " + output += memory + + + var/list/all_objectives = list() + for(var/datum/antagonist/A in antag_datums) + output += A.antag_memory + all_objectives |= A.objectives + + if(all_objectives.len) + output += "Objectives:" + var/obj_count = 1 + for(var/datum/objective/objective in all_objectives) + output += "
      Objective #[obj_count++]: [objective.explanation_text]" + var/list/datum/mind/other_owners = objective.get_owners() - src + if(other_owners.len) + output += "
        " + for(var/datum/mind/M in other_owners) + output += "
      • Conspirator: [M.name]
      • " + output += "
      " + + if(window) + recipient << browse(output,"window=memory") + else if(all_objectives.len || memory) + to_chat(recipient, "[output]") + +/datum/mind/Topic(href, href_list) + if(!check_rights(R_ADMIN)) + return + + var/self_antagging = usr == current + + if(href_list["add_antag"]) + add_antag_wrapper(text2path(href_list["add_antag"]),usr) + if(href_list["remove_antag"]) + var/datum/antagonist/A = locate(href_list["remove_antag"]) in antag_datums + if(!istype(A)) + to_chat(usr,"Invalid antagonist ref to be removed.") + return + A.admin_remove(usr) + + if (href_list["role_edit"]) + var/new_role = input("Select new role", "Assigned role", assigned_role) as null|anything in get_all_jobs() + if (!new_role) + return + assigned_role = new_role + + else if (href_list["memory_edit"]) + var/new_memo = copytext(sanitize(input("Write new memory", "Memory", memory) as null|message),1,MAX_MESSAGE_LEN) + if (isnull(new_memo)) + return + memory = new_memo + + else if (href_list["obj_edit"] || href_list["obj_add"]) + var/objective_pos //Edited objectives need to keep same order in antag objective list + var/def_value + var/datum/antagonist/target_antag + var/datum/objective/old_objective //The old objective we're replacing/editing + var/datum/objective/new_objective //New objective we're be adding + + if(href_list["obj_edit"]) + for(var/datum/antagonist/A in antag_datums) + old_objective = locate(href_list["obj_edit"]) in A.objectives + if(old_objective) + target_antag = A + objective_pos = A.objectives.Find(old_objective) + break + if(!old_objective) + to_chat(usr,"Invalid objective.") + return + + else + if(href_list["target_antag"]) + var/datum/antagonist/X = locate(href_list["target_antag"]) in antag_datums + if(X) + target_antag = X + if(!target_antag) + switch(antag_datums.len) + if(0) + target_antag = add_antag_datum(/datum/antagonist/custom) + if(1) + target_antag = antag_datums[1] + else + var/datum/antagonist/target = input("Which antagonist gets the objective:", "Antagonist", "(new custom antag)") as null|anything in antag_datums + "(new custom antag)" + if (QDELETED(target)) + return + else if(target == "(new custom antag)") + target_antag = add_antag_datum(/datum/antagonist/custom) + else + target_antag = target + + var/static/list/choices + if(!choices) + choices = list() + + var/list/allowed_types = list( + /datum/objective/assassinate, + /datum/objective/maroon, + /datum/objective/debrain, + /datum/objective/protect, + /datum/objective/destroy, + /datum/objective/hijack, + /datum/objective/escape, + /datum/objective/survive, + /datum/objective/martyr, + /datum/objective/steal, + /datum/objective/download, + /datum/objective/nuclear, + /datum/objective/capture, + /datum/objective/absorb, + /datum/objective/custom + ) + + for(var/T in allowed_types) + var/datum/objective/X = T + choices[initial(X.name)] = T + + if(old_objective) + if(old_objective.name in choices) + def_value = old_objective.name + + var/selected_type = input("Select objective type:", "Objective type", def_value) as null|anything in choices + selected_type = choices[selected_type] + if (!selected_type) + return + + if(!old_objective) + //Add new one + new_objective = new selected_type + new_objective.owner = src + new_objective.admin_edit(usr) + target_antag.objectives += new_objective + + message_admins("[key_name_admin(usr)] added a new objective for [current]: [new_objective.explanation_text]") + log_admin("[key_name(usr)] added a new objective for [current]: [new_objective.explanation_text]") + else + if(old_objective.type == selected_type) + //Edit the old + old_objective.admin_edit(usr) + new_objective = old_objective + else + //Replace the old + new_objective = new selected_type + new_objective.owner = src + new_objective.admin_edit(usr) + target_antag.objectives -= old_objective + target_antag.objectives.Insert(objective_pos, new_objective) + message_admins("[key_name_admin(usr)] edited [current]'s objective to [new_objective.explanation_text]") + log_admin("[key_name(usr)] edited [current]'s objective to [new_objective.explanation_text]") + + else if (href_list["obj_delete"]) + var/datum/objective/objective + + for(var/datum/antagonist/A in antag_datums) + objective = locate(href_list["obj_delete"]) in A.objectives + if(istype(objective)) + break + if(!objective) + to_chat(usr,"Invalid objective.") + return + qdel(objective) //TODO: Needs cleaning objective destroys (whatever that means) + message_admins("[key_name_admin(usr)] removed an objective for [current]: [objective.explanation_text]") + log_admin("[key_name(usr)] removed an objective for [current]: [objective.explanation_text]") + + else if(href_list["obj_completed"]) + var/datum/objective/objective + for(var/datum/antagonist/A in antag_datums) + objective = locate(href_list["obj_completed"]) in A.objectives + if(istype(objective)) + objective = objective + break + if(!objective) + to_chat(usr,"Invalid objective.") + return + objective.completed = !objective.completed + log_admin("[key_name(usr)] toggled the win state for [current]'s objective: [objective.explanation_text]") + + else if (href_list["silicon"]) + switch(href_list["silicon"]) + if("unemag") + var/mob/living/silicon/robot/R = current + if (istype(R)) + R.SetEmagged(0) + message_admins("[key_name_admin(usr)] has unemag'ed [R].") + log_admin("[key_name(usr)] has unemag'ed [R].") + + if("unemagcyborgs") + if(isAI(current)) + var/mob/living/silicon/ai/ai = current + for (var/mob/living/silicon/robot/R in ai.connected_robots) + R.SetEmagged(0) + message_admins("[key_name_admin(usr)] has unemag'ed [ai]'s Cyborgs.") + log_admin("[key_name(usr)] has unemag'ed [ai]'s Cyborgs.") + + else if (href_list["common"]) + switch(href_list["common"]) + if("undress") + for(var/obj/item/W in current) + current.dropItemToGround(W, TRUE) //The 1 forces all items to drop, since this is an admin undress. + if("takeuplink") + take_uplink() + memory = null//Remove any memory they may have had. + log_admin("[key_name(usr)] removed [current]'s uplink.") + if("crystals") + if(check_rights(R_FUN, 0)) + var/datum/component/uplink/U = find_syndicate_uplink() + if(U) + var/crystals = input("Amount of telecrystals for [key]","Syndicate uplink", U.telecrystals) as null | num + if(!isnull(crystals)) + U.telecrystals = crystals + message_admins("[key_name_admin(usr)] changed [current]'s telecrystal count to [crystals].") + log_admin("[key_name(usr)] changed [current]'s telecrystal count to [crystals].") + if("uplink") + if(!equip_traitor()) + to_chat(usr, "Equipping a syndicate failed!") + log_admin("[key_name(usr)] tried and failed to give [current] an uplink.") + else + log_admin("[key_name(usr)] gave [current] an uplink.") + + else if (href_list["obj_announce"]) + announce_objectives() + + //Something in here might have changed your mob + if(self_antagging && (!usr || !usr.client) && current.client) + usr = current + traitor_panel() + +/datum/mind/proc/get_all_objectives() + var/list/all_objectives = list() + for(var/datum/antagonist/A in antag_datums) + all_objectives |= A.objectives + return all_objectives + +/datum/mind/proc/announce_objectives() + var/obj_count = 1 + to_chat(current, "Your current objectives:") + for(var/objective in get_all_objectives()) + var/datum/objective/O = objective + to_chat(current, "Objective #[obj_count]: [O.explanation_text]") + obj_count++ + +/datum/mind/proc/find_syndicate_uplink() + var/list/L = current.GetAllContents() + for (var/i in L) + var/atom/movable/I = i + . = I.GetComponent(/datum/component/uplink) + if(.) + break + +/datum/mind/proc/take_uplink() + qdel(find_syndicate_uplink()) + +/datum/mind/proc/make_Traitor() + if(!(has_antag_datum(/datum/antagonist/traitor))) + add_antag_datum(/datum/antagonist/traitor) + +/datum/mind/proc/make_Changeling() + var/datum/antagonist/changeling/C = has_antag_datum(/datum/antagonist/changeling) + if(!C) + C = add_antag_datum(/datum/antagonist/changeling) + special_role = ROLE_CHANGELING + return C + +/datum/mind/proc/make_Wizard() + if(!has_antag_datum(/datum/antagonist/wizard)) + special_role = ROLE_WIZARD + assigned_role = ROLE_WIZARD + add_antag_datum(/datum/antagonist/wizard) + + +/datum/mind/proc/make_Cultist() + if(!has_antag_datum(/datum/antagonist/cult,TRUE)) + SSticker.mode.add_cultist(src,FALSE,equip=TRUE) + special_role = ROLE_CULTIST + to_chat(current, "You catch a glimpse of the Realm of Nar'Sie, The Geometer of Blood. You now see how flimsy your world is, you see that it should be open to the knowledge of Nar'Sie.") + to_chat(current, "Assist your new brethren in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back.") + +/datum/mind/proc/make_Rev() + var/datum/antagonist/rev/head/head = new() + head.give_flash = TRUE + head.give_hud = TRUE + add_antag_datum(head) + special_role = ROLE_REV_HEAD + +/datum/mind/proc/AddSpell(obj/effect/proc_holder/spell/S) + spell_list += S + S.action.Grant(current) + +/datum/mind/proc/owns_soul() + return soulOwner == src + +//To remove a specific spell from a mind +/datum/mind/proc/RemoveSpell(obj/effect/proc_holder/spell/spell) + if(!spell) + return + for(var/X in spell_list) + var/obj/effect/proc_holder/spell/S = X + if(istype(S, spell)) + spell_list -= S + qdel(S) + +/datum/mind/proc/RemoveAllSpells() + for(var/obj/effect/proc_holder/S in spell_list) + RemoveSpell(S) + +/datum/mind/proc/transfer_martial_arts(mob/living/new_character) + if(!ishuman(new_character)) + return + if(martial_art) + if(martial_art.base) //Is the martial art temporary? + martial_art.remove(new_character) + else + martial_art.teach(new_character) + +/datum/mind/proc/transfer_actions(mob/living/new_character) + if(current && current.actions) + for(var/datum/action/A in current.actions) + A.Grant(new_character) + transfer_mindbound_actions(new_character) + +/datum/mind/proc/transfer_mindbound_actions(mob/living/new_character) + for(var/X in spell_list) + var/obj/effect/proc_holder/spell/S = X + S.action.Grant(new_character) + var/datum/antagonist/changeling/changeling = new_character.mind.has_antag_datum(/datum/antagonist/changeling) + if(changeling &&(ishuman(new_character) || ismonkey(new_character))) + for(var/P in changeling.purchasedpowers) + var/obj/effect/proc_holder/changeling/I = P + I.action.Grant(new_character) + +/datum/mind/proc/disrupt_spells(delay, list/exceptions = New()) + for(var/X in spell_list) + var/obj/effect/proc_holder/spell/S = X + for(var/type in exceptions) + if(istype(S, type)) + continue + S.charge_counter = delay + S.updateButtonIcon() + INVOKE_ASYNC(S, /obj/effect/proc_holder/spell.proc/start_recharge) + +/datum/mind/proc/get_ghost(even_if_they_cant_reenter) + for(var/mob/dead/observer/G in GLOB.dead_mob_list) + if(G.mind == src) + if(G.can_reenter_corpse || even_if_they_cant_reenter) + return G + break + +/datum/mind/proc/grab_ghost(force) + var/mob/dead/observer/G = get_ghost(even_if_they_cant_reenter = force) + . = G + if(G) + G.reenter_corpse() + + +/datum/mind/proc/has_objective(objective_type) + for(var/datum/antagonist/A in antag_datums) + for(var/O in A.objectives) + if(istype(O,objective_type)) + return TRUE + +/mob/proc/sync_mind() + mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist) + mind.active = 1 //indicates that the mind is currently synced with a client + +/datum/mind/proc/has_martialart(var/string) + if(martial_art && martial_art.id == string) + return martial_art + return FALSE + +/mob/dead/new_player/sync_mind() + return + +/mob/dead/observer/sync_mind() + return + +//Initialisation procs +/mob/proc/mind_initialize() + if(mind) + mind.key = key + + else + mind = new /datum/mind(key) + SSticker.minds += mind + SEND_SIGNAL(src, COMSIG_MOB_ON_NEW_MIND) + if(!mind.name) + mind.name = real_name + mind.current = src + +/mob/living/carbon/mind_initialize() + ..() + last_mind = mind + +//HUMAN +/mob/living/carbon/human/mind_initialize() + ..() + if(!mind.assigned_role) + mind.assigned_role = "Unassigned" //default + +//AI +/mob/living/silicon/ai/mind_initialize() + ..() + mind.assigned_role = "AI" + +//BORG +/mob/living/silicon/robot/mind_initialize() + ..() + mind.assigned_role = "Cyborg" + +//PAI +/mob/living/silicon/pai/mind_initialize() + ..() + mind.assigned_role = ROLE_PAI + mind.special_role = "" diff --git a/code/datums/mood_events/drug_events.dm b/code/datums/mood_events/drug_events.dm index 1a681a8a4d..a5d7dc631d 100644 --- a/code/datums/mood_events/drug_events.dm +++ b/code/datums/mood_events/drug_events.dm @@ -1,115 +1,115 @@ -/datum/mood_event/high - mood_change = 6 - description = "Woooow duudeeeeee...I'm tripping baaalls...\n" - -/datum/mood_event/smoked - description = "I have had a smoke recently.\n" - mood_change = 2 - timeout = 3600 - -/datum/mood_event/overdose - mood_change = -8 - timeout = 3000 - -/datum/mood_event/overdose/add_effects(drug_name) - description = "I think I took a bit too much of that [drug_name]\n" - -/datum/mood_event/withdrawal_light - mood_change = -2 - -/datum/mood_event/withdrawal_light/add_effects(drug_name) - description = "I could use some [drug_name]\n" - -/datum/mood_event/withdrawal_medium - mood_change = -5 - -/datum/mood_event/withdrawal_medium/add_effects(drug_name) - description = "I really need [drug_name]\n" - -/datum/mood_event/withdrawal_severe - mood_change = -8 - -/datum/mood_event/withdrawal_severe/add_effects(drug_name) - description = "Oh god I need some [drug_name]\n" - -/datum/mood_event/withdrawal_critical - mood_change = -10 - -/datum/mood_event/withdrawal_critical/add_effects(drug_name) - description = "[drug_name]! [drug_name]! [drug_name]!\n" - -/datum/mood_event/happiness_drug - description = "I can't feel anything and I never want this to end.\n" - mood_change = 10 - -/datum/mood_event/happiness_drug_good_od - description = "YES! YES!! YES!!!\n" - mood_change = 20 - timeout = 300 - //special_screen_obj = "mood_happiness_good" Originally in tg, but I personally think they look dumb - -/datum/mood_event/happiness_drug_bad_od - description = "NO! NO!! NO!!!\n" - mood_change = -20 - timeout = 300 - //special_screen_obj = "mood_happiness_bad" Originally in tg - -/datum/mood_event/eigenstate - mood_change = -3 - description = "Where the hell am I? Is this an alternative dimension ?\n" - -/datum/mood_event/enthrall - mood_change = 5 - -/datum/mood_event/enthrall/add_effects(message) - description = "[message]\n" - -/datum/mood_event/enthrallpraise - mood_change = 10 - timeout = 1 MINUTES - -/datum/mood_event/enthrallpraise/add_effects(message) - description = "[message]\n" - -/datum/mood_event/enthrallscold - mood_change = -10 - timeout = 1 MINUTES - -/datum/mood_event/enthrallscold/add_effects(message) - description = "[message]\n"//aaa I'm not kinky enough for this - -/datum/mood_event/enthrallmissing1 - mood_change = -5 - -/datum/mood_event/enthrallmissing1/add_effects(message) - description = "[message]\n" - -/datum/mood_event/enthrallmissing2 - mood_change = -10 - -/datum/mood_event/enthrallmissing2/add_effects(message) - description = "[message]\n" - -/datum/mood_event/enthrallmissing3 - mood_change = -15 - -/datum/mood_event/enthrallmissing3/add_effects(message) - description = "[message]\n" - -/datum/mood_event/enthrallmissing4 - mood_change = -25 - -/datum/mood_event/enthrallmissing4/add_effects(message) - description = "[message]\n" - -/datum/mood_event/InLove - mood_change = 10 - -/datum/mood_event/InLove/add_effects(message) - description = "[message]\n" - -/datum/mood_event/MissingLove - mood_change = -10 - -/datum/mood_event/MissingLove/add_effects(message) - description = "[message]\n" +/datum/mood_event/high + mood_change = 6 + description = "Woooow duudeeeeee...I'm tripping baaalls...\n" + +/datum/mood_event/smoked + description = "I have had a smoke recently.\n" + mood_change = 2 + timeout = 3600 + +/datum/mood_event/overdose + mood_change = -8 + timeout = 3000 + +/datum/mood_event/overdose/add_effects(drug_name) + description = "I think I took a bit too much of that [drug_name]\n" + +/datum/mood_event/withdrawal_light + mood_change = -2 + +/datum/mood_event/withdrawal_light/add_effects(drug_name) + description = "I could use some [drug_name]\n" + +/datum/mood_event/withdrawal_medium + mood_change = -5 + +/datum/mood_event/withdrawal_medium/add_effects(drug_name) + description = "I really need [drug_name]\n" + +/datum/mood_event/withdrawal_severe + mood_change = -8 + +/datum/mood_event/withdrawal_severe/add_effects(drug_name) + description = "Oh god I need some [drug_name]\n" + +/datum/mood_event/withdrawal_critical + mood_change = -10 + +/datum/mood_event/withdrawal_critical/add_effects(drug_name) + description = "[drug_name]! [drug_name]! [drug_name]!\n" + +/datum/mood_event/happiness_drug + description = "I can't feel anything and I never want this to end.\n" + mood_change = 10 + +/datum/mood_event/happiness_drug_good_od + description = "YES! YES!! YES!!!\n" + mood_change = 20 + timeout = 300 + //special_screen_obj = "mood_happiness_good" Originally in tg, but I personally think they look dumb + +/datum/mood_event/happiness_drug_bad_od + description = "NO! NO!! NO!!!\n" + mood_change = -20 + timeout = 300 + //special_screen_obj = "mood_happiness_bad" Originally in tg + +/datum/mood_event/eigenstate + mood_change = -3 + description = "Where the hell am I? Is this an alternative dimension ?\n" + +/datum/mood_event/enthrall + mood_change = 5 + +/datum/mood_event/enthrall/add_effects(message) + description = "[message]\n" + +/datum/mood_event/enthrallpraise + mood_change = 10 + timeout = 1 MINUTES + +/datum/mood_event/enthrallpraise/add_effects(message) + description = "[message]\n" + +/datum/mood_event/enthrallscold + mood_change = -10 + timeout = 1 MINUTES + +/datum/mood_event/enthrallscold/add_effects(message) + description = "[message]\n"//aaa I'm not kinky enough for this + +/datum/mood_event/enthrallmissing1 + mood_change = -5 + +/datum/mood_event/enthrallmissing1/add_effects(message) + description = "[message]\n" + +/datum/mood_event/enthrallmissing2 + mood_change = -10 + +/datum/mood_event/enthrallmissing2/add_effects(message) + description = "[message]\n" + +/datum/mood_event/enthrallmissing3 + mood_change = -15 + +/datum/mood_event/enthrallmissing3/add_effects(message) + description = "[message]\n" + +/datum/mood_event/enthrallmissing4 + mood_change = -25 + +/datum/mood_event/enthrallmissing4/add_effects(message) + description = "[message]\n" + +/datum/mood_event/InLove + mood_change = 10 + +/datum/mood_event/InLove/add_effects(message) + description = "[message]\n" + +/datum/mood_event/MissingLove + mood_change = -10 + +/datum/mood_event/MissingLove/add_effects(message) + description = "[message]\n" diff --git a/code/datums/mood_events/mood_event.dm b/code/datums/mood_events/mood_event.dm index dfe3049bdd..c125ba054a 100644 --- a/code/datums/mood_events/mood_event.dm +++ b/code/datums/mood_events/mood_event.dm @@ -1,20 +1,20 @@ -/datum/mood_event - var/description ///For descriptions, use the span classes bold nicegreen, nicegreen, none, warning and boldwarning in order from great to horrible. - var/mood_change = 0 - var/timeout = 0 - var/hidden = FALSE//Not shown on examine - var/mob/owner - -/datum/mood_event/New(mob/M, param) - owner = M - add_effects(param) - -/datum/mood_event/Destroy() - remove_effects() - return ..() - -/datum/mood_event/proc/add_effects(param) - return - -/datum/mood_event/proc/remove_effects() - return +/datum/mood_event + var/description ///For descriptions, use the span classes bold nicegreen, nicegreen, none, warning and boldwarning in order from great to horrible. + var/mood_change = 0 + var/timeout = 0 + var/hidden = FALSE//Not shown on examine + var/mob/owner + +/datum/mood_event/New(mob/M, param) + owner = M + add_effects(param) + +/datum/mood_event/Destroy() + remove_effects() + return ..() + +/datum/mood_event/proc/add_effects(param) + return + +/datum/mood_event/proc/remove_effects() + return diff --git a/code/datums/mood_events/needs_events.dm b/code/datums/mood_events/needs_events.dm index eb58f2aa92..962681eb94 100644 --- a/code/datums/mood_events/needs_events.dm +++ b/code/datums/mood_events/needs_events.dm @@ -1,62 +1,62 @@ -//nutrition -/datum/mood_event/fat - description = "I'm so fat...\n" //muh fatshaming - mood_change = -4 - -/datum/mood_event/wellfed - description = "I'm stuffed!\n" - mood_change = 6 - -/datum/mood_event/fed - description = "I have recently had some food.\n" - mood_change = 3 - -/datum/mood_event/hungry - description = "I'm getting a bit hungry.\n" - mood_change = -8 - -/datum/mood_event/starving - description = "I'm starving!\n" - mood_change = -15 - -//Disgust -/datum/mood_event/gross - description = "I saw something gross.\n" - mood_change = -2 - -/datum/mood_event/verygross - description = "I think I'm going to puke...\n" - mood_change = -5 - -/datum/mood_event/disgusted - description = "Oh god that's disgusting...\n" - mood_change = -8 - -/datum/mood_event/disgust/bad_smell - description = "You smell something horribly decayed inside this room.\n" - mood_change = -3 - -/datum/mood_event/disgust/nauseating_stench - description = "The stench of rotting carcasses is unbearable!\n" - mood_change = -7 - -//Generic needs events -/datum/mood_event/favorite_food - description = "I really enjoyed eating that.\n" - mood_change = 3 - timeout = 2400 - -/datum/mood_event/gross_food - description = "I really didn't like that food.\n" - mood_change = -2 - timeout = 2400 - -/datum/mood_event/disgusting_food - description = "That food was disgusting!\n" - mood_change = -4 - timeout = 2400 - -/datum/mood_event/nice_shower - description = "I have recently had a nice shower.\n" - mood_change = 2 - timeout = 3 MINUTES +//nutrition +/datum/mood_event/fat + description = "I'm so fat...\n" //muh fatshaming + mood_change = -4 + +/datum/mood_event/wellfed + description = "I'm stuffed!\n" + mood_change = 6 + +/datum/mood_event/fed + description = "I have recently had some food.\n" + mood_change = 3 + +/datum/mood_event/hungry + description = "I'm getting a bit hungry.\n" + mood_change = -8 + +/datum/mood_event/starving + description = "I'm starving!\n" + mood_change = -15 + +//Disgust +/datum/mood_event/gross + description = "I saw something gross.\n" + mood_change = -2 + +/datum/mood_event/verygross + description = "I think I'm going to puke...\n" + mood_change = -5 + +/datum/mood_event/disgusted + description = "Oh god that's disgusting...\n" + mood_change = -8 + +/datum/mood_event/disgust/bad_smell + description = "You smell something horribly decayed inside this room.\n" + mood_change = -3 + +/datum/mood_event/disgust/nauseating_stench + description = "The stench of rotting carcasses is unbearable!\n" + mood_change = -7 + +//Generic needs events +/datum/mood_event/favorite_food + description = "I really enjoyed eating that.\n" + mood_change = 3 + timeout = 2400 + +/datum/mood_event/gross_food + description = "I really didn't like that food.\n" + mood_change = -2 + timeout = 2400 + +/datum/mood_event/disgusting_food + description = "That food was disgusting!\n" + mood_change = -4 + timeout = 2400 + +/datum/mood_event/nice_shower + description = "I have recently had a nice shower.\n" + mood_change = 2 + timeout = 3 MINUTES diff --git a/code/datums/position_point_vector.dm b/code/datums/position_point_vector.dm index a33d0d2225..44ff87e8ae 100644 --- a/code/datums/position_point_vector.dm +++ b/code/datums/position_point_vector.dm @@ -1,225 +1,225 @@ -//Designed for things that need precision trajectories like projectiles. -//Don't use this for anything that you don't absolutely have to use this with (like projectiles!) because it isn't worth using a datum unless you need accuracy down to decimal places in pixels. - -//You might see places where it does - 16 - 1. This is intentionally 17 instead of 16, because of how byond's tiles work and how not doing it will result in rounding errors like things getting put on the wrong turf. - -#define RETURN_PRECISE_POSITION(A) new /datum/position(A) -#define RETURN_PRECISE_POINT(A) new /datum/point(A) - -#define RETURN_POINT_VECTOR(ATOM, ANGLE, SPEED) (new /datum/point/vector(ATOM, null, null, null, null, ANGLE, SPEED)) -#define RETURN_POINT_VECTOR_INCREMENT(ATOM, ANGLE, SPEED, AMT) (new /datum/point/vector(ATOM, null, null, null, null, ANGLE, SPEED, AMT)) - -/proc/point_midpoint_points(datum/point/a, datum/point/b) //Obviously will not support multiZ calculations! Same for the two below. - var/datum/point/P = new - P.x = a.x + (b.x - a.x) / 2 - P.y = a.y + (b.y - a.y) / 2 - P.z = a.z - return P - -/proc/pixel_length_between_points(datum/point/a, datum/point/b) - return sqrt(((b.x - a.x) ** 2) + ((b.y - a.y) ** 2)) - -/proc/angle_between_points(datum/point/a, datum/point/b) - return ATAN2((b.y - a.y), (b.x - a.x)) - -/datum/position //For positions with map x/y/z and pixel x/y so you don't have to return lists. Could use addition/subtraction in the future I guess. - var/x = 0 - var/y = 0 - var/z = 0 - var/pixel_x = 0 - var/pixel_y = 0 - -/datum/position/proc/valid() - return x && y && z && !isnull(pixel_x) && !isnull(pixel_y) - -/datum/position/New(_x = 0, _y = 0, _z = 0, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/point. - if(istype(_x, /datum/point)) - var/datum/point/P = _x - var/turf/T = P.return_turf() - _x = T.x - _y = T.y - _z = T.z - _pixel_x = P.return_px() - _pixel_y = P.return_py() - else if(isatom(_x)) - var/atom/A = _x - _x = A.x - _y = A.y - _z = A.z - _pixel_x = A.pixel_x - _pixel_y = A.pixel_y - x = _x - y = _y - z = _z - pixel_x = _pixel_x - pixel_y = _pixel_y - -/datum/position/proc/return_turf() - return locate(x, y, z) - -/datum/position/proc/return_px() - return pixel_x - -/datum/position/proc/return_py() - return pixel_y - -/datum/position/proc/return_point() - return new /datum/point(src) - -/datum/point //A precise point on the map in absolute pixel locations based on world.icon_size. Pixels are FROM THE EDGE OF THE MAP! - var/x = 0 - var/y = 0 - var/z = 0 - -/datum/point/proc/valid() - return x && y && z - -/datum/point/proc/copy_to(datum/point/p = new) - p.x = x - p.y = y - p.z = z - return p - -/datum/point/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/position or /atom. - if(istype(_x, /datum/position)) - var/datum/position/P = _x - _x = P.x - _y = P.y - _z = P.z - _pixel_x = P.pixel_x - _pixel_y = P.pixel_y - else if(istype(_x, /atom)) - var/atom/A = _x - _x = A.x - _y = A.y - _z = A.z - _pixel_x = A.pixel_x - _pixel_y = A.pixel_y - initialize_location(_x, _y, _z, _pixel_x, _pixel_y) - -/datum/point/proc/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0) - if(!isnull(tile_x)) - x = ((tile_x - 1) * world.icon_size) + world.icon_size / 2 + p_x + 1 - if(!isnull(tile_y)) - y = ((tile_y - 1) * world.icon_size) + world.icon_size / 2 + p_y + 1 - if(!isnull(tile_z)) - z = tile_z - -/datum/point/proc/debug_out() - var/turf/T = return_turf() - return "\ref[src] aX [x] aY [y] aZ [z] pX [return_px()] pY [return_py()] mX [T.x] mY [T.y] mZ [T.z]" - -/datum/point/proc/move_atom_to_src(atom/movable/AM) - AM.forceMove(return_turf()) - AM.pixel_x = return_px() - AM.pixel_y = return_py() - -/datum/point/proc/return_turf() - return locate(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z) - -/datum/point/proc/return_coordinates() //[turf_x, turf_y, z] - return list(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z) - -/datum/point/proc/return_position() - return new /datum/position(src) - -/datum/point/proc/return_px() - return MODULUS(x, world.icon_size) - 16 - 1 - -/datum/point/proc/return_py() - return MODULUS(y, world.icon_size) - 16 - 1 - -/datum/point/vector - var/speed = 32 //pixels per iteration - var/iteration = 0 - var/angle = 0 - var/mpx = 0 //calculated x/y movement amounts to prevent having to do trig every step. - var/mpy = 0 - var/starting_x = 0 //just like before, pixels from EDGE of map! This is set in initialize_location(). - var/starting_y = 0 - var/starting_z = 0 - -/datum/point/vector/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0, _angle, _speed, initial_increment = 0) - ..() - initialize_trajectory(_speed, _angle) - if(initial_increment) - increment(initial_increment) - -/datum/point/vector/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0) - . = ..() - starting_x = x - starting_y = y - starting_z = z - -/datum/point/vector/copy_to(datum/point/vector/v = new) - ..(v) - v.speed = speed - v.iteration = iteration - v.angle = angle - v.mpx = mpx - v.mpy = mpy - v.starting_x = starting_x - v.starting_y = starting_y - v.starting_z = starting_z - return v - -/datum/point/vector/proc/initialize_trajectory(pixel_speed, new_angle) - if(!isnull(pixel_speed)) - speed = pixel_speed - set_angle(new_angle) - -/datum/point/vector/proc/set_angle(new_angle) //calculations use "byond angle" where north is 0 instead of 90, and south is 180 instead of 270. - if(isnull(angle)) - return - angle = new_angle - update_offsets() - -/datum/point/vector/proc/update_offsets() - mpx = sin(angle) * speed - mpy = cos(angle) * speed - -/datum/point/vector/proc/set_speed(new_speed) - if(isnull(new_speed) || speed == new_speed) - return - speed = new_speed - update_offsets() - -/datum/point/vector/proc/increment(multiplier = 1) - iteration++ - x += mpx * (multiplier) - y += mpy * (multiplier) - -/datum/point/vector/proc/return_vector_after_increments(amount = 7, multiplier = 1, force_simulate = FALSE) - var/datum/point/vector/v = copy_to() - if(force_simulate) - for(var/i in 1 to amount) - v.increment(multiplier) - else - v.increment(multiplier * amount) - return v - -/datum/point/vector/proc/on_z_change() - return - -/datum/point/vector/processed //pixel_speed is per decisecond. - var/last_process = 0 - var/last_move = 0 - var/paused = FALSE - -/datum/point/vector/processed/Destroy() - STOP_PROCESSING(SSprojectiles, src) - -/datum/point/vector/processed/proc/start() - last_process = world.time - last_move = world.time - START_PROCESSING(SSprojectiles, src) - -/datum/point/vector/processed/process() - if(paused) - last_move += world.time - last_process - last_process = world.time - return - var/needed_time = world.time - last_move - last_process = world.time - last_move = world.time - increment(needed_time / SSprojectiles.wait) +//Designed for things that need precision trajectories like projectiles. +//Don't use this for anything that you don't absolutely have to use this with (like projectiles!) because it isn't worth using a datum unless you need accuracy down to decimal places in pixels. + +//You might see places where it does - 16 - 1. This is intentionally 17 instead of 16, because of how byond's tiles work and how not doing it will result in rounding errors like things getting put on the wrong turf. + +#define RETURN_PRECISE_POSITION(A) new /datum/position(A) +#define RETURN_PRECISE_POINT(A) new /datum/point(A) + +#define RETURN_POINT_VECTOR(ATOM, ANGLE, SPEED) (new /datum/point/vector(ATOM, null, null, null, null, ANGLE, SPEED)) +#define RETURN_POINT_VECTOR_INCREMENT(ATOM, ANGLE, SPEED, AMT) (new /datum/point/vector(ATOM, null, null, null, null, ANGLE, SPEED, AMT)) + +/proc/point_midpoint_points(datum/point/a, datum/point/b) //Obviously will not support multiZ calculations! Same for the two below. + var/datum/point/P = new + P.x = a.x + (b.x - a.x) / 2 + P.y = a.y + (b.y - a.y) / 2 + P.z = a.z + return P + +/proc/pixel_length_between_points(datum/point/a, datum/point/b) + return sqrt(((b.x - a.x) ** 2) + ((b.y - a.y) ** 2)) + +/proc/angle_between_points(datum/point/a, datum/point/b) + return ATAN2((b.y - a.y), (b.x - a.x)) + +/datum/position //For positions with map x/y/z and pixel x/y so you don't have to return lists. Could use addition/subtraction in the future I guess. + var/x = 0 + var/y = 0 + var/z = 0 + var/pixel_x = 0 + var/pixel_y = 0 + +/datum/position/proc/valid() + return x && y && z && !isnull(pixel_x) && !isnull(pixel_y) + +/datum/position/New(_x = 0, _y = 0, _z = 0, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/point. + if(istype(_x, /datum/point)) + var/datum/point/P = _x + var/turf/T = P.return_turf() + _x = T.x + _y = T.y + _z = T.z + _pixel_x = P.return_px() + _pixel_y = P.return_py() + else if(isatom(_x)) + var/atom/A = _x + _x = A.x + _y = A.y + _z = A.z + _pixel_x = A.pixel_x + _pixel_y = A.pixel_y + x = _x + y = _y + z = _z + pixel_x = _pixel_x + pixel_y = _pixel_y + +/datum/position/proc/return_turf() + return locate(x, y, z) + +/datum/position/proc/return_px() + return pixel_x + +/datum/position/proc/return_py() + return pixel_y + +/datum/position/proc/return_point() + return new /datum/point(src) + +/datum/point //A precise point on the map in absolute pixel locations based on world.icon_size. Pixels are FROM THE EDGE OF THE MAP! + var/x = 0 + var/y = 0 + var/z = 0 + +/datum/point/proc/valid() + return x && y && z + +/datum/point/proc/copy_to(datum/point/p = new) + p.x = x + p.y = y + p.z = z + return p + +/datum/point/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/position or /atom. + if(istype(_x, /datum/position)) + var/datum/position/P = _x + _x = P.x + _y = P.y + _z = P.z + _pixel_x = P.pixel_x + _pixel_y = P.pixel_y + else if(istype(_x, /atom)) + var/atom/A = _x + _x = A.x + _y = A.y + _z = A.z + _pixel_x = A.pixel_x + _pixel_y = A.pixel_y + initialize_location(_x, _y, _z, _pixel_x, _pixel_y) + +/datum/point/proc/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0) + if(!isnull(tile_x)) + x = ((tile_x - 1) * world.icon_size) + world.icon_size / 2 + p_x + 1 + if(!isnull(tile_y)) + y = ((tile_y - 1) * world.icon_size) + world.icon_size / 2 + p_y + 1 + if(!isnull(tile_z)) + z = tile_z + +/datum/point/proc/debug_out() + var/turf/T = return_turf() + return "\ref[src] aX [x] aY [y] aZ [z] pX [return_px()] pY [return_py()] mX [T.x] mY [T.y] mZ [T.z]" + +/datum/point/proc/move_atom_to_src(atom/movable/AM) + AM.forceMove(return_turf()) + AM.pixel_x = return_px() + AM.pixel_y = return_py() + +/datum/point/proc/return_turf() + return locate(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z) + +/datum/point/proc/return_coordinates() //[turf_x, turf_y, z] + return list(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z) + +/datum/point/proc/return_position() + return new /datum/position(src) + +/datum/point/proc/return_px() + return MODULUS(x, world.icon_size) - 16 - 1 + +/datum/point/proc/return_py() + return MODULUS(y, world.icon_size) - 16 - 1 + +/datum/point/vector + var/speed = 32 //pixels per iteration + var/iteration = 0 + var/angle = 0 + var/mpx = 0 //calculated x/y movement amounts to prevent having to do trig every step. + var/mpy = 0 + var/starting_x = 0 //just like before, pixels from EDGE of map! This is set in initialize_location(). + var/starting_y = 0 + var/starting_z = 0 + +/datum/point/vector/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0, _angle, _speed, initial_increment = 0) + ..() + initialize_trajectory(_speed, _angle) + if(initial_increment) + increment(initial_increment) + +/datum/point/vector/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0) + . = ..() + starting_x = x + starting_y = y + starting_z = z + +/datum/point/vector/copy_to(datum/point/vector/v = new) + ..(v) + v.speed = speed + v.iteration = iteration + v.angle = angle + v.mpx = mpx + v.mpy = mpy + v.starting_x = starting_x + v.starting_y = starting_y + v.starting_z = starting_z + return v + +/datum/point/vector/proc/initialize_trajectory(pixel_speed, new_angle) + if(!isnull(pixel_speed)) + speed = pixel_speed + set_angle(new_angle) + +/datum/point/vector/proc/set_angle(new_angle) //calculations use "byond angle" where north is 0 instead of 90, and south is 180 instead of 270. + if(isnull(angle)) + return + angle = new_angle + update_offsets() + +/datum/point/vector/proc/update_offsets() + mpx = sin(angle) * speed + mpy = cos(angle) * speed + +/datum/point/vector/proc/set_speed(new_speed) + if(isnull(new_speed) || speed == new_speed) + return + speed = new_speed + update_offsets() + +/datum/point/vector/proc/increment(multiplier = 1) + iteration++ + x += mpx * (multiplier) + y += mpy * (multiplier) + +/datum/point/vector/proc/return_vector_after_increments(amount = 7, multiplier = 1, force_simulate = FALSE) + var/datum/point/vector/v = copy_to() + if(force_simulate) + for(var/i in 1 to amount) + v.increment(multiplier) + else + v.increment(multiplier * amount) + return v + +/datum/point/vector/proc/on_z_change() + return + +/datum/point/vector/processed //pixel_speed is per decisecond. + var/last_process = 0 + var/last_move = 0 + var/paused = FALSE + +/datum/point/vector/processed/Destroy() + STOP_PROCESSING(SSprojectiles, src) + +/datum/point/vector/processed/proc/start() + last_process = world.time + last_move = world.time + START_PROCESSING(SSprojectiles, src) + +/datum/point/vector/processed/process() + if(paused) + last_move += world.time - last_process + last_process = world.time + return + var/needed_time = world.time - last_move + last_process = world.time + last_move = world.time + increment(needed_time / SSprojectiles.wait) diff --git a/code/datums/spawners_menu.dm b/code/datums/spawners_menu.dm index ebbe08c525..bb7dc4cdb7 100644 --- a/code/datums/spawners_menu.dm +++ b/code/datums/spawners_menu.dm @@ -1,54 +1,54 @@ -/datum/spawners_menu - var/mob/dead/observer/owner - -/datum/spawners_menu/New(mob/dead/observer/new_owner) - if(!istype(new_owner)) - qdel(src) - owner = new_owner - -/datum/spawners_menu/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.observer_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "spawners_menu", "Spawners Menu", 700, 600, master_ui, state) - ui.open() - -/datum/spawners_menu/ui_data(mob/user) - var/list/data = list() - data["spawners"] = list() - for(var/spawner in GLOB.mob_spawners) - var/list/this = list() - this["name"] = spawner - this["desc"] = "" - this["refs"] = list() - for(var/spawner_obj in GLOB.mob_spawners[spawner]) - this["refs"] += "[REF(spawner_obj)]" - if(!this["desc"]) - if(istype(spawner_obj, /obj/effect/mob_spawn)) - var/obj/effect/mob_spawn/MS = spawner_obj - this["desc"] = MS.flavour_text - else - var/obj/O = spawner_obj - this["desc"] = O.desc - this["amount_left"] = LAZYLEN(GLOB.mob_spawners[spawner]) - data["spawners"] += list(this) - - return data - -/datum/spawners_menu/ui_act(action, params) - if(..()) - return - - var/spawner_ref = pick(GLOB.mob_spawners[params["name"]]) - var/obj/effect/mob_spawn/MS = locate(spawner_ref) in GLOB.poi_list - if(!MS) - return - - switch(action) - if("jump") - if(MS) - owner.forceMove(get_turf(MS)) - . = TRUE - if("spawn") - if(MS) - MS.attack_ghost(owner) +/datum/spawners_menu + var/mob/dead/observer/owner + +/datum/spawners_menu/New(mob/dead/observer/new_owner) + if(!istype(new_owner)) + qdel(src) + owner = new_owner + +/datum/spawners_menu/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.observer_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "spawners_menu", "Spawners Menu", 700, 600, master_ui, state) + ui.open() + +/datum/spawners_menu/ui_data(mob/user) + var/list/data = list() + data["spawners"] = list() + for(var/spawner in GLOB.mob_spawners) + var/list/this = list() + this["name"] = spawner + this["desc"] = "" + this["refs"] = list() + for(var/spawner_obj in GLOB.mob_spawners[spawner]) + this["refs"] += "[REF(spawner_obj)]" + if(!this["desc"]) + if(istype(spawner_obj, /obj/effect/mob_spawn)) + var/obj/effect/mob_spawn/MS = spawner_obj + this["desc"] = MS.flavour_text + else + var/obj/O = spawner_obj + this["desc"] = O.desc + this["amount_left"] = LAZYLEN(GLOB.mob_spawners[spawner]) + data["spawners"] += list(this) + + return data + +/datum/spawners_menu/ui_act(action, params) + if(..()) + return + + var/spawner_ref = pick(GLOB.mob_spawners[params["name"]]) + var/obj/effect/mob_spawn/MS = locate(spawner_ref) in GLOB.poi_list + if(!MS) + return + + switch(action) + if("jump") + if(MS) + owner.forceMove(get_turf(MS)) + . = TRUE + if("spawn") + if(MS) + MS.attack_ghost(owner) . = TRUE \ No newline at end of file diff --git a/code/datums/verbs.dm b/code/datums/verbs.dm index d8d7ee7433..442997288a 100644 --- a/code/datums/verbs.dm +++ b/code/datums/verbs.dm @@ -1,102 +1,102 @@ -/datum/verbs - var/name - var/list/children - var/datum/verbs/parent - var/list/verblist - var/abstract = FALSE - -//returns the master list for verbs of a type -/datum/verbs/proc/GetList() - CRASH("Abstract verblist for [type]") - -//do things for each entry in Generate_list -//return value sets Generate_list[verbpath] -/datum/verbs/proc/HandleVerb(list/entry, procpath/verbpath, ...) - return entry - -/datum/verbs/New() - var/mainlist = GetList() - var/ourentry = mainlist[type] - children = list() - verblist = list() - if (ourentry) - if (!islist(ourentry)) //some of our childern already loaded - qdel(src) - CRASH("Verb double load: [type]") - Add_children(ourentry) - - mainlist[type] = src - - Load_verbs(type, typesof("[type]/verb")) - - var/datum/verbs/parent = mainlist[parent_type] - if (!parent) - mainlist[parent_type] = list(src) - else if (islist(parent)) - parent += src - else - parent.Add_children(list(src)) - -/datum/verbs/proc/Set_parent(datum/verbs/_parent) - parent = _parent - if (abstract) - parent.Add_children(children) - var/list/verblistoftypes = list() - for(var/thing in verblist) - LAZYADD(verblistoftypes[verblist[thing]], thing) - - for(var/verbparenttype in verblistoftypes) - parent.Load_verbs(verbparenttype, verblistoftypes[verbparenttype]) - -/datum/verbs/proc/Add_children(list/kids) - if (abstract && parent) - parent.Add_children(kids) - return - - for(var/thing in kids) - var/datum/verbs/item = thing - item.Set_parent(src) - if (!item.abstract) - children += item - -/datum/verbs/proc/Load_verbs(verb_parent_type, list/verbs) - if (abstract && parent) - parent.Load_verbs(verb_parent_type, verbs) - return - - for (var/verbpath in verbs) - verblist[verbpath] = verb_parent_type - -/datum/verbs/proc/Generate_list(...) - . = list() - if (length(children)) - for (var/thing in children) - var/datum/verbs/child = thing - var/list/childlist = child.Generate_list(arglist(args)) - if (childlist) - var/childname = "[child]" - if (childname == "[child.type]") - var/list/tree = splittext(childname, "/") - childname = tree[tree.len] - .[child.type] = "parent=[url_encode(type)];name=[childname]" - . += childlist - - for (var/thing in verblist) - var/procpath/verbpath = thing - if (!verbpath) - stack_trace("Bad VERB in [type] verblist: [english_list(verblist)]") - var/list/entry = list() - entry["parent"] = "[type]" - entry["name"] = verbpath.desc - if (copytext(verbpath.name,1,2) == "@") - entry["command"] = copytext(verbpath.name,2) - else - entry["command"] = replacetext(verbpath.name, " ", "-") - - .[verbpath] = HandleVerb(arglist(list(entry, verbpath) + args)) - -/world/proc/LoadVerbs(verb_type) - if(!ispath(verb_type, /datum/verbs) || verb_type == /datum/verbs) - CRASH("Invalid verb_type: [verb_type]") - for (var/typepath in subtypesof(verb_type)) - new typepath() +/datum/verbs + var/name + var/list/children + var/datum/verbs/parent + var/list/verblist + var/abstract = FALSE + +//returns the master list for verbs of a type +/datum/verbs/proc/GetList() + CRASH("Abstract verblist for [type]") + +//do things for each entry in Generate_list +//return value sets Generate_list[verbpath] +/datum/verbs/proc/HandleVerb(list/entry, procpath/verbpath, ...) + return entry + +/datum/verbs/New() + var/mainlist = GetList() + var/ourentry = mainlist[type] + children = list() + verblist = list() + if (ourentry) + if (!islist(ourentry)) //some of our childern already loaded + qdel(src) + CRASH("Verb double load: [type]") + Add_children(ourentry) + + mainlist[type] = src + + Load_verbs(type, typesof("[type]/verb")) + + var/datum/verbs/parent = mainlist[parent_type] + if (!parent) + mainlist[parent_type] = list(src) + else if (islist(parent)) + parent += src + else + parent.Add_children(list(src)) + +/datum/verbs/proc/Set_parent(datum/verbs/_parent) + parent = _parent + if (abstract) + parent.Add_children(children) + var/list/verblistoftypes = list() + for(var/thing in verblist) + LAZYADD(verblistoftypes[verblist[thing]], thing) + + for(var/verbparenttype in verblistoftypes) + parent.Load_verbs(verbparenttype, verblistoftypes[verbparenttype]) + +/datum/verbs/proc/Add_children(list/kids) + if (abstract && parent) + parent.Add_children(kids) + return + + for(var/thing in kids) + var/datum/verbs/item = thing + item.Set_parent(src) + if (!item.abstract) + children += item + +/datum/verbs/proc/Load_verbs(verb_parent_type, list/verbs) + if (abstract && parent) + parent.Load_verbs(verb_parent_type, verbs) + return + + for (var/verbpath in verbs) + verblist[verbpath] = verb_parent_type + +/datum/verbs/proc/Generate_list(...) + . = list() + if (length(children)) + for (var/thing in children) + var/datum/verbs/child = thing + var/list/childlist = child.Generate_list(arglist(args)) + if (childlist) + var/childname = "[child]" + if (childname == "[child.type]") + var/list/tree = splittext(childname, "/") + childname = tree[tree.len] + .[child.type] = "parent=[url_encode(type)];name=[childname]" + . += childlist + + for (var/thing in verblist) + var/procpath/verbpath = thing + if (!verbpath) + stack_trace("Bad VERB in [type] verblist: [english_list(verblist)]") + var/list/entry = list() + entry["parent"] = "[type]" + entry["name"] = verbpath.desc + if (copytext(verbpath.name,1,2) == "@") + entry["command"] = copytext(verbpath.name,2) + else + entry["command"] = replacetext(verbpath.name, " ", "-") + + .[verbpath] = HandleVerb(arglist(list(entry, verbpath) + args)) + +/world/proc/LoadVerbs(verb_type) + if(!ispath(verb_type, /datum/verbs) || verb_type == /datum/verbs) + CRASH("Invalid verb_type: [verb_type]") + for (var/typepath in subtypesof(verb_type)) + new typepath() diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm index ac4473845d..315cfa59d6 100644 --- a/code/datums/wires/airlock.dm +++ b/code/datums/wires/airlock.dm @@ -1,186 +1,186 @@ -/datum/wires/airlock - holder_type = /obj/machinery/door/airlock - proper_name = "Generic Airlock" - var/wiretype - -/datum/wires/airlock/secure - randomize = TRUE - -/datum/wires/airlock/command - proper_name = "Command Airlock" - wiretype = "commandairlock" - -/datum/wires/airlock/security - proper_name = "Security Airlock" - wiretype = "securityairlock" - -/datum/wires/airlock/engineering - proper_name = "Engineering Airlock" - wiretype = "engineeringairlock" - -/datum/wires/airlock/science - proper_name = "Science Airlock" - wiretype = "scienceairlock" - -/datum/wires/airlock/medical - proper_name = "Medical Airlock" - wiretype = "medicalairlock" - -/datum/wires/airlock/cargo - proper_name = "Cargo Airlock" - wiretype = "cargoairlock" - -/datum/wires/airlock/New(atom/holder) - wires = list( - WIRE_POWER1, WIRE_POWER2, - WIRE_BACKUP1, WIRE_BACKUP2, - WIRE_OPEN, WIRE_BOLTS, WIRE_IDSCAN, WIRE_AI, - WIRE_SHOCK, WIRE_SAFETY, WIRE_TIMING, WIRE_LIGHT, - WIRE_ZAP1, WIRE_ZAP2 - ) - add_duds(2) - . = ..() - if(randomize || !wiretype) - return - if(!GLOB.wire_color_directory[wiretype]) - colors = list() - randomize() - GLOB.wire_color_directory[wiretype] = colors - GLOB.wire_name_directory[wiretype] = proper_name - else - colors = GLOB.wire_color_directory[wiretype] - -/datum/wires/airlock/interactable(mob/user) - var/obj/machinery/door/airlock/A = holder - if(!issilicon(user) && A.isElectrified() && A.shock(user, 100)) - return FALSE - if(A.panel_open) - return TRUE - -/datum/wires/airlock/get_status() - var/obj/machinery/door/airlock/A = holder - var/list/status = list() - status += "The door bolts [A.locked ? "have fallen!" : "look up."]" - status += "The test light is [A.hasPower() ? "on" : "off"]." - status += "The AI connection light is [A.aiControlDisabled || (A.obj_flags & EMAGGED) ? "off" : "on"]." - status += "The check wiring light is [A.safe ? "off" : "on"]." - status += "The timer is powered [A.autoclose ? "on" : "off"]." - status += "The speed light is [A.normalspeed ? "on" : "off"]." - status += "The emergency light is [A.emergency ? "on" : "off"]." - return status - -/datum/wires/airlock/on_pulse(wire) - set waitfor = FALSE - var/obj/machinery/door/airlock/A = holder - switch(wire) - if(WIRE_POWER1, WIRE_POWER2) // Pulse to loose power. - A.loseMainPower() - if(WIRE_BACKUP1, WIRE_BACKUP2) // Pulse to loose backup power. - A.loseBackupPower() - if(WIRE_OPEN) // Pulse to open door (only works not emagged and ID wire is cut or no access is required). - if(A.obj_flags & EMAGGED) - return - if(!A.requiresID() || A.check_access(null)) - if(A.density) - INVOKE_ASYNC(A, /obj/machinery/door/airlock.proc/open) - else - INVOKE_ASYNC(A, /obj/machinery/door/airlock.proc/close) - else - holder.visible_message("You hear a a grinding noise coming from the airlock.") - if(WIRE_BOLTS) // Pulse to toggle bolts (but only raise if power is on). - if(!A.locked) - A.bolt() - else - if(A.hasPower()) - A.unbolt() - A.update_icon() - if(WIRE_IDSCAN) // Pulse to disable emergency access and flash red lights. - if(A.hasPower() && A.density) - A.do_animate("deny") - if(A.emergency) - A.emergency = FALSE - A.update_icon() - if(WIRE_AI) // Pulse to disable WIRE_AI control for 10 ticks (follows same rules as cutting). - if(A.aiControlDisabled == 0) - A.aiControlDisabled = 1 - else if(A.aiControlDisabled == -1) - A.aiControlDisabled = 2 - sleep(10) - if(A) - if(A.aiControlDisabled == 1) - A.aiControlDisabled = 0 - else if(A.aiControlDisabled == 2) - A.aiControlDisabled = -1 - if(WIRE_SHOCK) // Pulse to shock the door for 10 ticks. - if(!A.secondsElectrified) - A.set_electrified(30) - if(usr) - LAZYADD(A.shockedby, text("\[[TIME_STAMP("hh:mm:ss", FALSE)]\] [key_name(usr)]")) - log_combat(usr, A, "electrified") - if(WIRE_SAFETY) - A.safe = !A.safe - if(!A.density) - A.close() - if(WIRE_TIMING) - A.normalspeed = !A.normalspeed - if(WIRE_LIGHT) - A.lights = !A.lights - A.update_icon() - -/datum/wires/airlock/on_cut(wire, mend) - var/obj/machinery/door/airlock/A = holder - switch(wire) - if(WIRE_POWER1, WIRE_POWER2) // Cut to loose power, repair all to gain power. - if(mend && !is_cut(WIRE_POWER1) && !is_cut(WIRE_POWER2)) - A.regainMainPower() - if(usr) - A.shock(usr, 50) - else - A.loseMainPower() - if(usr) - A.shock(usr, 50) - if(WIRE_BACKUP1, WIRE_BACKUP2) // Cut to loose backup power, repair all to gain backup power. - if(mend && !is_cut(WIRE_BACKUP1) && !is_cut(WIRE_BACKUP2)) - A.regainBackupPower() - if(usr) - A.shock(usr, 50) - else - A.loseBackupPower() - if(usr) - A.shock(usr, 50) - if(WIRE_BOLTS) // Cut to drop bolts, mend does nothing. - if(!mend) - A.bolt() - if(WIRE_AI) // Cut to disable WIRE_AI control, mend to re-enable. - if(mend) - if(A.aiControlDisabled == 1) // 0 = normal, 1 = locked out, 2 = overridden by WIRE_AI, -1 = previously overridden by WIRE_AI - A.aiControlDisabled = 0 - else if(A.aiControlDisabled == 2) - A.aiControlDisabled = -1 - else - if(A.aiControlDisabled == 0) - A.aiControlDisabled = 1 - else if(A.aiControlDisabled == -1) - A.aiControlDisabled = 2 - if(WIRE_SHOCK) // Cut to shock the door, mend to unshock. - if(mend) - if(A.secondsElectrified) - A.set_electrified(0) - else - if(A.secondsElectrified != -1) - A.set_electrified(-1) - if(usr) - LAZYADD(A.shockedby, text("\[[TIME_STAMP("hh:mm:ss", FALSE)]\] [key_name(usr)]")) - log_combat(usr, A, "electrified") - if(WIRE_SAFETY) // Cut to disable safeties, mend to re-enable. - A.safe = mend - if(WIRE_TIMING) // Cut to disable auto-close, mend to re-enable. - A.autoclose = mend - if(A.autoclose && !A.density) - A.close() - if(WIRE_LIGHT) // Cut to disable lights, mend to re-enable. - A.lights = mend - A.update_icon() - if(WIRE_ZAP1, WIRE_ZAP2) // Ouch. - if(usr) - A.shock(usr, 50) +/datum/wires/airlock + holder_type = /obj/machinery/door/airlock + proper_name = "Generic Airlock" + var/wiretype + +/datum/wires/airlock/secure + randomize = TRUE + +/datum/wires/airlock/command + proper_name = "Command Airlock" + wiretype = "commandairlock" + +/datum/wires/airlock/security + proper_name = "Security Airlock" + wiretype = "securityairlock" + +/datum/wires/airlock/engineering + proper_name = "Engineering Airlock" + wiretype = "engineeringairlock" + +/datum/wires/airlock/science + proper_name = "Science Airlock" + wiretype = "scienceairlock" + +/datum/wires/airlock/medical + proper_name = "Medical Airlock" + wiretype = "medicalairlock" + +/datum/wires/airlock/cargo + proper_name = "Cargo Airlock" + wiretype = "cargoairlock" + +/datum/wires/airlock/New(atom/holder) + wires = list( + WIRE_POWER1, WIRE_POWER2, + WIRE_BACKUP1, WIRE_BACKUP2, + WIRE_OPEN, WIRE_BOLTS, WIRE_IDSCAN, WIRE_AI, + WIRE_SHOCK, WIRE_SAFETY, WIRE_TIMING, WIRE_LIGHT, + WIRE_ZAP1, WIRE_ZAP2 + ) + add_duds(2) + . = ..() + if(randomize || !wiretype) + return + if(!GLOB.wire_color_directory[wiretype]) + colors = list() + randomize() + GLOB.wire_color_directory[wiretype] = colors + GLOB.wire_name_directory[wiretype] = proper_name + else + colors = GLOB.wire_color_directory[wiretype] + +/datum/wires/airlock/interactable(mob/user) + var/obj/machinery/door/airlock/A = holder + if(!issilicon(user) && A.isElectrified() && A.shock(user, 100)) + return FALSE + if(A.panel_open) + return TRUE + +/datum/wires/airlock/get_status() + var/obj/machinery/door/airlock/A = holder + var/list/status = list() + status += "The door bolts [A.locked ? "have fallen!" : "look up."]" + status += "The test light is [A.hasPower() ? "on" : "off"]." + status += "The AI connection light is [A.aiControlDisabled || (A.obj_flags & EMAGGED) ? "off" : "on"]." + status += "The check wiring light is [A.safe ? "off" : "on"]." + status += "The timer is powered [A.autoclose ? "on" : "off"]." + status += "The speed light is [A.normalspeed ? "on" : "off"]." + status += "The emergency light is [A.emergency ? "on" : "off"]." + return status + +/datum/wires/airlock/on_pulse(wire) + set waitfor = FALSE + var/obj/machinery/door/airlock/A = holder + switch(wire) + if(WIRE_POWER1, WIRE_POWER2) // Pulse to loose power. + A.loseMainPower() + if(WIRE_BACKUP1, WIRE_BACKUP2) // Pulse to loose backup power. + A.loseBackupPower() + if(WIRE_OPEN) // Pulse to open door (only works not emagged and ID wire is cut or no access is required). + if(A.obj_flags & EMAGGED) + return + if(!A.requiresID() || A.check_access(null)) + if(A.density) + INVOKE_ASYNC(A, /obj/machinery/door/airlock.proc/open) + else + INVOKE_ASYNC(A, /obj/machinery/door/airlock.proc/close) + else + holder.visible_message("You hear a a grinding noise coming from the airlock.") + if(WIRE_BOLTS) // Pulse to toggle bolts (but only raise if power is on). + if(!A.locked) + A.bolt() + else + if(A.hasPower()) + A.unbolt() + A.update_icon() + if(WIRE_IDSCAN) // Pulse to disable emergency access and flash red lights. + if(A.hasPower() && A.density) + A.do_animate("deny") + if(A.emergency) + A.emergency = FALSE + A.update_icon() + if(WIRE_AI) // Pulse to disable WIRE_AI control for 10 ticks (follows same rules as cutting). + if(A.aiControlDisabled == 0) + A.aiControlDisabled = 1 + else if(A.aiControlDisabled == -1) + A.aiControlDisabled = 2 + sleep(10) + if(A) + if(A.aiControlDisabled == 1) + A.aiControlDisabled = 0 + else if(A.aiControlDisabled == 2) + A.aiControlDisabled = -1 + if(WIRE_SHOCK) // Pulse to shock the door for 10 ticks. + if(!A.secondsElectrified) + A.set_electrified(30) + if(usr) + LAZYADD(A.shockedby, text("\[[TIME_STAMP("hh:mm:ss", FALSE)]\] [key_name(usr)]")) + log_combat(usr, A, "electrified") + if(WIRE_SAFETY) + A.safe = !A.safe + if(!A.density) + A.close() + if(WIRE_TIMING) + A.normalspeed = !A.normalspeed + if(WIRE_LIGHT) + A.lights = !A.lights + A.update_icon() + +/datum/wires/airlock/on_cut(wire, mend) + var/obj/machinery/door/airlock/A = holder + switch(wire) + if(WIRE_POWER1, WIRE_POWER2) // Cut to loose power, repair all to gain power. + if(mend && !is_cut(WIRE_POWER1) && !is_cut(WIRE_POWER2)) + A.regainMainPower() + if(usr) + A.shock(usr, 50) + else + A.loseMainPower() + if(usr) + A.shock(usr, 50) + if(WIRE_BACKUP1, WIRE_BACKUP2) // Cut to loose backup power, repair all to gain backup power. + if(mend && !is_cut(WIRE_BACKUP1) && !is_cut(WIRE_BACKUP2)) + A.regainBackupPower() + if(usr) + A.shock(usr, 50) + else + A.loseBackupPower() + if(usr) + A.shock(usr, 50) + if(WIRE_BOLTS) // Cut to drop bolts, mend does nothing. + if(!mend) + A.bolt() + if(WIRE_AI) // Cut to disable WIRE_AI control, mend to re-enable. + if(mend) + if(A.aiControlDisabled == 1) // 0 = normal, 1 = locked out, 2 = overridden by WIRE_AI, -1 = previously overridden by WIRE_AI + A.aiControlDisabled = 0 + else if(A.aiControlDisabled == 2) + A.aiControlDisabled = -1 + else + if(A.aiControlDisabled == 0) + A.aiControlDisabled = 1 + else if(A.aiControlDisabled == -1) + A.aiControlDisabled = 2 + if(WIRE_SHOCK) // Cut to shock the door, mend to unshock. + if(mend) + if(A.secondsElectrified) + A.set_electrified(0) + else + if(A.secondsElectrified != -1) + A.set_electrified(-1) + if(usr) + LAZYADD(A.shockedby, text("\[[TIME_STAMP("hh:mm:ss", FALSE)]\] [key_name(usr)]")) + log_combat(usr, A, "electrified") + if(WIRE_SAFETY) // Cut to disable safeties, mend to re-enable. + A.safe = mend + if(WIRE_TIMING) // Cut to disable auto-close, mend to re-enable. + A.autoclose = mend + if(A.autoclose && !A.density) + A.close() + if(WIRE_LIGHT) // Cut to disable lights, mend to re-enable. + A.lights = mend + A.update_icon() + if(WIRE_ZAP1, WIRE_ZAP2) // Ouch. + if(usr) + A.shock(usr, 50) diff --git a/code/datums/wires/mulebot.dm b/code/datums/wires/mulebot.dm index 9aa2ca81e8..a452b46830 100644 --- a/code/datums/wires/mulebot.dm +++ b/code/datums/wires/mulebot.dm @@ -1,31 +1,31 @@ -/datum/wires/mulebot - holder_type = /mob/living/simple_animal/bot/mulebot - randomize = TRUE - -/datum/wires/mulebot/New(atom/holder) - wires = list( - WIRE_POWER1, WIRE_POWER2, - WIRE_AVOIDANCE, WIRE_LOADCHECK, - WIRE_MOTOR1, WIRE_MOTOR2, - WIRE_RX, WIRE_TX, WIRE_BEACON - ) - ..() - -/datum/wires/mulebot/interactable(mob/user) - var/mob/living/simple_animal/bot/mulebot/M = holder - if(M.open) - return TRUE - -/datum/wires/mulebot/on_pulse(wire) - var/mob/living/simple_animal/bot/mulebot/M = holder - switch(wire) - if(WIRE_POWER1, WIRE_POWER2) - holder.visible_message("[icon2html(M, viewers(holder))] The charge light flickers.") - if(WIRE_AVOIDANCE) - holder.visible_message("[icon2html(M, viewers(holder))] The external warning lights flash briefly.") - if(WIRE_LOADCHECK) - holder.visible_message("[icon2html(M, viewers(holder))] The load platform clunks.") - if(WIRE_MOTOR1, WIRE_MOTOR2) - holder.visible_message("[icon2html(M, viewers(holder))] The drive motor whines briefly.") - else +/datum/wires/mulebot + holder_type = /mob/living/simple_animal/bot/mulebot + randomize = TRUE + +/datum/wires/mulebot/New(atom/holder) + wires = list( + WIRE_POWER1, WIRE_POWER2, + WIRE_AVOIDANCE, WIRE_LOADCHECK, + WIRE_MOTOR1, WIRE_MOTOR2, + WIRE_RX, WIRE_TX, WIRE_BEACON + ) + ..() + +/datum/wires/mulebot/interactable(mob/user) + var/mob/living/simple_animal/bot/mulebot/M = holder + if(M.open) + return TRUE + +/datum/wires/mulebot/on_pulse(wire) + var/mob/living/simple_animal/bot/mulebot/M = holder + switch(wire) + if(WIRE_POWER1, WIRE_POWER2) + holder.visible_message("[icon2html(M, viewers(holder))] The charge light flickers.") + if(WIRE_AVOIDANCE) + holder.visible_message("[icon2html(M, viewers(holder))] The external warning lights flash briefly.") + if(WIRE_LOADCHECK) + holder.visible_message("[icon2html(M, viewers(holder))] The load platform clunks.") + if(WIRE_MOTOR1, WIRE_MOTOR2) + holder.visible_message("[icon2html(M, viewers(holder))] The drive motor whines briefly.") + else holder.visible_message("[icon2html(M, viewers(holder))] You hear a radio crackle.") \ No newline at end of file diff --git a/code/datums/wires/particle_accelerator.dm b/code/datums/wires/particle_accelerator.dm index 4bf49dd814..af89f0d6f1 100644 --- a/code/datums/wires/particle_accelerator.dm +++ b/code/datums/wires/particle_accelerator.dm @@ -1,48 +1,48 @@ -/datum/wires/particle_accelerator/control_box - holder_type = /obj/machinery/particle_accelerator/control_box - proper_name = "Particle Accelerator" - -/datum/wires/particle_accelerator/control_box/New(atom/holder) - wires = list( - WIRE_POWER, WIRE_STRENGTH, WIRE_LIMIT, - WIRE_INTERFACE - ) - add_duds(2) - ..() - -/datum/wires/particle_accelerator/control_box/interactable(mob/user) - var/obj/machinery/particle_accelerator/control_box/C = holder - if(C.construction_state == 2) - return TRUE - -/datum/wires/particle_accelerator/control_box/on_pulse(wire) - var/obj/machinery/particle_accelerator/control_box/C = holder - switch(wire) - if(WIRE_POWER) - C.toggle_power() - if(WIRE_STRENGTH) - C.add_strength() - if(WIRE_INTERFACE) - C.interface_control = !C.interface_control - if(WIRE_LIMIT) - C.visible_message("[icon2html(C, viewers(holder))][C] makes a large whirring noise.") - -/datum/wires/particle_accelerator/control_box/on_cut(wire, mend) - var/obj/machinery/particle_accelerator/control_box/C = holder - switch(wire) - if(WIRE_POWER) - if(C.active == !mend) - C.toggle_power() - if(WIRE_STRENGTH) - for(var/i = 1; i < 3; i++) - C.remove_strength() - if(WIRE_INTERFACE) - if(!mend) - C.interface_control = FALSE - if(WIRE_LIMIT) - C.strength_upper_limit = (mend ? 2 : 3) - if(C.strength_upper_limit < C.strength) - C.remove_strength() - -/datum/wires/particle_accelerator/control_box/emp_pulse() // to prevent singulo from pulsing wires +/datum/wires/particle_accelerator/control_box + holder_type = /obj/machinery/particle_accelerator/control_box + proper_name = "Particle Accelerator" + +/datum/wires/particle_accelerator/control_box/New(atom/holder) + wires = list( + WIRE_POWER, WIRE_STRENGTH, WIRE_LIMIT, + WIRE_INTERFACE + ) + add_duds(2) + ..() + +/datum/wires/particle_accelerator/control_box/interactable(mob/user) + var/obj/machinery/particle_accelerator/control_box/C = holder + if(C.construction_state == 2) + return TRUE + +/datum/wires/particle_accelerator/control_box/on_pulse(wire) + var/obj/machinery/particle_accelerator/control_box/C = holder + switch(wire) + if(WIRE_POWER) + C.toggle_power() + if(WIRE_STRENGTH) + C.add_strength() + if(WIRE_INTERFACE) + C.interface_control = !C.interface_control + if(WIRE_LIMIT) + C.visible_message("[icon2html(C, viewers(holder))][C] makes a large whirring noise.") + +/datum/wires/particle_accelerator/control_box/on_cut(wire, mend) + var/obj/machinery/particle_accelerator/control_box/C = holder + switch(wire) + if(WIRE_POWER) + if(C.active == !mend) + C.toggle_power() + if(WIRE_STRENGTH) + for(var/i = 1; i < 3; i++) + C.remove_strength() + if(WIRE_INTERFACE) + if(!mend) + C.interface_control = FALSE + if(WIRE_LIMIT) + C.strength_upper_limit = (mend ? 2 : 3) + if(C.strength_upper_limit < C.strength) + C.remove_strength() + +/datum/wires/particle_accelerator/control_box/emp_pulse() // to prevent singulo from pulsing wires return \ No newline at end of file diff --git a/code/datums/wires/robot.dm b/code/datums/wires/robot.dm index 65438830a2..5e0d0d77d0 100644 --- a/code/datums/wires/robot.dm +++ b/code/datums/wires/robot.dm @@ -1,86 +1,86 @@ -/datum/wires/robot - holder_type = /mob/living/silicon/robot - randomize = TRUE - -/datum/wires/robot/New(atom/holder) - wires = list( - WIRE_AI, WIRE_CAMERA, - WIRE_LAWSYNC, WIRE_LOCKDOWN, - WIRE_RESET_MODULE - ) - add_duds(2) - ..() - -/datum/wires/robot/interactable(mob/user) - var/mob/living/silicon/robot/R = holder - if(R.wiresexposed) - return TRUE - -/datum/wires/robot/get_status() - var/mob/living/silicon/robot/R = holder - var/list/status = list() - status += "The law sync module is [R.lawupdate ? "on" : "off"]." - status += "The intelligence link display shows [R.connected_ai ? R.connected_ai.name : "NULL"]." - status += "The camera light is [!isnull(R.builtInCamera) && R.builtInCamera.status ? "on" : "off"]." - status += "The lockdown indicator is [R.lockcharge ? "on" : "off"]." - status += "The reset module hardware light is [R.has_module() ? "on" : "off"]." - return status - -/datum/wires/robot/on_pulse(wire, user) - var/mob/living/silicon/robot/R = holder - switch(wire) - if(WIRE_AI) // Pulse to pick a new AI. - if(!R.emagged) - var/new_ai - if(user) - new_ai = select_active_ai(user) - else - new_ai = select_active_ai(R) - R.notify_ai(DISCONNECT) - if(new_ai && (new_ai != R.connected_ai)) - R.connected_ai = new_ai - if(R.shell) - R.undeploy() //If this borg is an AI shell, disconnect the controlling AI and assign ti to a new AI - R.notify_ai(AI_SHELL) - else - R.notify_ai(TRUE) - if(WIRE_CAMERA) // Pulse to disable the camera. - if(!QDELETED(R.builtInCamera) && !R.scrambledcodes) - R.builtInCamera.toggle_cam(usr, 0) - R.visible_message("[R]'s camera lens focuses loudly.", "Your camera lens focuses loudly.") - if(WIRE_LAWSYNC) // Forces a law update if possible. - if(R.lawupdate) - R.visible_message("[R] gently chimes.", "LawSync protocol engaged.") - R.lawsync() - R.show_laws() - if(WIRE_LOCKDOWN) - R.SetLockdown(!R.lockcharge) // Toggle - if(WIRE_RESET_MODULE) - if(R.has_module()) - R.visible_message("[R]'s module servos twitch.", "Your module display flickers.") - -/datum/wires/robot/on_cut(wire, mend) - var/mob/living/silicon/robot/R = holder - switch(wire) - if(WIRE_AI) // Cut the AI wire to reset AI control. - if(!mend) - R.notify_ai(DISCONNECT) - if(R.shell) - R.undeploy() - R.connected_ai = null - if(WIRE_LAWSYNC) // Cut the law wire, and the borg will no longer receive law updates from its AI. Repair and it will re-sync. - if(mend) - if(!R.emagged) - R.lawupdate = TRUE - else if(!R.deployed) //AI shells must always have the same laws as the AI - R.lawupdate = FALSE - if (WIRE_CAMERA) // Disable the camera. - if(!QDELETED(R.builtInCamera) && !R.scrambledcodes) - R.builtInCamera.status = mend - R.builtInCamera.toggle_cam(usr, 0) - R.visible_message("[R]'s camera lens focuses loudly.", "Your camera lens focuses loudly.") - if(WIRE_LOCKDOWN) // Simple lockdown. - R.SetLockdown(!mend) - if(WIRE_RESET_MODULE) - if(R.has_module() && !mend) - R.ResetModule() +/datum/wires/robot + holder_type = /mob/living/silicon/robot + randomize = TRUE + +/datum/wires/robot/New(atom/holder) + wires = list( + WIRE_AI, WIRE_CAMERA, + WIRE_LAWSYNC, WIRE_LOCKDOWN, + WIRE_RESET_MODULE + ) + add_duds(2) + ..() + +/datum/wires/robot/interactable(mob/user) + var/mob/living/silicon/robot/R = holder + if(R.wiresexposed) + return TRUE + +/datum/wires/robot/get_status() + var/mob/living/silicon/robot/R = holder + var/list/status = list() + status += "The law sync module is [R.lawupdate ? "on" : "off"]." + status += "The intelligence link display shows [R.connected_ai ? R.connected_ai.name : "NULL"]." + status += "The camera light is [!isnull(R.builtInCamera) && R.builtInCamera.status ? "on" : "off"]." + status += "The lockdown indicator is [R.lockcharge ? "on" : "off"]." + status += "The reset module hardware light is [R.has_module() ? "on" : "off"]." + return status + +/datum/wires/robot/on_pulse(wire, user) + var/mob/living/silicon/robot/R = holder + switch(wire) + if(WIRE_AI) // Pulse to pick a new AI. + if(!R.emagged) + var/new_ai + if(user) + new_ai = select_active_ai(user) + else + new_ai = select_active_ai(R) + R.notify_ai(DISCONNECT) + if(new_ai && (new_ai != R.connected_ai)) + R.connected_ai = new_ai + if(R.shell) + R.undeploy() //If this borg is an AI shell, disconnect the controlling AI and assign ti to a new AI + R.notify_ai(AI_SHELL) + else + R.notify_ai(TRUE) + if(WIRE_CAMERA) // Pulse to disable the camera. + if(!QDELETED(R.builtInCamera) && !R.scrambledcodes) + R.builtInCamera.toggle_cam(usr, 0) + R.visible_message("[R]'s camera lens focuses loudly.", "Your camera lens focuses loudly.") + if(WIRE_LAWSYNC) // Forces a law update if possible. + if(R.lawupdate) + R.visible_message("[R] gently chimes.", "LawSync protocol engaged.") + R.lawsync() + R.show_laws() + if(WIRE_LOCKDOWN) + R.SetLockdown(!R.lockcharge) // Toggle + if(WIRE_RESET_MODULE) + if(R.has_module()) + R.visible_message("[R]'s module servos twitch.", "Your module display flickers.") + +/datum/wires/robot/on_cut(wire, mend) + var/mob/living/silicon/robot/R = holder + switch(wire) + if(WIRE_AI) // Cut the AI wire to reset AI control. + if(!mend) + R.notify_ai(DISCONNECT) + if(R.shell) + R.undeploy() + R.connected_ai = null + if(WIRE_LAWSYNC) // Cut the law wire, and the borg will no longer receive law updates from its AI. Repair and it will re-sync. + if(mend) + if(!R.emagged) + R.lawupdate = TRUE + else if(!R.deployed) //AI shells must always have the same laws as the AI + R.lawupdate = FALSE + if (WIRE_CAMERA) // Disable the camera. + if(!QDELETED(R.builtInCamera) && !R.scrambledcodes) + R.builtInCamera.status = mend + R.builtInCamera.toggle_cam(usr, 0) + R.visible_message("[R]'s camera lens focuses loudly.", "Your camera lens focuses loudly.") + if(WIRE_LOCKDOWN) // Simple lockdown. + R.SetLockdown(!mend) + if(WIRE_RESET_MODULE) + if(R.has_module() && !mend) + R.ResetModule() diff --git a/code/datums/wires/syndicatebomb.dm b/code/datums/wires/syndicatebomb.dm index 92cc1770b3..53c1a1b9bc 100644 --- a/code/datums/wires/syndicatebomb.dm +++ b/code/datums/wires/syndicatebomb.dm @@ -1,92 +1,92 @@ -/datum/wires/syndicatebomb - holder_type = /obj/machinery/syndicatebomb - randomize = TRUE - -/datum/wires/syndicatebomb/New(atom/holder) - wires = list( - WIRE_BOOM, WIRE_UNBOLT, - WIRE_ACTIVATE, WIRE_DELAY, WIRE_PROCEED - ) - ..() - -/datum/wires/syndicatebomb/interactable(mob/user) - var/obj/machinery/syndicatebomb/P = holder - if(P.open_panel) - return TRUE - -/datum/wires/syndicatebomb/on_pulse(wire) - var/obj/machinery/syndicatebomb/B = holder - switch(wire) - if(WIRE_BOOM) - if(B.active) - holder.visible_message("[icon2html(B, viewers(holder))] An alarm sounds! It's go-") - B.explode_now = TRUE - tell_admins(B) - if(WIRE_UNBOLT) - holder.visible_message("[icon2html(B, viewers(holder))] The bolts spin in place for a moment.") - if(WIRE_DELAY) - if(B.delayedbig) - holder.visible_message("[icon2html(B, viewers(holder))] The bomb has already been delayed.") - else - holder.visible_message("[icon2html(B, viewers(holder))] The bomb chirps.") - playsound(B, 'sound/machines/chime.ogg', 30, 1) - B.detonation_timer += 300 - B.delayedbig = TRUE - if(WIRE_PROCEED) - holder.visible_message("[icon2html(B, viewers(holder))] The bomb buzzes ominously!") - playsound(B, 'sound/machines/buzz-sigh.ogg', 30, 1) - var/seconds = B.seconds_remaining() - if(seconds >= 61) // Long fuse bombs can suddenly become more dangerous if you tinker with them. - B.detonation_timer = world.time + 600 - else if(seconds >= 21) - B.detonation_timer -= 100 - else if(seconds >= 11) // Both to prevent negative timers and to have a little mercy. - B.detonation_timer = world.time + 100 - if(WIRE_ACTIVATE) - if(!B.active && !B.defused) - holder.visible_message("[icon2html(B, viewers(holder))] You hear the bomb start ticking!") - B.activate() - B.update_icon() - else if(B.delayedlittle) - holder.visible_message("[icon2html(B, viewers(holder))] Nothing happens.") - else - holder.visible_message("[icon2html(B, viewers(holder))] The bomb seems to hesitate for a moment.") - B.detonation_timer += 100 - B.delayedlittle = TRUE - -/datum/wires/syndicatebomb/on_cut(wire, mend) - var/obj/machinery/syndicatebomb/B = holder - switch(wire) - if(WIRE_BOOM) - if(mend) - B.defused = FALSE // Cutting and mending all the wires of an inactive bomb will thus cure any sabotage. - else - if(B.active) - holder.visible_message("[icon2html(B, viewers(holder))] An alarm sounds! It's go-") - B.explode_now = TRUE - tell_admins(B) - else - B.defused = TRUE - if(WIRE_UNBOLT) - if(!mend && B.anchored) - holder.visible_message("[icon2html(B, viewers(holder))] The bolts lift out of the ground!") - playsound(B, 'sound/effects/stealthoff.ogg', 30, 1) - B.anchored = FALSE - if(WIRE_PROCEED) - if(!mend && B.active) - holder.visible_message("[icon2html(B, viewers(holder))] An alarm sounds! It's go-") - B.explode_now = TRUE - tell_admins(B) - if(WIRE_ACTIVATE) - if(!mend && B.active) - holder.visible_message("[icon2html(B, viewers(holder))] The timer stops! The bomb has been defused!") - B.active = FALSE - B.defused = TRUE - B.update_icon() - -/datum/wires/syndicatebomb/proc/tell_admins(obj/machinery/syndicatebomb/B) - if(istype(B, /obj/machinery/syndicatebomb/training)) - return - var/turf/T = get_turf(B) - log_game("\A [B] was detonated via boom wire at [AREACOORD(T)].") - message_admins("A [B.name] was detonated via boom wire at [ADMIN_VERBOSEJMP(T)].") +/datum/wires/syndicatebomb + holder_type = /obj/machinery/syndicatebomb + randomize = TRUE + +/datum/wires/syndicatebomb/New(atom/holder) + wires = list( + WIRE_BOOM, WIRE_UNBOLT, + WIRE_ACTIVATE, WIRE_DELAY, WIRE_PROCEED + ) + ..() + +/datum/wires/syndicatebomb/interactable(mob/user) + var/obj/machinery/syndicatebomb/P = holder + if(P.open_panel) + return TRUE + +/datum/wires/syndicatebomb/on_pulse(wire) + var/obj/machinery/syndicatebomb/B = holder + switch(wire) + if(WIRE_BOOM) + if(B.active) + holder.visible_message("[icon2html(B, viewers(holder))] An alarm sounds! It's go-") + B.explode_now = TRUE + tell_admins(B) + if(WIRE_UNBOLT) + holder.visible_message("[icon2html(B, viewers(holder))] The bolts spin in place for a moment.") + if(WIRE_DELAY) + if(B.delayedbig) + holder.visible_message("[icon2html(B, viewers(holder))] The bomb has already been delayed.") + else + holder.visible_message("[icon2html(B, viewers(holder))] The bomb chirps.") + playsound(B, 'sound/machines/chime.ogg', 30, 1) + B.detonation_timer += 300 + B.delayedbig = TRUE + if(WIRE_PROCEED) + holder.visible_message("[icon2html(B, viewers(holder))] The bomb buzzes ominously!") + playsound(B, 'sound/machines/buzz-sigh.ogg', 30, 1) + var/seconds = B.seconds_remaining() + if(seconds >= 61) // Long fuse bombs can suddenly become more dangerous if you tinker with them. + B.detonation_timer = world.time + 600 + else if(seconds >= 21) + B.detonation_timer -= 100 + else if(seconds >= 11) // Both to prevent negative timers and to have a little mercy. + B.detonation_timer = world.time + 100 + if(WIRE_ACTIVATE) + if(!B.active && !B.defused) + holder.visible_message("[icon2html(B, viewers(holder))] You hear the bomb start ticking!") + B.activate() + B.update_icon() + else if(B.delayedlittle) + holder.visible_message("[icon2html(B, viewers(holder))] Nothing happens.") + else + holder.visible_message("[icon2html(B, viewers(holder))] The bomb seems to hesitate for a moment.") + B.detonation_timer += 100 + B.delayedlittle = TRUE + +/datum/wires/syndicatebomb/on_cut(wire, mend) + var/obj/machinery/syndicatebomb/B = holder + switch(wire) + if(WIRE_BOOM) + if(mend) + B.defused = FALSE // Cutting and mending all the wires of an inactive bomb will thus cure any sabotage. + else + if(B.active) + holder.visible_message("[icon2html(B, viewers(holder))] An alarm sounds! It's go-") + B.explode_now = TRUE + tell_admins(B) + else + B.defused = TRUE + if(WIRE_UNBOLT) + if(!mend && B.anchored) + holder.visible_message("[icon2html(B, viewers(holder))] The bolts lift out of the ground!") + playsound(B, 'sound/effects/stealthoff.ogg', 30, 1) + B.anchored = FALSE + if(WIRE_PROCEED) + if(!mend && B.active) + holder.visible_message("[icon2html(B, viewers(holder))] An alarm sounds! It's go-") + B.explode_now = TRUE + tell_admins(B) + if(WIRE_ACTIVATE) + if(!mend && B.active) + holder.visible_message("[icon2html(B, viewers(holder))] The timer stops! The bomb has been defused!") + B.active = FALSE + B.defused = TRUE + B.update_icon() + +/datum/wires/syndicatebomb/proc/tell_admins(obj/machinery/syndicatebomb/B) + if(istype(B, /obj/machinery/syndicatebomb/training)) + return + var/turf/T = get_turf(B) + log_game("\A [B] was detonated via boom wire at [AREACOORD(T)].") + message_admins("A [B.name] was detonated via boom wire at [ADMIN_VERBOSEJMP(T)].") diff --git a/code/game/area/Space_Station_13_areas.dm b/code/game/area/Space_Station_13_areas.dm index fa66306302..f26cfc4cdc 100644 --- a/code/game/area/Space_Station_13_areas.dm +++ b/code/game/area/Space_Station_13_areas.dm @@ -1,1352 +1,1352 @@ -/* - -### This file contains a list of all the areas in your station. Format is as follows: - -/area/CATEGORY/OR/DESCRIPTOR/NAME (you can make as many subdivisions as you want) - name = "NICE NAME" (not required but makes things really nice) - icon = 'ICON FILENAME' (defaults to 'icons/turf/areas.dmi') - icon_state = "NAME OF ICON" (defaults to "unknown" (blank)) - requires_power = FALSE (defaults to true) - music = null (defaults to nothing, look in sound/ambience for music) - -NOTE: there are two lists of areas in the end of this file: centcom and station itself. Please maintain these lists valid. --rastaf0 - -*/ - - -/*-----------------------------------------------------------------------------*/ - -/area/ai_monitored //stub defined ai_monitored.dm - -/area/ai_monitored/turret_protected - -/area/arrival - requires_power = FALSE - -/area/arrival/start - name = "Arrival Area" - icon_state = "start" - -/area/admin - name = "Admin room" - icon_state = "start" - -/area/space - icon_state = "space" - requires_power = TRUE - always_unpowered = TRUE - dynamic_lighting = DYNAMIC_LIGHTING_DISABLED - power_light = FALSE - power_equip = FALSE - power_environ = FALSE - valid_territory = FALSE - outdoors = TRUE - ambientsounds = SPACE - blob_allowed = FALSE //Eating up space doesn't count for victory as a blob. - -/area/space/nearstation - icon_state = "space_near" - dynamic_lighting = DYNAMIC_LIGHTING_IFSTARLIGHT - -/area/start - name = "start area" - icon_state = "start" - requires_power = FALSE - dynamic_lighting = DYNAMIC_LIGHTING_DISABLED - has_gravity = STANDARD_GRAVITY - - -//EXTRA - -/area/asteroid - name = "Asteroid" - icon_state = "asteroid" - requires_power = FALSE - has_gravity = STANDARD_GRAVITY - blob_allowed = FALSE //Nope, no winning on the asteroid as a blob. Gotta eat the station. - valid_territory = FALSE - ambientsounds = MINING - -/area/asteroid/nearstation - dynamic_lighting = DYNAMIC_LIGHTING_FORCED - ambientsounds = RUINS - always_unpowered = FALSE - requires_power = TRUE - blob_allowed = TRUE - -/area/asteroid/nearstation/bomb_site - name = "Bomb Testing Asteroid" - -/area/asteroid/cave - name = "Asteroid - Underground" - icon_state = "cave" - requires_power = FALSE - outdoors = TRUE - -/area/asteroid/cave/space - name = "Asteroid - Space" - -/area/asteroid/artifactroom - name = "Asteroid - Artifact" - icon_state = "cave" - ambientsounds = RUINS - -/area/asteroid/artifactroom/Initialize() - . = ..() - set_dynamic_lighting() - - -//STATION13 - -//Maintenance - -/area/maintenance - ambientsounds = MAINTENANCE - valid_territory = FALSE - - -//Departments - -/area/maintenance/department/chapel - name = "Chapel Maintenance" - icon_state = "maint_chapel" - -/area/maintenance/department/chapel/monastery - name = "Monastery Maintenance" - icon_state = "maint_monastery" - -/area/maintenance/department/crew_quarters/bar - name = "Bar Maintenance" - icon_state = "maint_bar" - -/area/maintenance/department/crew_quarters/dorms - name = "Dormitory Maintenance" - icon_state = "maint_dorms" - -/area/maintenance/department/crew_quarters/locker - name = "Locker Room Maintenance" - icon_state = "maint_locker" - -/area/maintenance/department/eva - name = "EVA Maintenance" - icon_state = "maint_eva" - -/area/maintenance/department/electrical - name = "Electrical Maintenance" - icon_state = "maint_electrical" - -/area/maintenance/department/engine/atmos - name = "Atmospherics Maintenance" - icon_state = "maint_atmos" - -/area/maintenance/department/security - name = "Security Maintenance" - icon_state = "maint_sec" - -/area/maintenance/department/security/brig - name = "Brig Maintenance" - icon_state = "maint_brig" - -/area/maintenance/department/medical - name = "Medbay Maintenance" - icon_state = "medbay_maint" - -/area/maintenance/department/medical/morgue - name = "Morgue Maintenance" - icon_state = "morgue_maint" - -/area/maintenance/department/science - name = "Science Maintenance" - icon_state = "maint_sci" - -/area/maintenance/department/cargo - name = "Cargo Maintenance" - icon_state = "maint_cargo" - -/area/maintenance/department/bridge - name = "Bridge Maintenance" - icon_state = "maint_bridge" - -/area/maintenance/department/engine - name = "Engineering Maintenance" - icon_state = "maint_engi" - -/area/maintenance/department/science/xenobiology - name = "Xenobiology Maintenance" - icon_state = "xenomaint" - xenobiology_compatible = TRUE - - -//Maintenance - Generic - -/area/maintenance/arrivals/north - name = "Arrivals North Maintenance" - icon_state = "fpmaint" - -/area/maintenance/arrivals/north_2 - name = "Arrivals North Maintenance" - icon_state = "fpmaint" - -/area/maintenance/aft - name = "Aft Maintenance" - icon_state = "amaint" - -/area/maintenance/aft/secondary - name = "Aft Maintenance" - icon_state = "amaint_2" - -/area/maintenance/central - name = "Central Maintenance" - icon_state = "maintcentral" - -/area/maintenance/central/secondary - name = "Central Maintenance" - icon_state = "maintcentral" - -/area/maintenance/fore - name = "Fore Maintenance" - icon_state = "fmaint" - -/area/maintenance/fore/secondary - name = "Fore Maintenance" - icon_state = "fmaint_2" - -/area/maintenance/starboard - name = "Starboard Maintenance" - icon_state = "smaint" - -/area/maintenance/starboard/central - name = "Central Starboard Maintenance" - icon_state = "smaint" - -/area/maintenance/starboard/aft - name = "Starboard Quarter Maintenance" - icon_state = "asmaint" - -/area/maintenance/starboard/fore - name = "Starboard Bow Maintenance" - icon_state = "fsmaint" - -/area/maintenance/port - name = "Port Maintenance" - icon_state = "pmaint" - -/area/maintenance/port/central - name = "Central Port Maintenance" - icon_state = "maintcentral" - -/area/maintenance/port/aft - name = "Port Quarter Maintenance" - icon_state = "apmaint" - -/area/maintenance/port/fore - name = "Port Bow Maintenance" - icon_state = "fpmaint" - -/area/maintenance/disposal - name = "Waste Disposal" - icon_state = "disposal" - -/area/maintenance/disposal/incinerator - name = "Incinerator" - icon_state = "disposal" -/area/maintenance/bar - name = "Maintenance Bar" - icon_state = "maintbar" - -/area/maintenance/bar/cafe - name = "Abandoned Cafe" - -//Hallway - -/area/hallway/primary/aft - name = "Aft Primary Hallway" - icon_state = "hallA" - -/area/hallway/primary/fore - name = "Fore Primary Hallway" - icon_state = "hallF" - -/area/hallway/primary/starboard - name = "Starboard Primary Hallway" - icon_state = "hallS" - -/area/hallway/primary/starboard/aft - name = "Starboard Quarter Primary Hallway" - icon_state = "hallAS" - -/area/hallway/primary/starboard/fore - name = "Starboard Bow Primary Hallway" - icon_state = "hallFS" - -/area/hallway/primary/port - name = "Port Primary Hallway" - icon_state = "hallP" - -/area/hallway/primary/port/aft - name = "Port Quarter Primary Hallway" - icon_state = "hallAP" - -/area/hallway/primary/port/fore - name = "Port Bow Primary Hallway" - icon_state = "hallFP" - -/area/hallway/primary/central - name = "Central Primary Hallway" - icon_state = "hallC" - -/area/hallway/secondary/command - name = "Command Hallway" - icon_state = "bridge_hallway" - -/area/hallway/secondary/construction - name = "Construction Area" - icon_state = "construction" - -/area/hallway/secondary/exit - name = "Escape Shuttle Hallway" - icon_state = "escape" - -/area/hallway/secondary/exit/departure_lounge - name = "Departure Lounge" - icon_state = "escape_lounge" - -/area/hallway/secondary/entry - name = "Arrival Shuttle Hallway" - icon_state = "entry" - -/area/hallway/secondary/service - name = "Service Hallway" - icon_state = "hall_service" - -//Command - -/area/bridge - name = "Bridge" - icon_state = "bridge" - music = "signal" - -/area/bridge/meeting_room - name = "Heads of Staff Meeting Room" - icon_state = "meeting" - music = null - -/area/bridge/meeting_room/council - name = "Council Chamber" - icon_state = "meeting" - music = null - -/area/bridge/showroom/corporate - name = "Corporate Showroom" - icon_state = "showroom" - music = null - -/area/crew_quarters/heads/captain - name = "Captain's Office" - icon_state = "captain" - clockwork_warp_allowed = FALSE - -/area/crew_quarters/heads/captain/private - name = "Captain's Quarters" - icon_state = "captain" - -/area/crew_quarters/heads/chief - name = "Chief Engineer's Office" - icon_state = "ce_office" - -/area/crew_quarters/heads/chief/private - name = "Chief Engineer's Private Quarters" - icon_state = "ce_private" - -/area/crew_quarters/heads/cmo - name = "Chief Medical Officer's Office" - icon_state = "cmo_office" - -/area/crew_quarters/heads/cmo/private - name = "Chief Medical Officer's Private Quarters" - icon_state = "cmo_private" - -/area/crew_quarters/heads/hop - name = "Head of Personnel's Office" - icon_state = "hop_office" - -/area/crew_quarters/heads/hop/private - name = "Head of Personnel's Private Quarters" - icon_state = "hop_private" - -/area/crew_quarters/heads/hos - name = "Head of Security's Office" - icon_state = "hos_office" - -/area/crew_quarters/heads/hos/private - name = "Head of Security's Private Quarters" - icon_state = "hos_private" - -/area/crew_quarters/heads/hor - name = "Research Director's Office" - icon_state = "rd_office" - -/area/crew_quarters/heads/hor/private - name = "Research Director's Private Quarters" - icon_state = "rd_private" - -/area/comms - name = "Communications Relay" - icon_state = "tcomsatcham" - -/area/server - name = "Messaging Server Room" - icon_state = "server" - -//Crew - -/area/crew_quarters/dorms - name = "Dormitories" - icon_state = "Sleep" - safe = TRUE - -/area/crew_quarters/dorms/male - name = "Male Dorm" - icon_state = "Sleep" - -/area/crew_quarters/dorms/female - name = "Female Dorm" - icon_state = "Sleep" - -/area/crew_quarters/rehab_dome - name = "Rehabilitation Dome" - icon_state = "Sleep" - -/area/crew_quarters/toilet - name = "Dormitory Toilets" - icon_state = "toilet" - -/area/crew_quarters/toilet/auxiliary - name = "Auxiliary Restrooms" - icon_state = "toilet" - -/area/crew_quarters/toilet/locker - name = "Locker Toilets" - icon_state = "toilet" - -/area/crew_quarters/toilet/fitness - name = "Fitness Toilets" - icon_state = "toilet" - -/area/crew_quarters/toilet/female - name = "Female Toilets" - icon_state = "toilet" - -/area/crew_quarters/toilet/male - name = "Male Toilets" - icon_state = "toilet" - -/area/crew_quarters/toilet/restrooms - name = "Restrooms" - icon_state = "toilet" - -/area/crew_quarters/locker - name = "Locker Room" - icon_state = "locker" - -/area/crew_quarters/lounge - name = "Lounge" - icon_state = "yellow" - -/area/crew_quarters/fitness - name = "Fitness Room" - icon_state = "fitness" - -/area/crew_quarters/fitness/recreation - name = "Recreation Area" - icon_state = "fitness" - -/area/crew_quarters/cafeteria - name = "Cafeteria" - icon_state = "cafeteria" - -/area/crew_quarters/cafeteria/lunchroom - name = "Lunchroom" - icon_state = "cafeteria" - -/area/crew_quarters/kitchen - name = "Kitchen" - icon_state = "kitchen" - -/area/crew_quarters/kitchen/backroom - name = "Kitchen Coldroom" - icon_state = "kitchen" - -/area/crew_quarters/bar - name = "Bar" - icon_state = "bar" - -/area/crew_quarters/bar/atrium - name = "Atrium" - icon_state = "bar" - -/area/crew_quarters/electronic_marketing_den - name = "Electronic Marketing Den" - icon_state = "bar" - -/area/crew_quarters/abandoned_gambling_den - name = "Abandoned Gambling Den" - icon_state = "abandoned_g_den" - -/area/crew_quarters/abandoned_gambling_den/secondary - icon_state = "abandoned_g_den_2" - -/area/crew_quarters/theatre - name = "Theatre" - icon_state = "Theatre" - -/area/crew_quarters/theatre/abandoned - name = "Abandoned Theatre" - icon_state = "Theatre" - -/area/crew_quarters/theatre/clown - name = "Clown's Office" - -/area/crew_quarters/theatre/mime - name = "Mime's Office" - -/area/crew_quarters/cryopod - name = "Cryogenics" - icon_state = "cryosleep" - -/area/library - name = "Library" - icon_state = "library" - flags_1 = NONE - -/area/library/lounge - name = "Library Lounge" - icon_state = "library" - -/area/library/abandoned - name = "Abandoned Library" - icon_state = "library" - flags_1 = NONE - -/area/chapel - icon_state = "chapel" - ambientsounds = HOLY - flags_1 = NONE - clockwork_warp_allowed = FALSE - clockwork_warp_fail = "The consecration here prevents you from warping in." - -/area/chapel/main - name = "Chapel" - -/area/chapel/main/monastery - name = "Monastery" - -/area/chapel/office - name = "Chapel Office" - icon_state = "chapeloffice" - -/area/chapel/asteroid - name = "Chapel Asteroid" - icon_state = "explored" - -/area/chapel/asteroid/monastery - name = "Monastery Asteroid" - -/area/chapel/dock - name = "Chapel Dock" - icon_state = "construction" - -/area/lawoffice - name = "Law Office" - icon_state = "law" - - -//Engineering - -/area/engine - ambientsounds = ENGINEERING - -/area/engine/engine_smes - name = "Engineering SMES" - icon_state = "engine_smes" - -/area/engine/engineering - name = "Engineering" - icon_state = "engine" - -/area/engine/atmos - name = "Atmospherics" - icon_state = "atmos" - flags_1 = NONE - -/area/engine/atmospherics_engine - name = "Atmospherics Engine" - icon_state = "atmos_engine" - -/area/engine/supermatter - name = "Supermatter Engine" - icon_state = "engine_sm" - -/area/engine/break_room - name = "Engineering Foyer" - icon_state = "engine_foyer" - -/area/engine/gravity_generator - name = "Gravity Generator Room" - icon_state = "grav_gen" - clockwork_warp_allowed = FALSE - clockwork_warp_fail = "The gravitons generated here could throw off your warp's destination and possibly throw you into deep space." - -/area/engine/secure_construction - name = "Secure Construction Area" - icon_state = "engine" - -/area/engine/storage - name = "Engineering Storage" - icon_state = "engi_storage" - -/area/engine/storage_shared - name = "Shared Engineering Storage" - icon_state = "engi_storage" - -/area/engine/transit_tube - name = "Transit Tube" - icon_state = "transit_tube" - - -//Solars - -/area/solar - requires_power = FALSE - dynamic_lighting = DYNAMIC_LIGHTING_IFSTARLIGHT - valid_territory = FALSE - blob_allowed = FALSE - flags_1 = NONE - ambientsounds = ENGINEERING - -/area/solar/fore - name = "Fore Solar Array" - icon_state = "yellow" - -/area/solar/aft - name = "Aft Solar Array" - icon_state = "yellow" - -/area/solar/aux/port - name = "Port Bow Auxiliary Solar Array" - icon_state = "panelsA" - -/area/solar/aux/starboard - name = "Starboard Bow Auxiliary Solar Array" - icon_state = "panelsA" - -/area/solar/starboard - name = "Starboard Solar Array" - icon_state = "panelsS" - -/area/solar/starboard/aft - name = "Starboard Quarter Solar Array" - icon_state = "panelsAS" - -/area/solar/starboard/fore - name = "Starboard Bow Solar Array" - icon_state = "panelsFS" - -/area/solar/port - name = "Port Solar Array" - icon_state = "panelsP" - -/area/solar/port/aft - name = "Port Quarter Solar Array" - icon_state = "panelsAP" - -/area/solar/port/fore - name = "Port Bow Solar Array" - icon_state = "panelsFP" - - -//Solar Maint - -/area/maintenance/solars - name = "Solar Maintenance" - icon_state = "yellow" - -/area/maintenance/solars/port - name = "Port Solar Maintenance" - icon_state = "SolarcontrolP" - -/area/maintenance/solars/port/aft - name = "Port Quarter Solar Maintenance" - icon_state = "SolarcontrolAP" - -/area/maintenance/solars/port/fore - name = "Port Bow Solar Maintenance" - icon_state = "SolarcontrolFP" - -/area/maintenance/solars/starboard - name = "Starboard Solar Maintenance" - icon_state = "SolarcontrolS" - -/area/maintenance/solars/starboard/aft - name = "Starboard Quarter Solar Maintenance" - icon_state = "SolarcontrolAS" - -/area/maintenance/solars/starboard/fore - name = "Starboard Bow Solar Maintenance" - icon_state = "SolarcontrolFS" - -/area/maintenance/solars/aux/port - name = "Port Auxiliary Solar Maintenance" - icon_state = "SolarcontrolA" - -/area/maintenance/solars/aux/port/aft - name = "Port Quarter Auxiliary Solar Maintenance" - icon_state = "SolarcontrolAP" - -/area/maintenance/solars/aux/port/fore - name = "Port Bow Auxiliary Solar Maintenance" - icon_state = "SolarcontrolA" - -/area/maintenance/solars/aux/starboard - name = "Starboard Auxiliary Solar Maintenance" - icon_state = "SolarcontrolA" - -/area/maintenance/solars/aux/starboard/aft - name = "Starboard Quarter Auxiliary Solar Maintenance" - icon_state = "SolarcontrolA" - -/area/maintenance/solars/aux/starboard/fore - name = "Starboard Bow Auxiliary Solar Maintenance" - icon_state = "SolarcontrolA" - -//Teleporter - -/area/teleporter - name = "Teleporter Room" - icon_state = "teleporter" - music = "signal" - ambientsounds = ENGINEERING - -/area/gateway - name = "Gateway" - icon_state = "gateway" - music = "signal" - ambientsounds = ENGINEERING - -//MedBay - -/area/medical - name = "Medical" - icon_state = "medbay3" - ambientsounds = MEDICAL - -/area/medical/abandoned - name = "Abandoned Medbay" - icon_state = "medbay3" - music = 'sound/ambience/signal.ogg' - -/area/medical/medbay/central - name = "Medbay Central" - icon_state = "medbay" - music = 'sound/ambience/signal.ogg' - -/area/medical/medbay/front_office - name = "Medbay Front Office" - icon_state = "medbay" - music = 'sound/ambience/signal.ogg' - -/area/medical/medbay/lobby - name = "Medbay Lobby" - icon_state = "medbay" - music = 'sound/ambience/signal.ogg' - - //Medbay is a large area, these additional areas help level out APC load. - -/area/medical/medbay/zone2 - name = "Medbay" - icon_state = "medbay2" - music = 'sound/ambience/signal.ogg' - -/area/medical/medbay/zone3 - name = "Medbay" - icon_state = "medbay3" - music = 'sound/ambience/signal.ogg' - -/area/medical/medbay/aft - name = "Medbay Aft" - icon_state = "medbay3" - music = 'sound/ambience/signal.ogg' - -/area/medical/storage - name = "Medbay Storage" - icon_state = "medbay2" - music = 'sound/ambience/signal.ogg' - -/area/medical/patients_rooms - name = "Patients' Rooms" - icon_state = "patients" - -/area/medical/patients_rooms/room_a - name = "Patient Room A" - icon_state = "patients" - -/area/medical/patients_rooms/room_b - name = "Patient Room B" - icon_state = "patients" - -/area/medical/virology - name = "Virology" - icon_state = "virology" - flags_1 = NONE - -/area/medical/morgue - name = "Morgue" - icon_state = "morgue" - ambientsounds = SPOOKY - -/area/medical/chemistry - name = "Chemistry" - icon_state = "chem" - -/area/medical/surgery - name = "Surgery" - icon_state = "surgery" - -/area/medical/cryo - name = "Cryogenics" - icon_state = "cryo" - -/area/medical/exam_room - name = "Exam Room" - icon_state = "exam_room" - -/area/medical/genetics - name = "Genetics Lab" - icon_state = "genetics" - -/area/medical/genetics/cloning - name = "Cloning Lab" - icon_state = "cloning" - -/area/medical/sleeper - name = "Medbay Treatment Center" - icon_state = "exam_room" - - -//Security - -/area/security - name = "Security" - icon_state = "security" - ambientsounds = HIGHSEC - -/area/security/main - name = "Security Office" - icon_state = "security" - -/area/security/brig - name = "Brig" - icon_state = "brig" - -/area/security/courtroom - name = "Courtroom" - icon_state = "courtroom" - -/area/security/prison - name = "Prison Wing" - icon_state = "sec_prison" - -/area/security/processing - name = "Labor Shuttle Dock" - icon_state = "sec_prison" - -/area/security/processing/cremation - name = "Security Crematorium" - icon_state = "sec_prison" - -/area/security/warden - name = "Brig Control" - icon_state = "Warden" - -/area/security/armory - name = "Armory" - icon_state = "armory" - -/area/security/detectives_office - name = "Detective's Office" - icon_state = "detective" - ambientsounds = list('sound/ambience/ambidet1.ogg','sound/ambience/ambidet2.ogg') - -/area/security/detectives_office/private_investigators_office - name = "Private Investigator's Office" - icon_state = "detective" - -/area/security/range - name = "Firing Range" - icon_state = "firingrange" - -/area/security/execution - icon_state = "execution_room" - -/area/security/execution/transfer - name = "Transfer Centre" - -/area/security/execution/education - name = "Prisoner Education Chamber" - -/area/security/nuke_storage - name = "Vault" - icon_state = "nuke_storage" - -/area/ai_monitored/nuke_storage - name = "Vault" - icon_state = "nuke_storage" - -/area/security/checkpoint - name = "Security Checkpoint" - icon_state = "checkpoint1" - -/area/security/checkpoint/auxiliary - icon_state = "checkpoint_aux" - -/area/security/checkpoint/tertiary - icon_state = "checkpoint_tert" - -/area/security/checkpoint/escape - icon_state = "checkpoint_esc" - -/area/security/checkpoint/supply - name = "Security Post - Cargo Bay" - icon_state = "checkpoint_supp" - -/area/security/checkpoint/engineering - name = "Security Post - Engineering" - icon_state = "checkpoint_engi" - -/area/security/checkpoint/medical - name = "Security Post - Medbay" - icon_state = "checkpoint_med" - -/area/security/checkpoint/science - name = "Security Post - Science" - icon_state = "checkpoint_sci" - -/area/security/checkpoint/science/research - name = "Security Post - Research Division" - icon_state = "checkpoint_res" - -/area/security/checkpoint/customs - name = "Customs" - icon_state = "customs_point" - -/area/security/checkpoint/customs/auxiliary - icon_state = "customs_point_aux" - -/area/security/vacantoffice - name = "Vacant Office" - icon_state = "security" - -/area/security/vacantoffice/a - name = "Vacant Office A" - icon_state = "security" - -/area/security/vacantoffice/b - name = "Vacant Office B" - icon_state = "security" - -/area/quartermaster - name = "Quartermasters" - icon_state = "quart" - -///////////WORK IN PROGRESS////////// - -/area/quartermaster/sorting - name = "Delivery Office" - icon_state = "cargo_delivery" - -/area/quartermaster/warehouse - name = "Warehouse" - icon_state = "cargo_warehouse" - -////////////WORK IN PROGRESS////////// - -/area/quartermaster/office - name = "Cargo Office" - icon_state = "quartoffice" - -/area/quartermaster/storage - name = "Cargo Bay" - icon_state = "cargo_bay" - -/area/quartermaster/qm - name = "Quartermaster's Office" - icon_state = "quart" - -/area/quartermaster/qm/private - name = "Quartermaster's Private Quarters" - icon_state = "quart" - -/area/quartermaster/miningdock - name = "Mining Dock" - icon_state = "mining" - -/area/quartermaster/miningdock/abandoned - name = "Abandoned Mining Dock" - icon_state = "mining" - -/area/quartermaster/miningoffice - name = "Mining Office" - icon_state = "mining" - -/area/quartermaster/miningstorage - name = "Mining Storage" - icon_state = "mining" - -/area/janitor - name = "Custodial Closet" - icon_state = "janitor" - flags_1 = NONE - -/area/hydroponics - name = "Hydroponics" - icon_state = "hydro" - -/area/hydroponics/garden - name = "Garden" - icon_state = "garden" - -/area/hydroponics/garden/abandoned - name = "Abandoned Garden" - icon_state = "abandoned_garden" - -/area/hydroponics/garden/monastery - name = "Monastery Garden" - icon_state = "hydro" - - -//Science - -/area/science - name = "Science Division" - icon_state = "toxlab" - -/area/science/lab - name = "Research and Development" - icon_state = "toxlab" - -/area/science/xenobiology - name = "Xenobiology Lab" - icon_state = "toxlab" - -/area/science/storage - name = "Toxins Storage" - icon_state = "toxstorage" - -/area/science/mineral_storeroom - name = "Mineral Storeroom" - icon_state = "toxmisc" - -/area/science/test_area - valid_territory = FALSE - name = "Toxins Test Area" - icon_state = "toxtest" - -/area/science/mixing - name = "Toxins Mixing Lab" - icon_state = "toxmix" - -/area/science/mixing/chamber - name = "Toxins Mixing Chamber" - icon_state = "toxmix" - valid_territory = FALSE - -/area/science/misc_lab - name = "Testing Lab" - icon_state = "toxmisc" - -/area/science/misc_lab/range - name = "Research Testing Range" - icon_state = "toxmisc" - -/area/science/server - name = "Research Division Server Room" - icon_state = "server" - -/area/science/explab - name = "Experimentation Lab" - icon_state = "toxmisc" - -/area/science/robotics - name = "Robotics" - icon_state = "medresearch" - -/area/science/robotics/mechbay - name = "Mech Bay" - icon_state = "mechbay" - -/area/science/robotics/mechbay_cargo - name = "Mech Bay" - icon_state = "yellow" - -/area/science/robotics/showroom - name = "Robotics Showroom" - icon_state = "showroom" - -/area/science/robotics/lab - name = "Robotics Lab" - icon_state = "ass_line" - -/area/science/research - name = "Research Division" - icon_state = "medresearch" - -/area/science/circuit - name = "Circuitry Lab" - icon_state = "cir_lab" - -/area/science/research/lobby - name = "Research Division Lobby" - icon_state = "medresearch" - -/area/science/research/abandoned - name = "Abandoned Research Lab" - icon_state = "medresearch" - -/area/science/nanite - name = "Nanite Lab" - icon_state = "toxmisc" - -//Storage - -/area/storage/tools - name = "Auxiliary Tool Storage" - icon_state = "storage" - -/area/storage/primary - name = "Primary Tool Storage" - icon_state = "primarystorage" - -/area/storage/autolathe - name = "Autolathe Storage" - icon_state = "storage" - -/area/storage/art - name = "Art Supply Storage" - icon_state = "storage" - -/area/storage/auxiliary - name = "Auxiliary Storage" - icon_state = "auxstorage" - -/area/storage/atmos - name = "Atmospherics Storage" - icon_state = "atmos" - valid_territory = FALSE - -/area/storage/tcom - name = "Telecomms Storage" - icon_state = "green" - valid_territory = FALSE - -/area/storage/eva - name = "EVA Storage" - icon_state = "eva" - clockwork_warp_allowed = FALSE - -/area/storage/secure - name = "Secure Storage" - icon_state = "storage" - clockwork_warp_allowed = FALSE - -/area/storage/emergency/starboard - name = "Starboard Emergency Storage" - icon_state = "emergencystorage" - -/area/storage/emergency/port - name = "Port Emergency Storage" - icon_state = "emergencystorage" - -/area/storage/tech - name = "Technical Storage" - icon_state = "auxstorage" - -/area/storage/testroom - requires_power = FALSE - name = "Test Room" - icon_state = "storage" - - -//Construction - -/area/construction - name = "Construction Area" - icon_state = "yellow" - ambientsounds = ENGINEERING - -/area/construction/minisat_exterior - name = "Minisat Exterior" - icon_state = "yellow" - -/area/construction/mining/aux_base - name = "Auxiliary Base Construction" - icon_state = "yellow" - -/area/construction/mining/aux_base/closet - name = "Auxiliary Closet Construction" - icon_state = "yellow" - -/area/construction/supplyshuttle - name = "Supply Shuttle" - icon_state = "yellow" - -/area/construction/quarters - name = "Engineers' Quarters" - icon_state = "yellow" - -/area/construction/qmaint - name = "Maintenance" - icon_state = "yellow" - -/area/construction/hallway - name = "Hallway" - icon_state = "yellow" - -/area/construction/solars - name = "Solar Panels" - icon_state = "yellow" - -/area/construction/solarscontrol - name = "Solar Panel Control" - icon_state = "yellow" - -/area/construction/storage - name = "Construction Site Storage" - icon_state = "yellow" - -/area/construction/storage/wing - name = "Storage Wing" - icon_state = "storage_wing" - - -//AI - -/area/ai_monitored/security/armory - name = "Armory" - icon_state = "armory" - ambientsounds = HIGHSEC - -/area/ai_monitored/storage/eva - name = "EVA Storage" - icon_state = "eva" - ambientsounds = HIGHSEC - -/area/ai_monitored/storage/satellite - name = "AI Satellite Maint" - icon_state = "storage" - ambientsounds = HIGHSEC - - //Turret_protected - -/area/ai_monitored/turret_protected - ambientsounds = list('sound/ambience/ambimalf.ogg', 'sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg') - -/area/ai_monitored/turret_protected/ai_upload - name = "AI Upload Chamber" - icon_state = "ai_upload" - -/area/ai_monitored/turret_protected/ai_upload_foyer - name = "AI Upload Access" - icon_state = "ai_foyer" - -/area/ai_monitored/turret_protected/ai - name = "AI Chamber" - icon_state = "ai_chamber" - -/area/ai_monitored/turret_protected/aisat - name = "AI Satellite" - icon_state = "ai" - -/area/ai_monitored/turret_protected/aisat/atmos - name = "AI Satellite Atmos" - icon_state = "ai" - -/area/ai_monitored/turret_protected/aisat/foyer - name = "AI Satellite Foyer" - icon_state = "ai" - -/area/ai_monitored/turret_protected/aisat/service - name = "AI Satellite Service" - icon_state = "ai" - -/area/ai_monitored/turret_protected/aisat/hallway - name = "AI Satellite Hallway" - icon_state = "ai" - -/area/aisat - name = "AI Satellite Exterior" - icon_state = "yellow" - -/area/ai_monitored/turret_protected/aisat_interior - name = "AI Satellite Antechamber" - icon_state = "ai" - -/area/ai_monitored/turret_protected/AIsatextFP - name = "AI Sat Ext" - icon_state = "storage" - -/area/ai_monitored/turret_protected/AIsatextFS - name = "AI Sat Ext" - icon_state = "storage" - -/area/ai_monitored/turret_protected/AIsatextAS - name = "AI Sat Ext" - icon_state = "storage" - -/area/ai_monitored/turret_protected/AIsatextAP - name = "AI Sat Ext" - icon_state = "storage" - - -// Telecommunications Satellite - -/area/tcommsat - clockwork_warp_allowed = FALSE - clockwork_warp_fail = "For safety reasons, warping here is disallowed; the radio and bluespace noise could cause catastrophic results." - ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg', 'sound/ambience/ambitech.ogg',\ - 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambitech3.ogg', 'sound/ambience/ambimystery.ogg') - -/area/tcommsat/entrance - name = "Telecomms Teleporter" - icon_state = "tcomsatentrance" - -/area/tcommsat/chamber - name = "Abandoned Satellite" - icon_state = "tcomsatcham" - -/area/ai_monitored/turret_protected/tcomsat - name = "Telecomms Satellite" - icon_state = "tcomsatlob" - -/area/ai_monitored/turret_protected/tcomfoyer - name = "Telecomms Foyer" - icon_state = "tcomsatentrance" - -/area/ai_monitored/turret_protected/tcomwest - name = "Telecommunications Satellite West Wing" - icon_state = "tcomsatwest" - -/area/ai_monitored/turret_protected/tcomeast - name = "Telecommunications Satellite East Wing" - icon_state = "tcomsateast" - -/area/tcommsat/computer - name = "Telecomms Control Room" - icon_state = "tcomsatcomp" - -/area/tcommsat/server - name = "Telecomms Server Room" - icon_state = "tcomsatcham" - -/area/tcommsat/lounge - name = "Telecommunications Satellite Lounge" - icon_state = "tcomsatlounge" +/* + +### This file contains a list of all the areas in your station. Format is as follows: + +/area/CATEGORY/OR/DESCRIPTOR/NAME (you can make as many subdivisions as you want) + name = "NICE NAME" (not required but makes things really nice) + icon = 'ICON FILENAME' (defaults to 'icons/turf/areas.dmi') + icon_state = "NAME OF ICON" (defaults to "unknown" (blank)) + requires_power = FALSE (defaults to true) + music = null (defaults to nothing, look in sound/ambience for music) + +NOTE: there are two lists of areas in the end of this file: centcom and station itself. Please maintain these lists valid. --rastaf0 + +*/ + + +/*-----------------------------------------------------------------------------*/ + +/area/ai_monitored //stub defined ai_monitored.dm + +/area/ai_monitored/turret_protected + +/area/arrival + requires_power = FALSE + +/area/arrival/start + name = "Arrival Area" + icon_state = "start" + +/area/admin + name = "Admin room" + icon_state = "start" + +/area/space + icon_state = "space" + requires_power = TRUE + always_unpowered = TRUE + dynamic_lighting = DYNAMIC_LIGHTING_DISABLED + power_light = FALSE + power_equip = FALSE + power_environ = FALSE + valid_territory = FALSE + outdoors = TRUE + ambientsounds = SPACE + blob_allowed = FALSE //Eating up space doesn't count for victory as a blob. + +/area/space/nearstation + icon_state = "space_near" + dynamic_lighting = DYNAMIC_LIGHTING_IFSTARLIGHT + +/area/start + name = "start area" + icon_state = "start" + requires_power = FALSE + dynamic_lighting = DYNAMIC_LIGHTING_DISABLED + has_gravity = STANDARD_GRAVITY + + +//EXTRA + +/area/asteroid + name = "Asteroid" + icon_state = "asteroid" + requires_power = FALSE + has_gravity = STANDARD_GRAVITY + blob_allowed = FALSE //Nope, no winning on the asteroid as a blob. Gotta eat the station. + valid_territory = FALSE + ambientsounds = MINING + +/area/asteroid/nearstation + dynamic_lighting = DYNAMIC_LIGHTING_FORCED + ambientsounds = RUINS + always_unpowered = FALSE + requires_power = TRUE + blob_allowed = TRUE + +/area/asteroid/nearstation/bomb_site + name = "Bomb Testing Asteroid" + +/area/asteroid/cave + name = "Asteroid - Underground" + icon_state = "cave" + requires_power = FALSE + outdoors = TRUE + +/area/asteroid/cave/space + name = "Asteroid - Space" + +/area/asteroid/artifactroom + name = "Asteroid - Artifact" + icon_state = "cave" + ambientsounds = RUINS + +/area/asteroid/artifactroom/Initialize() + . = ..() + set_dynamic_lighting() + + +//STATION13 + +//Maintenance + +/area/maintenance + ambientsounds = MAINTENANCE + valid_territory = FALSE + + +//Departments + +/area/maintenance/department/chapel + name = "Chapel Maintenance" + icon_state = "maint_chapel" + +/area/maintenance/department/chapel/monastery + name = "Monastery Maintenance" + icon_state = "maint_monastery" + +/area/maintenance/department/crew_quarters/bar + name = "Bar Maintenance" + icon_state = "maint_bar" + +/area/maintenance/department/crew_quarters/dorms + name = "Dormitory Maintenance" + icon_state = "maint_dorms" + +/area/maintenance/department/crew_quarters/locker + name = "Locker Room Maintenance" + icon_state = "maint_locker" + +/area/maintenance/department/eva + name = "EVA Maintenance" + icon_state = "maint_eva" + +/area/maintenance/department/electrical + name = "Electrical Maintenance" + icon_state = "maint_electrical" + +/area/maintenance/department/engine/atmos + name = "Atmospherics Maintenance" + icon_state = "maint_atmos" + +/area/maintenance/department/security + name = "Security Maintenance" + icon_state = "maint_sec" + +/area/maintenance/department/security/brig + name = "Brig Maintenance" + icon_state = "maint_brig" + +/area/maintenance/department/medical + name = "Medbay Maintenance" + icon_state = "medbay_maint" + +/area/maintenance/department/medical/morgue + name = "Morgue Maintenance" + icon_state = "morgue_maint" + +/area/maintenance/department/science + name = "Science Maintenance" + icon_state = "maint_sci" + +/area/maintenance/department/cargo + name = "Cargo Maintenance" + icon_state = "maint_cargo" + +/area/maintenance/department/bridge + name = "Bridge Maintenance" + icon_state = "maint_bridge" + +/area/maintenance/department/engine + name = "Engineering Maintenance" + icon_state = "maint_engi" + +/area/maintenance/department/science/xenobiology + name = "Xenobiology Maintenance" + icon_state = "xenomaint" + xenobiology_compatible = TRUE + + +//Maintenance - Generic + +/area/maintenance/arrivals/north + name = "Arrivals North Maintenance" + icon_state = "fpmaint" + +/area/maintenance/arrivals/north_2 + name = "Arrivals North Maintenance" + icon_state = "fpmaint" + +/area/maintenance/aft + name = "Aft Maintenance" + icon_state = "amaint" + +/area/maintenance/aft/secondary + name = "Aft Maintenance" + icon_state = "amaint_2" + +/area/maintenance/central + name = "Central Maintenance" + icon_state = "maintcentral" + +/area/maintenance/central/secondary + name = "Central Maintenance" + icon_state = "maintcentral" + +/area/maintenance/fore + name = "Fore Maintenance" + icon_state = "fmaint" + +/area/maintenance/fore/secondary + name = "Fore Maintenance" + icon_state = "fmaint_2" + +/area/maintenance/starboard + name = "Starboard Maintenance" + icon_state = "smaint" + +/area/maintenance/starboard/central + name = "Central Starboard Maintenance" + icon_state = "smaint" + +/area/maintenance/starboard/aft + name = "Starboard Quarter Maintenance" + icon_state = "asmaint" + +/area/maintenance/starboard/fore + name = "Starboard Bow Maintenance" + icon_state = "fsmaint" + +/area/maintenance/port + name = "Port Maintenance" + icon_state = "pmaint" + +/area/maintenance/port/central + name = "Central Port Maintenance" + icon_state = "maintcentral" + +/area/maintenance/port/aft + name = "Port Quarter Maintenance" + icon_state = "apmaint" + +/area/maintenance/port/fore + name = "Port Bow Maintenance" + icon_state = "fpmaint" + +/area/maintenance/disposal + name = "Waste Disposal" + icon_state = "disposal" + +/area/maintenance/disposal/incinerator + name = "Incinerator" + icon_state = "disposal" +/area/maintenance/bar + name = "Maintenance Bar" + icon_state = "maintbar" + +/area/maintenance/bar/cafe + name = "Abandoned Cafe" + +//Hallway + +/area/hallway/primary/aft + name = "Aft Primary Hallway" + icon_state = "hallA" + +/area/hallway/primary/fore + name = "Fore Primary Hallway" + icon_state = "hallF" + +/area/hallway/primary/starboard + name = "Starboard Primary Hallway" + icon_state = "hallS" + +/area/hallway/primary/starboard/aft + name = "Starboard Quarter Primary Hallway" + icon_state = "hallAS" + +/area/hallway/primary/starboard/fore + name = "Starboard Bow Primary Hallway" + icon_state = "hallFS" + +/area/hallway/primary/port + name = "Port Primary Hallway" + icon_state = "hallP" + +/area/hallway/primary/port/aft + name = "Port Quarter Primary Hallway" + icon_state = "hallAP" + +/area/hallway/primary/port/fore + name = "Port Bow Primary Hallway" + icon_state = "hallFP" + +/area/hallway/primary/central + name = "Central Primary Hallway" + icon_state = "hallC" + +/area/hallway/secondary/command + name = "Command Hallway" + icon_state = "bridge_hallway" + +/area/hallway/secondary/construction + name = "Construction Area" + icon_state = "construction" + +/area/hallway/secondary/exit + name = "Escape Shuttle Hallway" + icon_state = "escape" + +/area/hallway/secondary/exit/departure_lounge + name = "Departure Lounge" + icon_state = "escape_lounge" + +/area/hallway/secondary/entry + name = "Arrival Shuttle Hallway" + icon_state = "entry" + +/area/hallway/secondary/service + name = "Service Hallway" + icon_state = "hall_service" + +//Command + +/area/bridge + name = "Bridge" + icon_state = "bridge" + music = "signal" + +/area/bridge/meeting_room + name = "Heads of Staff Meeting Room" + icon_state = "meeting" + music = null + +/area/bridge/meeting_room/council + name = "Council Chamber" + icon_state = "meeting" + music = null + +/area/bridge/showroom/corporate + name = "Corporate Showroom" + icon_state = "showroom" + music = null + +/area/crew_quarters/heads/captain + name = "Captain's Office" + icon_state = "captain" + clockwork_warp_allowed = FALSE + +/area/crew_quarters/heads/captain/private + name = "Captain's Quarters" + icon_state = "captain" + +/area/crew_quarters/heads/chief + name = "Chief Engineer's Office" + icon_state = "ce_office" + +/area/crew_quarters/heads/chief/private + name = "Chief Engineer's Private Quarters" + icon_state = "ce_private" + +/area/crew_quarters/heads/cmo + name = "Chief Medical Officer's Office" + icon_state = "cmo_office" + +/area/crew_quarters/heads/cmo/private + name = "Chief Medical Officer's Private Quarters" + icon_state = "cmo_private" + +/area/crew_quarters/heads/hop + name = "Head of Personnel's Office" + icon_state = "hop_office" + +/area/crew_quarters/heads/hop/private + name = "Head of Personnel's Private Quarters" + icon_state = "hop_private" + +/area/crew_quarters/heads/hos + name = "Head of Security's Office" + icon_state = "hos_office" + +/area/crew_quarters/heads/hos/private + name = "Head of Security's Private Quarters" + icon_state = "hos_private" + +/area/crew_quarters/heads/hor + name = "Research Director's Office" + icon_state = "rd_office" + +/area/crew_quarters/heads/hor/private + name = "Research Director's Private Quarters" + icon_state = "rd_private" + +/area/comms + name = "Communications Relay" + icon_state = "tcomsatcham" + +/area/server + name = "Messaging Server Room" + icon_state = "server" + +//Crew + +/area/crew_quarters/dorms + name = "Dormitories" + icon_state = "Sleep" + safe = TRUE + +/area/crew_quarters/dorms/male + name = "Male Dorm" + icon_state = "Sleep" + +/area/crew_quarters/dorms/female + name = "Female Dorm" + icon_state = "Sleep" + +/area/crew_quarters/rehab_dome + name = "Rehabilitation Dome" + icon_state = "Sleep" + +/area/crew_quarters/toilet + name = "Dormitory Toilets" + icon_state = "toilet" + +/area/crew_quarters/toilet/auxiliary + name = "Auxiliary Restrooms" + icon_state = "toilet" + +/area/crew_quarters/toilet/locker + name = "Locker Toilets" + icon_state = "toilet" + +/area/crew_quarters/toilet/fitness + name = "Fitness Toilets" + icon_state = "toilet" + +/area/crew_quarters/toilet/female + name = "Female Toilets" + icon_state = "toilet" + +/area/crew_quarters/toilet/male + name = "Male Toilets" + icon_state = "toilet" + +/area/crew_quarters/toilet/restrooms + name = "Restrooms" + icon_state = "toilet" + +/area/crew_quarters/locker + name = "Locker Room" + icon_state = "locker" + +/area/crew_quarters/lounge + name = "Lounge" + icon_state = "yellow" + +/area/crew_quarters/fitness + name = "Fitness Room" + icon_state = "fitness" + +/area/crew_quarters/fitness/recreation + name = "Recreation Area" + icon_state = "fitness" + +/area/crew_quarters/cafeteria + name = "Cafeteria" + icon_state = "cafeteria" + +/area/crew_quarters/cafeteria/lunchroom + name = "Lunchroom" + icon_state = "cafeteria" + +/area/crew_quarters/kitchen + name = "Kitchen" + icon_state = "kitchen" + +/area/crew_quarters/kitchen/backroom + name = "Kitchen Coldroom" + icon_state = "kitchen" + +/area/crew_quarters/bar + name = "Bar" + icon_state = "bar" + +/area/crew_quarters/bar/atrium + name = "Atrium" + icon_state = "bar" + +/area/crew_quarters/electronic_marketing_den + name = "Electronic Marketing Den" + icon_state = "bar" + +/area/crew_quarters/abandoned_gambling_den + name = "Abandoned Gambling Den" + icon_state = "abandoned_g_den" + +/area/crew_quarters/abandoned_gambling_den/secondary + icon_state = "abandoned_g_den_2" + +/area/crew_quarters/theatre + name = "Theatre" + icon_state = "Theatre" + +/area/crew_quarters/theatre/abandoned + name = "Abandoned Theatre" + icon_state = "Theatre" + +/area/crew_quarters/theatre/clown + name = "Clown's Office" + +/area/crew_quarters/theatre/mime + name = "Mime's Office" + +/area/crew_quarters/cryopod + name = "Cryogenics" + icon_state = "cryosleep" + +/area/library + name = "Library" + icon_state = "library" + flags_1 = NONE + +/area/library/lounge + name = "Library Lounge" + icon_state = "library" + +/area/library/abandoned + name = "Abandoned Library" + icon_state = "library" + flags_1 = NONE + +/area/chapel + icon_state = "chapel" + ambientsounds = HOLY + flags_1 = NONE + clockwork_warp_allowed = FALSE + clockwork_warp_fail = "The consecration here prevents you from warping in." + +/area/chapel/main + name = "Chapel" + +/area/chapel/main/monastery + name = "Monastery" + +/area/chapel/office + name = "Chapel Office" + icon_state = "chapeloffice" + +/area/chapel/asteroid + name = "Chapel Asteroid" + icon_state = "explored" + +/area/chapel/asteroid/monastery + name = "Monastery Asteroid" + +/area/chapel/dock + name = "Chapel Dock" + icon_state = "construction" + +/area/lawoffice + name = "Law Office" + icon_state = "law" + + +//Engineering + +/area/engine + ambientsounds = ENGINEERING + +/area/engine/engine_smes + name = "Engineering SMES" + icon_state = "engine_smes" + +/area/engine/engineering + name = "Engineering" + icon_state = "engine" + +/area/engine/atmos + name = "Atmospherics" + icon_state = "atmos" + flags_1 = NONE + +/area/engine/atmospherics_engine + name = "Atmospherics Engine" + icon_state = "atmos_engine" + +/area/engine/supermatter + name = "Supermatter Engine" + icon_state = "engine_sm" + +/area/engine/break_room + name = "Engineering Foyer" + icon_state = "engine_foyer" + +/area/engine/gravity_generator + name = "Gravity Generator Room" + icon_state = "grav_gen" + clockwork_warp_allowed = FALSE + clockwork_warp_fail = "The gravitons generated here could throw off your warp's destination and possibly throw you into deep space." + +/area/engine/secure_construction + name = "Secure Construction Area" + icon_state = "engine" + +/area/engine/storage + name = "Engineering Storage" + icon_state = "engi_storage" + +/area/engine/storage_shared + name = "Shared Engineering Storage" + icon_state = "engi_storage" + +/area/engine/transit_tube + name = "Transit Tube" + icon_state = "transit_tube" + + +//Solars + +/area/solar + requires_power = FALSE + dynamic_lighting = DYNAMIC_LIGHTING_IFSTARLIGHT + valid_territory = FALSE + blob_allowed = FALSE + flags_1 = NONE + ambientsounds = ENGINEERING + +/area/solar/fore + name = "Fore Solar Array" + icon_state = "yellow" + +/area/solar/aft + name = "Aft Solar Array" + icon_state = "yellow" + +/area/solar/aux/port + name = "Port Bow Auxiliary Solar Array" + icon_state = "panelsA" + +/area/solar/aux/starboard + name = "Starboard Bow Auxiliary Solar Array" + icon_state = "panelsA" + +/area/solar/starboard + name = "Starboard Solar Array" + icon_state = "panelsS" + +/area/solar/starboard/aft + name = "Starboard Quarter Solar Array" + icon_state = "panelsAS" + +/area/solar/starboard/fore + name = "Starboard Bow Solar Array" + icon_state = "panelsFS" + +/area/solar/port + name = "Port Solar Array" + icon_state = "panelsP" + +/area/solar/port/aft + name = "Port Quarter Solar Array" + icon_state = "panelsAP" + +/area/solar/port/fore + name = "Port Bow Solar Array" + icon_state = "panelsFP" + + +//Solar Maint + +/area/maintenance/solars + name = "Solar Maintenance" + icon_state = "yellow" + +/area/maintenance/solars/port + name = "Port Solar Maintenance" + icon_state = "SolarcontrolP" + +/area/maintenance/solars/port/aft + name = "Port Quarter Solar Maintenance" + icon_state = "SolarcontrolAP" + +/area/maintenance/solars/port/fore + name = "Port Bow Solar Maintenance" + icon_state = "SolarcontrolFP" + +/area/maintenance/solars/starboard + name = "Starboard Solar Maintenance" + icon_state = "SolarcontrolS" + +/area/maintenance/solars/starboard/aft + name = "Starboard Quarter Solar Maintenance" + icon_state = "SolarcontrolAS" + +/area/maintenance/solars/starboard/fore + name = "Starboard Bow Solar Maintenance" + icon_state = "SolarcontrolFS" + +/area/maintenance/solars/aux/port + name = "Port Auxiliary Solar Maintenance" + icon_state = "SolarcontrolA" + +/area/maintenance/solars/aux/port/aft + name = "Port Quarter Auxiliary Solar Maintenance" + icon_state = "SolarcontrolAP" + +/area/maintenance/solars/aux/port/fore + name = "Port Bow Auxiliary Solar Maintenance" + icon_state = "SolarcontrolA" + +/area/maintenance/solars/aux/starboard + name = "Starboard Auxiliary Solar Maintenance" + icon_state = "SolarcontrolA" + +/area/maintenance/solars/aux/starboard/aft + name = "Starboard Quarter Auxiliary Solar Maintenance" + icon_state = "SolarcontrolA" + +/area/maintenance/solars/aux/starboard/fore + name = "Starboard Bow Auxiliary Solar Maintenance" + icon_state = "SolarcontrolA" + +//Teleporter + +/area/teleporter + name = "Teleporter Room" + icon_state = "teleporter" + music = "signal" + ambientsounds = ENGINEERING + +/area/gateway + name = "Gateway" + icon_state = "gateway" + music = "signal" + ambientsounds = ENGINEERING + +//MedBay + +/area/medical + name = "Medical" + icon_state = "medbay3" + ambientsounds = MEDICAL + +/area/medical/abandoned + name = "Abandoned Medbay" + icon_state = "medbay3" + music = 'sound/ambience/signal.ogg' + +/area/medical/medbay/central + name = "Medbay Central" + icon_state = "medbay" + music = 'sound/ambience/signal.ogg' + +/area/medical/medbay/front_office + name = "Medbay Front Office" + icon_state = "medbay" + music = 'sound/ambience/signal.ogg' + +/area/medical/medbay/lobby + name = "Medbay Lobby" + icon_state = "medbay" + music = 'sound/ambience/signal.ogg' + + //Medbay is a large area, these additional areas help level out APC load. + +/area/medical/medbay/zone2 + name = "Medbay" + icon_state = "medbay2" + music = 'sound/ambience/signal.ogg' + +/area/medical/medbay/zone3 + name = "Medbay" + icon_state = "medbay3" + music = 'sound/ambience/signal.ogg' + +/area/medical/medbay/aft + name = "Medbay Aft" + icon_state = "medbay3" + music = 'sound/ambience/signal.ogg' + +/area/medical/storage + name = "Medbay Storage" + icon_state = "medbay2" + music = 'sound/ambience/signal.ogg' + +/area/medical/patients_rooms + name = "Patients' Rooms" + icon_state = "patients" + +/area/medical/patients_rooms/room_a + name = "Patient Room A" + icon_state = "patients" + +/area/medical/patients_rooms/room_b + name = "Patient Room B" + icon_state = "patients" + +/area/medical/virology + name = "Virology" + icon_state = "virology" + flags_1 = NONE + +/area/medical/morgue + name = "Morgue" + icon_state = "morgue" + ambientsounds = SPOOKY + +/area/medical/chemistry + name = "Chemistry" + icon_state = "chem" + +/area/medical/surgery + name = "Surgery" + icon_state = "surgery" + +/area/medical/cryo + name = "Cryogenics" + icon_state = "cryo" + +/area/medical/exam_room + name = "Exam Room" + icon_state = "exam_room" + +/area/medical/genetics + name = "Genetics Lab" + icon_state = "genetics" + +/area/medical/genetics/cloning + name = "Cloning Lab" + icon_state = "cloning" + +/area/medical/sleeper + name = "Medbay Treatment Center" + icon_state = "exam_room" + + +//Security + +/area/security + name = "Security" + icon_state = "security" + ambientsounds = HIGHSEC + +/area/security/main + name = "Security Office" + icon_state = "security" + +/area/security/brig + name = "Brig" + icon_state = "brig" + +/area/security/courtroom + name = "Courtroom" + icon_state = "courtroom" + +/area/security/prison + name = "Prison Wing" + icon_state = "sec_prison" + +/area/security/processing + name = "Labor Shuttle Dock" + icon_state = "sec_prison" + +/area/security/processing/cremation + name = "Security Crematorium" + icon_state = "sec_prison" + +/area/security/warden + name = "Brig Control" + icon_state = "Warden" + +/area/security/armory + name = "Armory" + icon_state = "armory" + +/area/security/detectives_office + name = "Detective's Office" + icon_state = "detective" + ambientsounds = list('sound/ambience/ambidet1.ogg','sound/ambience/ambidet2.ogg') + +/area/security/detectives_office/private_investigators_office + name = "Private Investigator's Office" + icon_state = "detective" + +/area/security/range + name = "Firing Range" + icon_state = "firingrange" + +/area/security/execution + icon_state = "execution_room" + +/area/security/execution/transfer + name = "Transfer Centre" + +/area/security/execution/education + name = "Prisoner Education Chamber" + +/area/security/nuke_storage + name = "Vault" + icon_state = "nuke_storage" + +/area/ai_monitored/nuke_storage + name = "Vault" + icon_state = "nuke_storage" + +/area/security/checkpoint + name = "Security Checkpoint" + icon_state = "checkpoint1" + +/area/security/checkpoint/auxiliary + icon_state = "checkpoint_aux" + +/area/security/checkpoint/tertiary + icon_state = "checkpoint_tert" + +/area/security/checkpoint/escape + icon_state = "checkpoint_esc" + +/area/security/checkpoint/supply + name = "Security Post - Cargo Bay" + icon_state = "checkpoint_supp" + +/area/security/checkpoint/engineering + name = "Security Post - Engineering" + icon_state = "checkpoint_engi" + +/area/security/checkpoint/medical + name = "Security Post - Medbay" + icon_state = "checkpoint_med" + +/area/security/checkpoint/science + name = "Security Post - Science" + icon_state = "checkpoint_sci" + +/area/security/checkpoint/science/research + name = "Security Post - Research Division" + icon_state = "checkpoint_res" + +/area/security/checkpoint/customs + name = "Customs" + icon_state = "customs_point" + +/area/security/checkpoint/customs/auxiliary + icon_state = "customs_point_aux" + +/area/security/vacantoffice + name = "Vacant Office" + icon_state = "security" + +/area/security/vacantoffice/a + name = "Vacant Office A" + icon_state = "security" + +/area/security/vacantoffice/b + name = "Vacant Office B" + icon_state = "security" + +/area/quartermaster + name = "Quartermasters" + icon_state = "quart" + +///////////WORK IN PROGRESS////////// + +/area/quartermaster/sorting + name = "Delivery Office" + icon_state = "cargo_delivery" + +/area/quartermaster/warehouse + name = "Warehouse" + icon_state = "cargo_warehouse" + +////////////WORK IN PROGRESS////////// + +/area/quartermaster/office + name = "Cargo Office" + icon_state = "quartoffice" + +/area/quartermaster/storage + name = "Cargo Bay" + icon_state = "cargo_bay" + +/area/quartermaster/qm + name = "Quartermaster's Office" + icon_state = "quart" + +/area/quartermaster/qm/private + name = "Quartermaster's Private Quarters" + icon_state = "quart" + +/area/quartermaster/miningdock + name = "Mining Dock" + icon_state = "mining" + +/area/quartermaster/miningdock/abandoned + name = "Abandoned Mining Dock" + icon_state = "mining" + +/area/quartermaster/miningoffice + name = "Mining Office" + icon_state = "mining" + +/area/quartermaster/miningstorage + name = "Mining Storage" + icon_state = "mining" + +/area/janitor + name = "Custodial Closet" + icon_state = "janitor" + flags_1 = NONE + +/area/hydroponics + name = "Hydroponics" + icon_state = "hydro" + +/area/hydroponics/garden + name = "Garden" + icon_state = "garden" + +/area/hydroponics/garden/abandoned + name = "Abandoned Garden" + icon_state = "abandoned_garden" + +/area/hydroponics/garden/monastery + name = "Monastery Garden" + icon_state = "hydro" + + +//Science + +/area/science + name = "Science Division" + icon_state = "toxlab" + +/area/science/lab + name = "Research and Development" + icon_state = "toxlab" + +/area/science/xenobiology + name = "Xenobiology Lab" + icon_state = "toxlab" + +/area/science/storage + name = "Toxins Storage" + icon_state = "toxstorage" + +/area/science/mineral_storeroom + name = "Mineral Storeroom" + icon_state = "toxmisc" + +/area/science/test_area + valid_territory = FALSE + name = "Toxins Test Area" + icon_state = "toxtest" + +/area/science/mixing + name = "Toxins Mixing Lab" + icon_state = "toxmix" + +/area/science/mixing/chamber + name = "Toxins Mixing Chamber" + icon_state = "toxmix" + valid_territory = FALSE + +/area/science/misc_lab + name = "Testing Lab" + icon_state = "toxmisc" + +/area/science/misc_lab/range + name = "Research Testing Range" + icon_state = "toxmisc" + +/area/science/server + name = "Research Division Server Room" + icon_state = "server" + +/area/science/explab + name = "Experimentation Lab" + icon_state = "toxmisc" + +/area/science/robotics + name = "Robotics" + icon_state = "medresearch" + +/area/science/robotics/mechbay + name = "Mech Bay" + icon_state = "mechbay" + +/area/science/robotics/mechbay_cargo + name = "Mech Bay" + icon_state = "yellow" + +/area/science/robotics/showroom + name = "Robotics Showroom" + icon_state = "showroom" + +/area/science/robotics/lab + name = "Robotics Lab" + icon_state = "ass_line" + +/area/science/research + name = "Research Division" + icon_state = "medresearch" + +/area/science/circuit + name = "Circuitry Lab" + icon_state = "cir_lab" + +/area/science/research/lobby + name = "Research Division Lobby" + icon_state = "medresearch" + +/area/science/research/abandoned + name = "Abandoned Research Lab" + icon_state = "medresearch" + +/area/science/nanite + name = "Nanite Lab" + icon_state = "toxmisc" + +//Storage + +/area/storage/tools + name = "Auxiliary Tool Storage" + icon_state = "storage" + +/area/storage/primary + name = "Primary Tool Storage" + icon_state = "primarystorage" + +/area/storage/autolathe + name = "Autolathe Storage" + icon_state = "storage" + +/area/storage/art + name = "Art Supply Storage" + icon_state = "storage" + +/area/storage/auxiliary + name = "Auxiliary Storage" + icon_state = "auxstorage" + +/area/storage/atmos + name = "Atmospherics Storage" + icon_state = "atmos" + valid_territory = FALSE + +/area/storage/tcom + name = "Telecomms Storage" + icon_state = "green" + valid_territory = FALSE + +/area/storage/eva + name = "EVA Storage" + icon_state = "eva" + clockwork_warp_allowed = FALSE + +/area/storage/secure + name = "Secure Storage" + icon_state = "storage" + clockwork_warp_allowed = FALSE + +/area/storage/emergency/starboard + name = "Starboard Emergency Storage" + icon_state = "emergencystorage" + +/area/storage/emergency/port + name = "Port Emergency Storage" + icon_state = "emergencystorage" + +/area/storage/tech + name = "Technical Storage" + icon_state = "auxstorage" + +/area/storage/testroom + requires_power = FALSE + name = "Test Room" + icon_state = "storage" + + +//Construction + +/area/construction + name = "Construction Area" + icon_state = "yellow" + ambientsounds = ENGINEERING + +/area/construction/minisat_exterior + name = "Minisat Exterior" + icon_state = "yellow" + +/area/construction/mining/aux_base + name = "Auxiliary Base Construction" + icon_state = "yellow" + +/area/construction/mining/aux_base/closet + name = "Auxiliary Closet Construction" + icon_state = "yellow" + +/area/construction/supplyshuttle + name = "Supply Shuttle" + icon_state = "yellow" + +/area/construction/quarters + name = "Engineers' Quarters" + icon_state = "yellow" + +/area/construction/qmaint + name = "Maintenance" + icon_state = "yellow" + +/area/construction/hallway + name = "Hallway" + icon_state = "yellow" + +/area/construction/solars + name = "Solar Panels" + icon_state = "yellow" + +/area/construction/solarscontrol + name = "Solar Panel Control" + icon_state = "yellow" + +/area/construction/storage + name = "Construction Site Storage" + icon_state = "yellow" + +/area/construction/storage/wing + name = "Storage Wing" + icon_state = "storage_wing" + + +//AI + +/area/ai_monitored/security/armory + name = "Armory" + icon_state = "armory" + ambientsounds = HIGHSEC + +/area/ai_monitored/storage/eva + name = "EVA Storage" + icon_state = "eva" + ambientsounds = HIGHSEC + +/area/ai_monitored/storage/satellite + name = "AI Satellite Maint" + icon_state = "storage" + ambientsounds = HIGHSEC + + //Turret_protected + +/area/ai_monitored/turret_protected + ambientsounds = list('sound/ambience/ambimalf.ogg', 'sound/ambience/ambitech.ogg', 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambiatmos.ogg', 'sound/ambience/ambiatmos2.ogg') + +/area/ai_monitored/turret_protected/ai_upload + name = "AI Upload Chamber" + icon_state = "ai_upload" + +/area/ai_monitored/turret_protected/ai_upload_foyer + name = "AI Upload Access" + icon_state = "ai_foyer" + +/area/ai_monitored/turret_protected/ai + name = "AI Chamber" + icon_state = "ai_chamber" + +/area/ai_monitored/turret_protected/aisat + name = "AI Satellite" + icon_state = "ai" + +/area/ai_monitored/turret_protected/aisat/atmos + name = "AI Satellite Atmos" + icon_state = "ai" + +/area/ai_monitored/turret_protected/aisat/foyer + name = "AI Satellite Foyer" + icon_state = "ai" + +/area/ai_monitored/turret_protected/aisat/service + name = "AI Satellite Service" + icon_state = "ai" + +/area/ai_monitored/turret_protected/aisat/hallway + name = "AI Satellite Hallway" + icon_state = "ai" + +/area/aisat + name = "AI Satellite Exterior" + icon_state = "yellow" + +/area/ai_monitored/turret_protected/aisat_interior + name = "AI Satellite Antechamber" + icon_state = "ai" + +/area/ai_monitored/turret_protected/AIsatextFP + name = "AI Sat Ext" + icon_state = "storage" + +/area/ai_monitored/turret_protected/AIsatextFS + name = "AI Sat Ext" + icon_state = "storage" + +/area/ai_monitored/turret_protected/AIsatextAS + name = "AI Sat Ext" + icon_state = "storage" + +/area/ai_monitored/turret_protected/AIsatextAP + name = "AI Sat Ext" + icon_state = "storage" + + +// Telecommunications Satellite + +/area/tcommsat + clockwork_warp_allowed = FALSE + clockwork_warp_fail = "For safety reasons, warping here is disallowed; the radio and bluespace noise could cause catastrophic results." + ambientsounds = list('sound/ambience/ambisin2.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/signal.ogg', 'sound/ambience/ambigen10.ogg', 'sound/ambience/ambitech.ogg',\ + 'sound/ambience/ambitech2.ogg', 'sound/ambience/ambitech3.ogg', 'sound/ambience/ambimystery.ogg') + +/area/tcommsat/entrance + name = "Telecomms Teleporter" + icon_state = "tcomsatentrance" + +/area/tcommsat/chamber + name = "Abandoned Satellite" + icon_state = "tcomsatcham" + +/area/ai_monitored/turret_protected/tcomsat + name = "Telecomms Satellite" + icon_state = "tcomsatlob" + +/area/ai_monitored/turret_protected/tcomfoyer + name = "Telecomms Foyer" + icon_state = "tcomsatentrance" + +/area/ai_monitored/turret_protected/tcomwest + name = "Telecommunications Satellite West Wing" + icon_state = "tcomsatwest" + +/area/ai_monitored/turret_protected/tcomeast + name = "Telecommunications Satellite East Wing" + icon_state = "tcomsateast" + +/area/tcommsat/computer + name = "Telecomms Control Room" + icon_state = "tcomsatcomp" + +/area/tcommsat/server + name = "Telecomms Server Room" + icon_state = "tcomsatcham" + +/area/tcommsat/lounge + name = "Telecommunications Satellite Lounge" + icon_state = "tcomsatlounge" diff --git a/code/game/area/ai_monitored.dm b/code/game/area/ai_monitored.dm index 9d42b67bf9..87b44291f5 100644 --- a/code/game/area/ai_monitored.dm +++ b/code/game/area/ai_monitored.dm @@ -1,31 +1,31 @@ -/area/ai_monitored - name = "AI Monitored Area" - clockwork_warp_allowed = FALSE - var/list/obj/machinery/camera/motioncameras = list() - var/list/datum/weakref/motionTargets = list() - -/area/ai_monitored/Initialize(mapload) - . = ..() - if(mapload) - for (var/obj/machinery/camera/M in src) - if(M.isMotion()) - motioncameras.Add(M) - M.area_motion = src - -//Only need to use one camera - -/area/ai_monitored/Entered(atom/movable/O) - ..() - if (ismob(O) && motioncameras.len) - for(var/X in motioncameras) - var/obj/machinery/camera/cam = X - cam.newTarget(O) - return - -/area/ai_monitored/Exited(atom/movable/O) - ..() - if (ismob(O) && motioncameras.len) - for(var/X in motioncameras) - var/obj/machinery/camera/cam = X - cam.lostTargetRef(WEAKREF(O)) +/area/ai_monitored + name = "AI Monitored Area" + clockwork_warp_allowed = FALSE + var/list/obj/machinery/camera/motioncameras = list() + var/list/datum/weakref/motionTargets = list() + +/area/ai_monitored/Initialize(mapload) + . = ..() + if(mapload) + for (var/obj/machinery/camera/M in src) + if(M.isMotion()) + motioncameras.Add(M) + M.area_motion = src + +//Only need to use one camera + +/area/ai_monitored/Entered(atom/movable/O) + ..() + if (ismob(O) && motioncameras.len) + for(var/X in motioncameras) + var/obj/machinery/camera/cam = X + cam.newTarget(O) + return + +/area/ai_monitored/Exited(atom/movable/O) + ..() + if (ismob(O) && motioncameras.len) + for(var/X in motioncameras) + var/obj/machinery/camera/cam = X + cam.lostTargetRef(WEAKREF(O)) return \ No newline at end of file diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 36b701aae1..9a6d992991 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -1,866 +1,866 @@ -/atom - layer = TURF_LAYER - plane = GAME_PLANE - var/level = 2 - var/article // If non-null, overrides a/an/some in all cases - - var/flags_1 = NONE - var/interaction_flags_atom = NONE - var/datum/reagents/reagents = null - - //This atom's HUD (med/sec, etc) images. Associative list. - var/list/image/hud_list = null - //HUD images that this atom can provide. - var/list/hud_possible - - //Value used to increment ex_act() if reactionary_explosions is on - var/explosion_block = 0 - - var/list/atom_colours //used to store the different colors on an atom - //its inherent color, the colored paint applied on it, special color effect etc... - - var/list/priority_overlays //overlays that should remain on top and not normally removed when using cut_overlay functions, like c4. - var/list/remove_overlays // a very temporary list of overlays to remove - var/list/add_overlays // a very temporary list of overlays to add - - var/list/managed_vis_overlays //vis overlays managed by SSvis_overlays to automaticaly turn them like other overlays - ///overlays managed by update_overlays() to prevent removing overlays that weren't added by the same proc - var/list/managed_overlays - - var/datum/proximity_monitor/proximity_monitor - var/buckle_message_cooldown = 0 - var/fingerprintslast - - var/list/filter_data //For handling persistent filters - - var/datum/component/orbiter/orbiters - - var/rad_flags = NONE // Will move to flags_1 when i can be arsed to - var/rad_insulation = RAD_NO_INSULATION - - var/icon/blood_splatter_icon - var/list/fingerprints - var/list/fingerprintshidden - var/list/blood_DNA - var/list/suit_fibers - -/atom/New(loc, ...) - //atom creation method that preloads variables at creation - if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New() - world.preloader_load(src) - - if(datum_flags & DF_USE_TAG) - GenerateTag() - - var/do_initialize = SSatoms.initialized - if(do_initialize != INITIALIZATION_INSSATOMS) - args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD - if(SSatoms.InitAtom(src, args)) - //we were deleted - return - -//Called after New if the map is being loaded. mapload = TRUE -//Called from base of New if the map is not being loaded. mapload = FALSE -//This base must be called or derivatives must set initialized to TRUE -//must not sleep -//Other parameters are passed from New (excluding loc), this does not happen if mapload is TRUE -//Must return an Initialize hint. Defined in __DEFINES/subsystems.dm - -//Note: the following functions don't call the base for optimization and must copypasta: -// /turf/Initialize -// /turf/open/space/Initialize - -/atom/proc/Initialize(mapload, ...) - if(flags_1 & INITIALIZED_1) - stack_trace("Warning: [src]([type]) initialized multiple times!") - flags_1 |= INITIALIZED_1 - - //atom color stuff - if(color) - add_atom_colour(color, FIXED_COLOUR_PRIORITY) - - if (light_power && light_range) - update_light() - - if (opacity && isturf(loc)) - var/turf/T = loc - T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guaranteed to be on afterwards anyways. - - if (canSmoothWith) - canSmoothWith = typelist("canSmoothWith", canSmoothWith) - - ComponentInitialize() - - return INITIALIZE_HINT_NORMAL - -//called if Initialize returns INITIALIZE_HINT_LATELOAD -/atom/proc/LateInitialize() - return - -// Put your AddComponent() calls here -/atom/proc/ComponentInitialize() - return - -/atom/Destroy() - if(alternate_appearances) - for(var/K in alternate_appearances) - var/datum/atom_hud/alternate_appearance/AA = alternate_appearances[K] - AA.remove_from_hud(src) - - if(reagents) - qdel(reagents) - - LAZYCLEARLIST(overlays) - LAZYCLEARLIST(priority_overlays) - - QDEL_NULL(light) - - return ..() - -/atom/proc/handle_ricochet(obj/item/projectile/P) - return - -/atom/proc/CanPass(atom/movable/mover, turf/target) - return !density - -/atom/proc/onCentCom() - var/turf/T = get_turf(src) - if(!T) - return FALSE - - if(is_reserved_level(T.z)) - for(var/A in SSshuttle.mobile) - var/obj/docking_port/mobile/M = A - if(M.launch_status == ENDGAME_TRANSIT) - for(var/place in M.shuttle_areas) - var/area/shuttle/shuttle_area = place - if(T in shuttle_area) - return TRUE - - if(!is_centcom_level(T.z))//if not, don't bother - return FALSE - - //Check for centcom itself - if(istype(T.loc, /area/centcom)) - return TRUE - - //Check for centcom shuttles - for(var/A in SSshuttle.mobile) - var/obj/docking_port/mobile/M = A - if(M.launch_status == ENDGAME_LAUNCHED) - for(var/place in M.shuttle_areas) - var/area/shuttle/shuttle_area = place - if(T in shuttle_area) - return TRUE - -/atom/proc/onSyndieBase() - var/turf/T = get_turf(src) - if(!T) - return FALSE - - if(!is_centcom_level(T.z))//if not, don't bother - return FALSE - - if(istype(T.loc, /area/shuttle/syndicate) || istype(T.loc, /area/syndicate_mothership) || istype(T.loc, /area/shuttle/assault_pod)) - return TRUE - - return FALSE - -/atom/proc/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) - SEND_SIGNAL(src, COMSIG_ATOM_HULK_ATTACK, user) - if(does_attack_animation) - user.changeNext_move(CLICK_CD_MELEE) - log_combat(user, src, "punched", "hulk powers") - user.do_attack_animation(src, ATTACK_EFFECT_SMASH) - -/atom/proc/CheckParts(list/parts_list) - for(var/A in parts_list) - if(istype(A, /datum/reagent)) - if(!reagents) - reagents = new() - reagents.reagent_list.Add(A) - reagents.conditional_update() - else if(ismovableatom(A)) - var/atom/movable/M = A - if(isliving(M.loc)) - var/mob/living/L = M.loc - L.transferItemToLoc(M, src) - else - M.forceMove(src) - -//common name -/atom/proc/update_multiz(prune_on_fail = FALSE) - return FALSE - -/atom/proc/assume_air(datum/gas_mixture/giver) - qdel(giver) - return null - -/atom/proc/remove_air(amount) - return null - -/atom/proc/return_air() - if(loc) - return loc.return_air() - else - return null - -/atom/proc/check_eye(mob/user) - return - -/atom/proc/Bumped(atom/movable/AM) - set waitfor = FALSE - -// Convenience procs to see if a container is open for chemistry handling -/atom/proc/is_open_container() - return is_refillable() && is_drainable() - -/atom/proc/is_injectable(allowmobs = TRUE) - return reagents && (reagents.reagents_holder_flags & (INJECTABLE | REFILLABLE)) - -/atom/proc/is_drawable(allowmobs = TRUE) - return reagents && (reagents.reagents_holder_flags & (DRAWABLE | DRAINABLE)) - -/atom/proc/is_refillable() - return reagents && (reagents.reagents_holder_flags & REFILLABLE) - -/atom/proc/is_drainable() - return reagents && (reagents.reagents_holder_flags & DRAINABLE) - - -/atom/proc/AllowDrop() - return FALSE - -/atom/proc/CheckExit() - return TRUE - -/atom/proc/HasProximity(atom/movable/AM as mob|obj) - return - -/atom/proc/emp_act(severity) - var/protection = SEND_SIGNAL(src, COMSIG_ATOM_EMP_ACT, severity) - if(!(protection & EMP_PROTECT_WIRES) && istype(wires)) - wires.emp_pulse() - return protection // Pass the protection value collected here upwards - -/atom/proc/bullet_act(obj/item/projectile/P, def_zone) - SEND_SIGNAL(src, COMSIG_ATOM_BULLET_ACT, P, def_zone) - . = P.on_hit(src, 0, def_zone) - -//used on altdisarm() for special interactions between the shoved victim (target) and the src, with user being the one shoving the target on it. -// IMPORTANT: if you wish to add a new own shove_act() to a certain object, remember to add SHOVABLE_ONTO to its obj_flags bitfied var first. -/atom/proc/shove_act(mob/living/target, mob/living/user) - return FALSE - -/atom/proc/in_contents_of(container)//can take class or object instance as argument - if(ispath(container)) - if(istype(src.loc, container)) - return TRUE - else if(src in container) - return TRUE - return FALSE - -/atom/proc/get_examine_name(mob/user) - . = "\a [src]" - var/list/override = list(gender == PLURAL ? "some" : "a", " ", "[name]") - if(article) - . = "[article] [src]" - override[EXAMINE_POSITION_ARTICLE] = article - - var/should_override = FALSE - - if(SEND_SIGNAL(src, COMSIG_ATOM_GET_EXAMINE_NAME, user, override) & COMPONENT_EXNAME_CHANGED) - should_override = TRUE - - - if(blood_DNA && !istype(src, /obj/effect/decal)) - override[EXAMINE_POSITION_BEFORE] = " blood-stained " - should_override = TRUE - - if(should_override) - . = override.Join("") - -///Generate the full examine string of this atom (including icon for goonchat) -/atom/proc/get_examine_string(mob/user, thats = FALSE) - return "[icon2html(src, user)] [thats? "That's ":""][get_examine_name(user)]" - -/atom/proc/examine(mob/user) - . = list("[get_examine_string(user, TRUE)].") - - if(desc) - . += desc - - if(reagents) - if(reagents.reagents_holder_flags & TRANSPARENT) - . += "It contains:" - if(length(reagents.reagent_list)) - if(user.can_see_reagents()) //Show each individual reagent - for(var/datum/reagent/R in reagents.reagent_list) - . += "[R.volume] units of [R.name]" - else //Otherwise, just show the total volume - var/total_volume = 0 - for(var/datum/reagent/R in reagents.reagent_list) - total_volume += R.volume - . += "[total_volume] units of various reagents" - else - . += "Nothing." - else if(reagents.reagents_holder_flags & AMOUNT_VISIBLE) - if(reagents.total_volume) - . += "It has [reagents.total_volume] unit\s left." - else - . += "It's empty." - - SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) - -/// Updates the icon of the atom -/atom/proc/update_icon() - // I expect we're going to need more return flags and options in this proc - var/signalOut = SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_ICON) - - if(!(signalOut & COMSIG_ATOM_NO_UPDATE_ICON_STATE)) - update_icon_state() - - if(!(signalOut & COMSIG_ATOM_NO_UPDATE_OVERLAYS)) - var/list/new_overlays = update_overlays() - if(managed_overlays) - cut_overlay(managed_overlays) - managed_overlays = null - if(length(new_overlays)) - managed_overlays = new_overlays - add_overlay(new_overlays) - -/// Updates the icon state of the atom -/atom/proc/update_icon_state() - -/// Updates the overlays of the atom -/atom/proc/update_overlays() - SHOULD_CALL_PARENT(1) - . = list() - SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_OVERLAYS, .) - -/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) - return //For handling the effects of explosions on contents that would not normally be effected - -/atom/proc/ex_act(severity, target) - set waitfor = FALSE - contents_explosion(severity, target) - SEND_SIGNAL(src, COMSIG_ATOM_EX_ACT, severity, target) - -/atom/proc/blob_act(obj/structure/blob/B) - SEND_SIGNAL(src, COMSIG_ATOM_BLOB_ACT, B) - return - -/atom/proc/fire_act(exposed_temperature, exposed_volume) - SEND_SIGNAL(src, COMSIG_ATOM_FIRE_ACT, exposed_temperature, exposed_volume) - return - -/atom/proc/hitby(atom/movable/AM, skipcatch, hitpush, blocked) - if(density && !has_gravity(AM)) //thrown stuff bounces off dense stuff in no grav, unless the thrown stuff ends up inside what it hit(embedding, bola, etc...). - addtimer(CALLBACK(src, .proc/hitby_react, AM), 2) - -/atom/proc/hitby_react(atom/movable/AM) - if(AM && isturf(AM.loc)) - step(AM, turn(AM.dir, 180)) - -/atom/proc/handle_slip(mob/living/carbon/C, knockdown_amount, obj/O, lube) - return - -//returns the mob's dna info as a list, to be inserted in an object's blood_DNA list -/mob/living/proc/get_blood_dna_list() - var/blood_id = get_blood_id() - if(!(blood_id =="blood" || blood_id == "jellyblood")) - return - return list("ANIMAL DNA" = "Y-") - -/mob/living/carbon/get_blood_dna_list() - var/blood_id = get_blood_id() - if(!(blood_id =="blood" || blood_id == "jellyblood")) - return - var/list/blood_dna = list() - if(dna) - blood_dna[dna.unique_enzymes] = dna.blood_type - else - blood_dna["UNKNOWN DNA"] = "X*" - return blood_dna - -/mob/living/carbon/alien/get_blood_dna_list() - return list("UNKNOWN DNA" = "X*") - -//to add a mob's dna info into an object's blood_DNA list. -/atom/proc/transfer_mob_blood_dna(mob/living/L) - // Returns 0 if we have that blood already - var/new_blood_dna = L.get_blood_dna_list() - if(!new_blood_dna) - return FALSE - LAZYINITLIST(blood_DNA) //if our list of DNA doesn't exist yet, initialise it. - var/old_length = blood_DNA.len - blood_DNA |= new_blood_dna - if(blood_DNA.len == old_length) - return FALSE - return TRUE - -//to add blood dna info to the object's blood_DNA list -/atom/proc/transfer_blood_dna(list/blood_dna, list/datum/disease/diseases) - LAZYINITLIST(blood_DNA) - var/old_length = blood_DNA.len - blood_DNA |= blood_dna - if(blood_DNA.len > old_length) - return TRUE - //some new blood DNA was added - -//to add blood from a mob onto something, and transfer their dna info -/atom/proc/add_mob_blood(mob/living/M) - var/list/blood_dna = M.get_blood_dna_list() - if(!blood_dna) - return FALSE - return add_blood_DNA(blood_dna, M.diseases) - -//to add blood onto something, with blood dna info to include. -/atom/proc/add_blood_DNA(list/blood_dna, list/datum/disease/diseases) - return FALSE - -/obj/add_blood_DNA(list/blood_dna, list/datum/disease/diseases) - return transfer_blood_dna(blood_dna, diseases) - -/obj/item/add_blood_DNA(list/blood_dna, list/datum/disease/diseases) - . = ..() - if(!.) - return - add_blood_overlay() - -/obj/item/proc/add_blood_overlay() - if(!blood_DNA.len) - return - if(initial(icon) && initial(icon_state)) - blood_splatter_icon = icon(initial(icon), initial(icon_state), , 1) //we only want to apply blood-splatters to the initial icon_state for each object - blood_splatter_icon.Blend("#fff", ICON_ADD) //fills the icon_state with white (except where it's transparent) - blood_splatter_icon.Blend(icon('icons/effects/blood.dmi', "itemblood"), ICON_MULTIPLY) //adds blood and the remaining white areas become transparant - blood_splatter_icon.Blend(blood_DNA_to_color(), ICON_MULTIPLY) - add_overlay(blood_splatter_icon) - -/obj/item/clothing/gloves/add_blood_DNA(list/blood_dna, list/datum/disease/diseases) - . = ..() - transfer_blood = rand(2, 4) - -/turf/add_blood_DNA(list/blood_dna, list/datum/disease/diseases) - var/obj/effect/decal/cleanable/blood/splatter/B = locate() in src - if(!B) - B = new /obj/effect/decal/cleanable/blood/splatter(src, diseases) - B.transfer_blood_dna(blood_dna, diseases) //give blood info to the blood decal. - return TRUE //we bloodied the floor - -/mob/living/carbon/human/add_blood_DNA(list/blood_dna, list/datum/disease/diseases) - if(head) - head.add_blood_DNA(blood_dna, diseases) - update_inv_head() - else if(wear_mask) - wear_mask.add_blood_DNA(blood_dna, diseases) - update_inv_wear_mask() - if(wear_neck) - wear_neck.add_blood_DNA(blood_dna, diseases) - update_inv_neck() - if(wear_suit) - wear_suit.add_blood_DNA(blood_dna, diseases) - update_inv_wear_suit() - else if(w_uniform) - w_uniform.add_blood_DNA(blood_dna, diseases) - update_inv_w_uniform() - if(gloves) - var/obj/item/clothing/gloves/G = gloves - G.add_blood_DNA(blood_dna, diseases) - else - transfer_blood_dna(blood_dna, diseases) - bloody_hands = rand(2, 4) - update_inv_gloves() //handles bloody hands overlays and updating - return TRUE - -/atom/proc/blood_DNA_to_color() - var/list/colors = list()//first we make a list of all bloodtypes present - for(var/bloop in blood_DNA) - if(colors[blood_DNA[bloop]]) - colors[blood_DNA[bloop]]++ - else - colors[blood_DNA[bloop]] = 1 - - var/final_rgb = BLOOD_COLOR_HUMAN //a default so we don't have white blood graphics if something messed up - - if(colors.len) - var/sum = 0 //this is all shitcode, but it works; trust me - final_rgb = bloodtype_to_color(colors[1]) - sum = colors[colors[1]] - if(colors.len > 1) - var/i = 2 - while(i <= colors.len) - var/tmp = colors[colors[i]] - final_rgb = BlendRGB(final_rgb, bloodtype_to_color(colors[i]), tmp/(tmp+sum)) - sum += tmp - i++ - - return final_rgb - -/atom/proc/clean_blood() - if(islist(blood_DNA)) - blood_DNA = null - return TRUE - -/atom/proc/wash_cream() - return TRUE - -/atom/proc/isinspace() - if(isspaceturf(get_turf(src))) - return TRUE - else - return FALSE - -/atom/proc/handle_fall() - return - -/atom/proc/singularity_act() - return - -/atom/proc/singularity_pull(obj/singularity/S, current_size) - SEND_SIGNAL(src, COMSIG_ATOM_SING_PULL, S, current_size) - -/atom/proc/acid_act(acidpwr, acid_volume) - SEND_SIGNAL(src, COMSIG_ATOM_ACID_ACT, acidpwr, acid_volume) - -/atom/proc/emag_act() - return SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT) - -/atom/proc/rad_act(strength) - SEND_SIGNAL(src, COMSIG_ATOM_RAD_ACT, strength) - -/atom/proc/narsie_act() - SEND_SIGNAL(src, COMSIG_ATOM_NARSIE_ACT) - -/atom/proc/ratvar_act() - SEND_SIGNAL(src, COMSIG_ATOM_RATVAR_ACT) - -/atom/proc/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) - return FALSE - -/atom/proc/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - SEND_SIGNAL(src, COMSIG_ATOM_RCD_ACT, user, the_rcd, passed_mode) - return FALSE - -/atom/proc/storage_contents_dump_act(obj/item/storage/src_object, mob/user) - if(GetComponent(/datum/component/storage)) - return component_storage_contents_dump_act(src_object, user) - return FALSE - -/atom/proc/component_storage_contents_dump_act(datum/component/storage/src_object, mob/user) - var/list/things = src_object.contents() - var/datum/progressbar/progress = new(user, things.len, src) - var/datum/component/storage/STR = GetComponent(/datum/component/storage) - while (do_after(user, 10, TRUE, src, FALSE, CALLBACK(STR, /datum/component/storage.proc/handle_mass_item_insertion, things, src_object, user, progress))) - stoplag(1) - qdel(progress) - to_chat(user, "You dump as much of [src_object.parent]'s contents into [STR.insert_preposition]to [src] as you can.") - STR.orient2hud(user) - src_object.orient2hud(user) - if(user.active_storage) //refresh the HUD to show the transfered contents - user.active_storage.close(user) - user.active_storage.show_to(user) - return TRUE - -/atom/proc/get_dumping_location(obj/item/storage/source,mob/user) - return null - -//This proc is called on the location of an atom when the atom is Destroy()'d -/atom/proc/handle_atom_del(atom/A) - SEND_SIGNAL(src, COMSIG_ATOM_CONTENTS_DEL, A) - -//called when the turf the atom resides on is ChangeTurfed -/atom/proc/HandleTurfChange(turf/T) - for(var/a in src) - var/atom/A = a - A.HandleTurfChange(T) - -//the vision impairment to give to the mob whose perspective is set to that atom (e.g. an unfocused camera giving you an impaired vision when looking through it) -/atom/proc/get_remote_view_fullscreens(mob/user) - return - -//the sight changes to give to the mob whose perspective is set to that atom (e.g. A mob with nightvision loses its nightvision while looking through a normal camera) -/atom/proc/update_remote_sight(mob/living/user) - return - - -//Hook for running code when a dir change occurs -/atom/proc/setDir(newdir, ismousemovement=FALSE) - SEND_SIGNAL(src, COMSIG_ATOM_DIR_CHANGE, dir, newdir) - dir = newdir - -/atom/proc/mech_melee_attack(obj/mecha/M) - return - -//If a mob logouts/logins in side of an object you can use this proc -/atom/proc/on_log(login) - if(loc) - loc.on_log(login) - - -/* - Atom Colour Priority System - A System that gives finer control over which atom colour to colour the atom with. - The "highest priority" one is always displayed as opposed to the default of - "whichever was set last is displayed" -*/ - - -/* - Adds an instance of colour_type to the atom's atom_colours list -*/ -/atom/proc/add_atom_colour(coloration, colour_priority) - if(!atom_colours || !atom_colours.len) - atom_colours = list() - atom_colours.len = COLOUR_PRIORITY_AMOUNT //four priority levels currently. - if(!coloration) - return - if(colour_priority > atom_colours.len) - return - atom_colours[colour_priority] = coloration - update_atom_colour() - - -/* - Removes an instance of colour_type from the atom's atom_colours list -*/ -/atom/proc/remove_atom_colour(colour_priority, coloration) - if(!atom_colours) - atom_colours = list() - atom_colours.len = COLOUR_PRIORITY_AMOUNT //four priority levels currently. - if(colour_priority > atom_colours.len) - return - if(coloration && atom_colours[colour_priority] != coloration) - return //if we don't have the expected color (for a specific priority) to remove, do nothing - atom_colours[colour_priority] = null - update_atom_colour() - - -/* - Resets the atom's color to null, and then sets it to the highest priority - colour available -*/ -/atom/proc/update_atom_colour() - if(!atom_colours) - atom_colours = list() - atom_colours.len = COLOUR_PRIORITY_AMOUNT //four priority levels currently. - color = null - for(var/C in atom_colours) - if(islist(C)) - var/list/L = C - if(L.len) - color = L - return - else if(C) - color = C - return - -/atom/vv_edit_var(var_name, var_value) - if(!GLOB.Debug2) - flags_1 |= ADMIN_SPAWNED_1 - . = ..() - switch(var_name) - if("color") - add_atom_colour(color, ADMIN_COLOUR_PRIORITY) - -/atom/vv_get_dropdown() - . = ..() - . += "---" - var/turf/curturf = get_turf(src) - if (curturf) - .["Jump to"] = "?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[curturf.x];Y=[curturf.y];Z=[curturf.z]" - .["Modify Transform"] = "?_src_=vars;[HrefToken()];modtransform=[REF(src)]" - .["Add reagent"] = "?_src_=vars;[HrefToken()];addreagent=[REF(src)]" - .["Trigger EM pulse"] = "?_src_=vars;[HrefToken()];emp=[REF(src)]" - .["Trigger explosion"] = "?_src_=vars;[HrefToken()];explode=[REF(src)]" - -/atom/proc/drop_location() - var/atom/L = loc - if(!L) - return null - return L.AllowDrop() ? L : L.drop_location() - -/atom/Entered(atom/movable/AM, atom/oldLoc) - SEND_SIGNAL(src, COMSIG_ATOM_ENTERED, AM, oldLoc) - -/atom/Exit(atom/movable/AM, atom/newLoc) - . = ..() - if(SEND_SIGNAL(src, COMSIG_ATOM_EXIT, AM, newLoc) & COMPONENT_ATOM_BLOCK_EXIT) - return FALSE - -/atom/Exited(atom/movable/AM, atom/newLoc) - SEND_SIGNAL(src, COMSIG_ATOM_EXITED, AM, newLoc) - -/atom/proc/return_temperature() - return - -// Tool behavior procedure. Redirects to tool-specific procs by default. -// You can override it to catch all tool interactions, for use in complex deconstruction procs. -// Just don't forget to return ..() in the end. -/atom/proc/tool_act(mob/living/user, obj/item/I, tool_type) - switch(tool_type) - if(TOOL_CROWBAR) - return crowbar_act(user, I) - if(TOOL_MULTITOOL) - return multitool_act(user, I) - if(TOOL_SCREWDRIVER) - return screwdriver_act(user, I) - if(TOOL_WRENCH) - return wrench_act(user, I) - if(TOOL_WIRECUTTER) - return wirecutter_act(user, I) - if(TOOL_WELDER) - return welder_act(user, I) - if(TOOL_ANALYZER) - return analyzer_act(user, I) - -// Tool-specific behavior procs. To be overridden in subtypes. -/atom/proc/crowbar_act(mob/living/user, obj/item/I) - return - -/atom/proc/multitool_act(mob/living/user, obj/item/I) - return - -/atom/proc/screwdriver_act(mob/living/user, obj/item/I) - SEND_SIGNAL(src, COMSIG_ATOM_SCREWDRIVER_ACT, user, I) - -/atom/proc/wrench_act(mob/living/user, obj/item/I) - return - -/atom/proc/wirecutter_act(mob/living/user, obj/item/I) - return - -/atom/proc/welder_act(mob/living/user, obj/item/I) - return - -/atom/proc/analyzer_act(mob/living/user, obj/item/I) - return - -/atom/proc/GenerateTag() - return - -// Generic logging helper -/atom/proc/log_message(message, message_type, color=null, log_globally=TRUE) - if(!log_globally) - return - - var/log_text = "[key_name(src)] [message] [loc_name(src)]" - switch(message_type) - if(LOG_ATTACK) - log_attack(log_text) - if(LOG_SAY) - log_say(log_text) - if(LOG_WHISPER) - log_whisper(log_text) - if(LOG_EMOTE) - log_emote(log_text) - if(LOG_DSAY) - log_dsay(log_text) - if(LOG_PDA) - log_pda(log_text) - if(LOG_CHAT) - log_chat(log_text) - if(LOG_COMMENT) - log_comment(log_text) - if(LOG_TELECOMMS) - log_telecomms(log_text) - if(LOG_OOC) - log_ooc(log_text) - if(LOG_ADMIN) - log_admin(log_text) - if(LOG_ADMIN_PRIVATE) - log_admin_private(log_text) - if(LOG_ASAY) - log_adminsay(log_text) - if(LOG_OWNERSHIP) - log_game(log_text) - if(LOG_GAME) - log_game(log_text) - else - stack_trace("Invalid individual logging type: [message_type]. Defaulting to [LOG_GAME] (LOG_GAME).") - log_game(log_text) - -// Helper for logging chat messages or other logs with arbitrary inputs (e.g. announcements) -/atom/proc/log_talk(message, message_type, tag=null, log_globally=TRUE, forced_by=null) - var/prefix = tag ? "([tag]) " : "" - var/suffix = forced_by ? " FORCED by [forced_by]" : "" - log_message("[prefix]\"[message]\"[suffix]", message_type, log_globally=log_globally) - -// Helper for logging of messages with only one sender and receiver -/proc/log_directed_talk(atom/source, atom/target, message, message_type, tag) - if(!tag) - stack_trace("Unspecified tag for private message") - tag = "UNKNOWN" - - source.log_talk(message, message_type, tag="[tag] to [key_name(target)]") - if(source != target) - target.log_talk(message, message_type, tag="[tag] from [key_name(source)]", log_globally=FALSE) - -/* -Proc for attack log creation, because really why not -1 argument is the actor performing the action -2 argument is the target of the action -3 is a verb describing the action (e.g. punched, throwed, kicked, etc.) -4 is a tool with which the action was made (usually an item) -5 is any additional text, which will be appended to the rest of the log line -*/ - -/proc/log_combat(atom/user, atom/target, what_done, atom/object=null, addition=null) - var/ssource = key_name(user) - var/starget = key_name(target) - - var/mob/living/living_target = target - var/hp = istype(living_target) ? " (NEWHP: [living_target.health]) " : "" - - var/sobject = "" - if(object) - sobject = " with [key_name(object)]" - var/saddition = "" - if(addition) - saddition = " [addition]" - - var/postfix = "[sobject][saddition][hp]" - - var/message = "has [what_done] [starget][postfix]" - user.log_message(message, LOG_ATTACK, color="red") - - if(user != target) - var/reverse_message = "has been [what_done] by [ssource][postfix]" - target.log_message(reverse_message, LOG_ATTACK, color="orange", log_globally=FALSE) - -// Filter stuff -/atom/movable/proc/add_filter(name,priority,list/params) - LAZYINITLIST(filter_data) - var/list/p = params.Copy() - p["priority"] = priority - filter_data[name] = p - update_filters() - -/atom/movable/proc/update_filters() - filters = null - filter_data = sortTim(filter_data, /proc/cmp_filter_data_priority, TRUE) - for(var/f in filter_data) - var/list/data = filter_data[f] - var/list/arguments = data.Copy() - arguments -= "priority" - filters += filter(arglist(arguments)) - -/atom/movable/proc/get_filter(name) - if(filter_data && filter_data[name]) - return filters[filter_data.Find(name)] - -/atom/movable/proc/remove_filter(name) - if(filter_data && filter_data[name]) - filter_data -= name - update_filters() - return TRUE - -/atom/proc/intercept_zImpact(atom/movable/AM, levels = 1) +/atom + layer = TURF_LAYER + plane = GAME_PLANE + var/level = 2 + var/article // If non-null, overrides a/an/some in all cases + + var/flags_1 = NONE + var/interaction_flags_atom = NONE + var/datum/reagents/reagents = null + + //This atom's HUD (med/sec, etc) images. Associative list. + var/list/image/hud_list = null + //HUD images that this atom can provide. + var/list/hud_possible + + //Value used to increment ex_act() if reactionary_explosions is on + var/explosion_block = 0 + + var/list/atom_colours //used to store the different colors on an atom + //its inherent color, the colored paint applied on it, special color effect etc... + + var/list/priority_overlays //overlays that should remain on top and not normally removed when using cut_overlay functions, like c4. + var/list/remove_overlays // a very temporary list of overlays to remove + var/list/add_overlays // a very temporary list of overlays to add + + var/list/managed_vis_overlays //vis overlays managed by SSvis_overlays to automaticaly turn them like other overlays + ///overlays managed by update_overlays() to prevent removing overlays that weren't added by the same proc + var/list/managed_overlays + + var/datum/proximity_monitor/proximity_monitor + var/buckle_message_cooldown = 0 + var/fingerprintslast + + var/list/filter_data //For handling persistent filters + + var/datum/component/orbiter/orbiters + + var/rad_flags = NONE // Will move to flags_1 when i can be arsed to + var/rad_insulation = RAD_NO_INSULATION + + var/icon/blood_splatter_icon + var/list/fingerprints + var/list/fingerprintshidden + var/list/blood_DNA + var/list/suit_fibers + +/atom/New(loc, ...) + //atom creation method that preloads variables at creation + if(GLOB.use_preloader && (src.type == GLOB._preloader.target_path))//in case the instanciated atom is creating other atoms in New() + world.preloader_load(src) + + if(datum_flags & DF_USE_TAG) + GenerateTag() + + var/do_initialize = SSatoms.initialized + if(do_initialize != INITIALIZATION_INSSATOMS) + args[1] = do_initialize == INITIALIZATION_INNEW_MAPLOAD + if(SSatoms.InitAtom(src, args)) + //we were deleted + return + +//Called after New if the map is being loaded. mapload = TRUE +//Called from base of New if the map is not being loaded. mapload = FALSE +//This base must be called or derivatives must set initialized to TRUE +//must not sleep +//Other parameters are passed from New (excluding loc), this does not happen if mapload is TRUE +//Must return an Initialize hint. Defined in __DEFINES/subsystems.dm + +//Note: the following functions don't call the base for optimization and must copypasta: +// /turf/Initialize +// /turf/open/space/Initialize + +/atom/proc/Initialize(mapload, ...) + if(flags_1 & INITIALIZED_1) + stack_trace("Warning: [src]([type]) initialized multiple times!") + flags_1 |= INITIALIZED_1 + + //atom color stuff + if(color) + add_atom_colour(color, FIXED_COLOUR_PRIORITY) + + if (light_power && light_range) + update_light() + + if (opacity && isturf(loc)) + var/turf/T = loc + T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guaranteed to be on afterwards anyways. + + if (canSmoothWith) + canSmoothWith = typelist("canSmoothWith", canSmoothWith) + + ComponentInitialize() + + return INITIALIZE_HINT_NORMAL + +//called if Initialize returns INITIALIZE_HINT_LATELOAD +/atom/proc/LateInitialize() + return + +// Put your AddComponent() calls here +/atom/proc/ComponentInitialize() + return + +/atom/Destroy() + if(alternate_appearances) + for(var/K in alternate_appearances) + var/datum/atom_hud/alternate_appearance/AA = alternate_appearances[K] + AA.remove_from_hud(src) + + if(reagents) + qdel(reagents) + + LAZYCLEARLIST(overlays) + LAZYCLEARLIST(priority_overlays) + + QDEL_NULL(light) + + return ..() + +/atom/proc/handle_ricochet(obj/item/projectile/P) + return + +/atom/proc/CanPass(atom/movable/mover, turf/target) + return !density + +/atom/proc/onCentCom() + var/turf/T = get_turf(src) + if(!T) + return FALSE + + if(is_reserved_level(T.z)) + for(var/A in SSshuttle.mobile) + var/obj/docking_port/mobile/M = A + if(M.launch_status == ENDGAME_TRANSIT) + for(var/place in M.shuttle_areas) + var/area/shuttle/shuttle_area = place + if(T in shuttle_area) + return TRUE + + if(!is_centcom_level(T.z))//if not, don't bother + return FALSE + + //Check for centcom itself + if(istype(T.loc, /area/centcom)) + return TRUE + + //Check for centcom shuttles + for(var/A in SSshuttle.mobile) + var/obj/docking_port/mobile/M = A + if(M.launch_status == ENDGAME_LAUNCHED) + for(var/place in M.shuttle_areas) + var/area/shuttle/shuttle_area = place + if(T in shuttle_area) + return TRUE + +/atom/proc/onSyndieBase() + var/turf/T = get_turf(src) + if(!T) + return FALSE + + if(!is_centcom_level(T.z))//if not, don't bother + return FALSE + + if(istype(T.loc, /area/shuttle/syndicate) || istype(T.loc, /area/syndicate_mothership) || istype(T.loc, /area/shuttle/assault_pod)) + return TRUE + + return FALSE + +/atom/proc/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE) + SEND_SIGNAL(src, COMSIG_ATOM_HULK_ATTACK, user) + if(does_attack_animation) + user.changeNext_move(CLICK_CD_MELEE) + log_combat(user, src, "punched", "hulk powers") + user.do_attack_animation(src, ATTACK_EFFECT_SMASH) + +/atom/proc/CheckParts(list/parts_list) + for(var/A in parts_list) + if(istype(A, /datum/reagent)) + if(!reagents) + reagents = new() + reagents.reagent_list.Add(A) + reagents.conditional_update() + else if(ismovableatom(A)) + var/atom/movable/M = A + if(isliving(M.loc)) + var/mob/living/L = M.loc + L.transferItemToLoc(M, src) + else + M.forceMove(src) + +//common name +/atom/proc/update_multiz(prune_on_fail = FALSE) + return FALSE + +/atom/proc/assume_air(datum/gas_mixture/giver) + qdel(giver) + return null + +/atom/proc/remove_air(amount) + return null + +/atom/proc/return_air() + if(loc) + return loc.return_air() + else + return null + +/atom/proc/check_eye(mob/user) + return + +/atom/proc/Bumped(atom/movable/AM) + set waitfor = FALSE + +// Convenience procs to see if a container is open for chemistry handling +/atom/proc/is_open_container() + return is_refillable() && is_drainable() + +/atom/proc/is_injectable(allowmobs = TRUE) + return reagents && (reagents.reagents_holder_flags & (INJECTABLE | REFILLABLE)) + +/atom/proc/is_drawable(allowmobs = TRUE) + return reagents && (reagents.reagents_holder_flags & (DRAWABLE | DRAINABLE)) + +/atom/proc/is_refillable() + return reagents && (reagents.reagents_holder_flags & REFILLABLE) + +/atom/proc/is_drainable() + return reagents && (reagents.reagents_holder_flags & DRAINABLE) + + +/atom/proc/AllowDrop() + return FALSE + +/atom/proc/CheckExit() + return TRUE + +/atom/proc/HasProximity(atom/movable/AM as mob|obj) + return + +/atom/proc/emp_act(severity) + var/protection = SEND_SIGNAL(src, COMSIG_ATOM_EMP_ACT, severity) + if(!(protection & EMP_PROTECT_WIRES) && istype(wires)) + wires.emp_pulse() + return protection // Pass the protection value collected here upwards + +/atom/proc/bullet_act(obj/item/projectile/P, def_zone) + SEND_SIGNAL(src, COMSIG_ATOM_BULLET_ACT, P, def_zone) + . = P.on_hit(src, 0, def_zone) + +//used on altdisarm() for special interactions between the shoved victim (target) and the src, with user being the one shoving the target on it. +// IMPORTANT: if you wish to add a new own shove_act() to a certain object, remember to add SHOVABLE_ONTO to its obj_flags bitfied var first. +/atom/proc/shove_act(mob/living/target, mob/living/user) + return FALSE + +/atom/proc/in_contents_of(container)//can take class or object instance as argument + if(ispath(container)) + if(istype(src.loc, container)) + return TRUE + else if(src in container) + return TRUE + return FALSE + +/atom/proc/get_examine_name(mob/user) + . = "\a [src]" + var/list/override = list(gender == PLURAL ? "some" : "a", " ", "[name]") + if(article) + . = "[article] [src]" + override[EXAMINE_POSITION_ARTICLE] = article + + var/should_override = FALSE + + if(SEND_SIGNAL(src, COMSIG_ATOM_GET_EXAMINE_NAME, user, override) & COMPONENT_EXNAME_CHANGED) + should_override = TRUE + + + if(blood_DNA && !istype(src, /obj/effect/decal)) + override[EXAMINE_POSITION_BEFORE] = " blood-stained " + should_override = TRUE + + if(should_override) + . = override.Join("") + +///Generate the full examine string of this atom (including icon for goonchat) +/atom/proc/get_examine_string(mob/user, thats = FALSE) + return "[icon2html(src, user)] [thats? "That's ":""][get_examine_name(user)]" + +/atom/proc/examine(mob/user) + . = list("[get_examine_string(user, TRUE)].") + + if(desc) + . += desc + + if(reagents) + if(reagents.reagents_holder_flags & TRANSPARENT) + . += "It contains:" + if(length(reagents.reagent_list)) + if(user.can_see_reagents()) //Show each individual reagent + for(var/datum/reagent/R in reagents.reagent_list) + . += "[R.volume] units of [R.name]" + else //Otherwise, just show the total volume + var/total_volume = 0 + for(var/datum/reagent/R in reagents.reagent_list) + total_volume += R.volume + . += "[total_volume] units of various reagents" + else + . += "Nothing." + else if(reagents.reagents_holder_flags & AMOUNT_VISIBLE) + if(reagents.total_volume) + . += "It has [reagents.total_volume] unit\s left." + else + . += "It's empty." + + SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) + +/// Updates the icon of the atom +/atom/proc/update_icon() + // I expect we're going to need more return flags and options in this proc + var/signalOut = SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_ICON) + + if(!(signalOut & COMSIG_ATOM_NO_UPDATE_ICON_STATE)) + update_icon_state() + + if(!(signalOut & COMSIG_ATOM_NO_UPDATE_OVERLAYS)) + var/list/new_overlays = update_overlays() + if(managed_overlays) + cut_overlay(managed_overlays) + managed_overlays = null + if(length(new_overlays)) + managed_overlays = new_overlays + add_overlay(new_overlays) + +/// Updates the icon state of the atom +/atom/proc/update_icon_state() + +/// Updates the overlays of the atom +/atom/proc/update_overlays() + SHOULD_CALL_PARENT(1) + . = list() + SEND_SIGNAL(src, COMSIG_ATOM_UPDATE_OVERLAYS, .) + +/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) + return //For handling the effects of explosions on contents that would not normally be effected + +/atom/proc/ex_act(severity, target) + set waitfor = FALSE + contents_explosion(severity, target) + SEND_SIGNAL(src, COMSIG_ATOM_EX_ACT, severity, target) + +/atom/proc/blob_act(obj/structure/blob/B) + SEND_SIGNAL(src, COMSIG_ATOM_BLOB_ACT, B) + return + +/atom/proc/fire_act(exposed_temperature, exposed_volume) + SEND_SIGNAL(src, COMSIG_ATOM_FIRE_ACT, exposed_temperature, exposed_volume) + return + +/atom/proc/hitby(atom/movable/AM, skipcatch, hitpush, blocked) + if(density && !has_gravity(AM)) //thrown stuff bounces off dense stuff in no grav, unless the thrown stuff ends up inside what it hit(embedding, bola, etc...). + addtimer(CALLBACK(src, .proc/hitby_react, AM), 2) + +/atom/proc/hitby_react(atom/movable/AM) + if(AM && isturf(AM.loc)) + step(AM, turn(AM.dir, 180)) + +/atom/proc/handle_slip(mob/living/carbon/C, knockdown_amount, obj/O, lube) + return + +//returns the mob's dna info as a list, to be inserted in an object's blood_DNA list +/mob/living/proc/get_blood_dna_list() + var/blood_id = get_blood_id() + if(!(blood_id =="blood" || blood_id == "jellyblood")) + return + return list("ANIMAL DNA" = "Y-") + +/mob/living/carbon/get_blood_dna_list() + var/blood_id = get_blood_id() + if(!(blood_id =="blood" || blood_id == "jellyblood")) + return + var/list/blood_dna = list() + if(dna) + blood_dna[dna.unique_enzymes] = dna.blood_type + else + blood_dna["UNKNOWN DNA"] = "X*" + return blood_dna + +/mob/living/carbon/alien/get_blood_dna_list() + return list("UNKNOWN DNA" = "X*") + +//to add a mob's dna info into an object's blood_DNA list. +/atom/proc/transfer_mob_blood_dna(mob/living/L) + // Returns 0 if we have that blood already + var/new_blood_dna = L.get_blood_dna_list() + if(!new_blood_dna) + return FALSE + LAZYINITLIST(blood_DNA) //if our list of DNA doesn't exist yet, initialise it. + var/old_length = blood_DNA.len + blood_DNA |= new_blood_dna + if(blood_DNA.len == old_length) + return FALSE + return TRUE + +//to add blood dna info to the object's blood_DNA list +/atom/proc/transfer_blood_dna(list/blood_dna, list/datum/disease/diseases) + LAZYINITLIST(blood_DNA) + var/old_length = blood_DNA.len + blood_DNA |= blood_dna + if(blood_DNA.len > old_length) + return TRUE + //some new blood DNA was added + +//to add blood from a mob onto something, and transfer their dna info +/atom/proc/add_mob_blood(mob/living/M) + var/list/blood_dna = M.get_blood_dna_list() + if(!blood_dna) + return FALSE + return add_blood_DNA(blood_dna, M.diseases) + +//to add blood onto something, with blood dna info to include. +/atom/proc/add_blood_DNA(list/blood_dna, list/datum/disease/diseases) + return FALSE + +/obj/add_blood_DNA(list/blood_dna, list/datum/disease/diseases) + return transfer_blood_dna(blood_dna, diseases) + +/obj/item/add_blood_DNA(list/blood_dna, list/datum/disease/diseases) + . = ..() + if(!.) + return + add_blood_overlay() + +/obj/item/proc/add_blood_overlay() + if(!blood_DNA.len) + return + if(initial(icon) && initial(icon_state)) + blood_splatter_icon = icon(initial(icon), initial(icon_state), , 1) //we only want to apply blood-splatters to the initial icon_state for each object + blood_splatter_icon.Blend("#fff", ICON_ADD) //fills the icon_state with white (except where it's transparent) + blood_splatter_icon.Blend(icon('icons/effects/blood.dmi', "itemblood"), ICON_MULTIPLY) //adds blood and the remaining white areas become transparant + blood_splatter_icon.Blend(blood_DNA_to_color(), ICON_MULTIPLY) + add_overlay(blood_splatter_icon) + +/obj/item/clothing/gloves/add_blood_DNA(list/blood_dna, list/datum/disease/diseases) + . = ..() + transfer_blood = rand(2, 4) + +/turf/add_blood_DNA(list/blood_dna, list/datum/disease/diseases) + var/obj/effect/decal/cleanable/blood/splatter/B = locate() in src + if(!B) + B = new /obj/effect/decal/cleanable/blood/splatter(src, diseases) + B.transfer_blood_dna(blood_dna, diseases) //give blood info to the blood decal. + return TRUE //we bloodied the floor + +/mob/living/carbon/human/add_blood_DNA(list/blood_dna, list/datum/disease/diseases) + if(head) + head.add_blood_DNA(blood_dna, diseases) + update_inv_head() + else if(wear_mask) + wear_mask.add_blood_DNA(blood_dna, diseases) + update_inv_wear_mask() + if(wear_neck) + wear_neck.add_blood_DNA(blood_dna, diseases) + update_inv_neck() + if(wear_suit) + wear_suit.add_blood_DNA(blood_dna, diseases) + update_inv_wear_suit() + else if(w_uniform) + w_uniform.add_blood_DNA(blood_dna, diseases) + update_inv_w_uniform() + if(gloves) + var/obj/item/clothing/gloves/G = gloves + G.add_blood_DNA(blood_dna, diseases) + else + transfer_blood_dna(blood_dna, diseases) + bloody_hands = rand(2, 4) + update_inv_gloves() //handles bloody hands overlays and updating + return TRUE + +/atom/proc/blood_DNA_to_color() + var/list/colors = list()//first we make a list of all bloodtypes present + for(var/bloop in blood_DNA) + if(colors[blood_DNA[bloop]]) + colors[blood_DNA[bloop]]++ + else + colors[blood_DNA[bloop]] = 1 + + var/final_rgb = BLOOD_COLOR_HUMAN //a default so we don't have white blood graphics if something messed up + + if(colors.len) + var/sum = 0 //this is all shitcode, but it works; trust me + final_rgb = bloodtype_to_color(colors[1]) + sum = colors[colors[1]] + if(colors.len > 1) + var/i = 2 + while(i <= colors.len) + var/tmp = colors[colors[i]] + final_rgb = BlendRGB(final_rgb, bloodtype_to_color(colors[i]), tmp/(tmp+sum)) + sum += tmp + i++ + + return final_rgb + +/atom/proc/clean_blood() + if(islist(blood_DNA)) + blood_DNA = null + return TRUE + +/atom/proc/wash_cream() + return TRUE + +/atom/proc/isinspace() + if(isspaceturf(get_turf(src))) + return TRUE + else + return FALSE + +/atom/proc/handle_fall() + return + +/atom/proc/singularity_act() + return + +/atom/proc/singularity_pull(obj/singularity/S, current_size) + SEND_SIGNAL(src, COMSIG_ATOM_SING_PULL, S, current_size) + +/atom/proc/acid_act(acidpwr, acid_volume) + SEND_SIGNAL(src, COMSIG_ATOM_ACID_ACT, acidpwr, acid_volume) + +/atom/proc/emag_act() + return SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT) + +/atom/proc/rad_act(strength) + SEND_SIGNAL(src, COMSIG_ATOM_RAD_ACT, strength) + +/atom/proc/narsie_act() + SEND_SIGNAL(src, COMSIG_ATOM_NARSIE_ACT) + +/atom/proc/ratvar_act() + SEND_SIGNAL(src, COMSIG_ATOM_RATVAR_ACT) + +/atom/proc/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) + return FALSE + +/atom/proc/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) + SEND_SIGNAL(src, COMSIG_ATOM_RCD_ACT, user, the_rcd, passed_mode) + return FALSE + +/atom/proc/storage_contents_dump_act(obj/item/storage/src_object, mob/user) + if(GetComponent(/datum/component/storage)) + return component_storage_contents_dump_act(src_object, user) + return FALSE + +/atom/proc/component_storage_contents_dump_act(datum/component/storage/src_object, mob/user) + var/list/things = src_object.contents() + var/datum/progressbar/progress = new(user, things.len, src) + var/datum/component/storage/STR = GetComponent(/datum/component/storage) + while (do_after(user, 10, TRUE, src, FALSE, CALLBACK(STR, /datum/component/storage.proc/handle_mass_item_insertion, things, src_object, user, progress))) + stoplag(1) + qdel(progress) + to_chat(user, "You dump as much of [src_object.parent]'s contents into [STR.insert_preposition]to [src] as you can.") + STR.orient2hud(user) + src_object.orient2hud(user) + if(user.active_storage) //refresh the HUD to show the transfered contents + user.active_storage.close(user) + user.active_storage.show_to(user) + return TRUE + +/atom/proc/get_dumping_location(obj/item/storage/source,mob/user) + return null + +//This proc is called on the location of an atom when the atom is Destroy()'d +/atom/proc/handle_atom_del(atom/A) + SEND_SIGNAL(src, COMSIG_ATOM_CONTENTS_DEL, A) + +//called when the turf the atom resides on is ChangeTurfed +/atom/proc/HandleTurfChange(turf/T) + for(var/a in src) + var/atom/A = a + A.HandleTurfChange(T) + +//the vision impairment to give to the mob whose perspective is set to that atom (e.g. an unfocused camera giving you an impaired vision when looking through it) +/atom/proc/get_remote_view_fullscreens(mob/user) + return + +//the sight changes to give to the mob whose perspective is set to that atom (e.g. A mob with nightvision loses its nightvision while looking through a normal camera) +/atom/proc/update_remote_sight(mob/living/user) + return + + +//Hook for running code when a dir change occurs +/atom/proc/setDir(newdir, ismousemovement=FALSE) + SEND_SIGNAL(src, COMSIG_ATOM_DIR_CHANGE, dir, newdir) + dir = newdir + +/atom/proc/mech_melee_attack(obj/mecha/M) + return + +//If a mob logouts/logins in side of an object you can use this proc +/atom/proc/on_log(login) + if(loc) + loc.on_log(login) + + +/* + Atom Colour Priority System + A System that gives finer control over which atom colour to colour the atom with. + The "highest priority" one is always displayed as opposed to the default of + "whichever was set last is displayed" +*/ + + +/* + Adds an instance of colour_type to the atom's atom_colours list +*/ +/atom/proc/add_atom_colour(coloration, colour_priority) + if(!atom_colours || !atom_colours.len) + atom_colours = list() + atom_colours.len = COLOUR_PRIORITY_AMOUNT //four priority levels currently. + if(!coloration) + return + if(colour_priority > atom_colours.len) + return + atom_colours[colour_priority] = coloration + update_atom_colour() + + +/* + Removes an instance of colour_type from the atom's atom_colours list +*/ +/atom/proc/remove_atom_colour(colour_priority, coloration) + if(!atom_colours) + atom_colours = list() + atom_colours.len = COLOUR_PRIORITY_AMOUNT //four priority levels currently. + if(colour_priority > atom_colours.len) + return + if(coloration && atom_colours[colour_priority] != coloration) + return //if we don't have the expected color (for a specific priority) to remove, do nothing + atom_colours[colour_priority] = null + update_atom_colour() + + +/* + Resets the atom's color to null, and then sets it to the highest priority + colour available +*/ +/atom/proc/update_atom_colour() + if(!atom_colours) + atom_colours = list() + atom_colours.len = COLOUR_PRIORITY_AMOUNT //four priority levels currently. + color = null + for(var/C in atom_colours) + if(islist(C)) + var/list/L = C + if(L.len) + color = L + return + else if(C) + color = C + return + +/atom/vv_edit_var(var_name, var_value) + if(!GLOB.Debug2) + flags_1 |= ADMIN_SPAWNED_1 + . = ..() + switch(var_name) + if("color") + add_atom_colour(color, ADMIN_COLOUR_PRIORITY) + +/atom/vv_get_dropdown() + . = ..() + . += "---" + var/turf/curturf = get_turf(src) + if (curturf) + .["Jump to"] = "?_src_=holder;[HrefToken()];adminplayerobservecoodjump=1;X=[curturf.x];Y=[curturf.y];Z=[curturf.z]" + .["Modify Transform"] = "?_src_=vars;[HrefToken()];modtransform=[REF(src)]" + .["Add reagent"] = "?_src_=vars;[HrefToken()];addreagent=[REF(src)]" + .["Trigger EM pulse"] = "?_src_=vars;[HrefToken()];emp=[REF(src)]" + .["Trigger explosion"] = "?_src_=vars;[HrefToken()];explode=[REF(src)]" + +/atom/proc/drop_location() + var/atom/L = loc + if(!L) + return null + return L.AllowDrop() ? L : L.drop_location() + +/atom/Entered(atom/movable/AM, atom/oldLoc) + SEND_SIGNAL(src, COMSIG_ATOM_ENTERED, AM, oldLoc) + +/atom/Exit(atom/movable/AM, atom/newLoc) + . = ..() + if(SEND_SIGNAL(src, COMSIG_ATOM_EXIT, AM, newLoc) & COMPONENT_ATOM_BLOCK_EXIT) + return FALSE + +/atom/Exited(atom/movable/AM, atom/newLoc) + SEND_SIGNAL(src, COMSIG_ATOM_EXITED, AM, newLoc) + +/atom/proc/return_temperature() + return + +// Tool behavior procedure. Redirects to tool-specific procs by default. +// You can override it to catch all tool interactions, for use in complex deconstruction procs. +// Just don't forget to return ..() in the end. +/atom/proc/tool_act(mob/living/user, obj/item/I, tool_type) + switch(tool_type) + if(TOOL_CROWBAR) + return crowbar_act(user, I) + if(TOOL_MULTITOOL) + return multitool_act(user, I) + if(TOOL_SCREWDRIVER) + return screwdriver_act(user, I) + if(TOOL_WRENCH) + return wrench_act(user, I) + if(TOOL_WIRECUTTER) + return wirecutter_act(user, I) + if(TOOL_WELDER) + return welder_act(user, I) + if(TOOL_ANALYZER) + return analyzer_act(user, I) + +// Tool-specific behavior procs. To be overridden in subtypes. +/atom/proc/crowbar_act(mob/living/user, obj/item/I) + return + +/atom/proc/multitool_act(mob/living/user, obj/item/I) + return + +/atom/proc/screwdriver_act(mob/living/user, obj/item/I) + SEND_SIGNAL(src, COMSIG_ATOM_SCREWDRIVER_ACT, user, I) + +/atom/proc/wrench_act(mob/living/user, obj/item/I) + return + +/atom/proc/wirecutter_act(mob/living/user, obj/item/I) + return + +/atom/proc/welder_act(mob/living/user, obj/item/I) + return + +/atom/proc/analyzer_act(mob/living/user, obj/item/I) + return + +/atom/proc/GenerateTag() + return + +// Generic logging helper +/atom/proc/log_message(message, message_type, color=null, log_globally=TRUE) + if(!log_globally) + return + + var/log_text = "[key_name(src)] [message] [loc_name(src)]" + switch(message_type) + if(LOG_ATTACK) + log_attack(log_text) + if(LOG_SAY) + log_say(log_text) + if(LOG_WHISPER) + log_whisper(log_text) + if(LOG_EMOTE) + log_emote(log_text) + if(LOG_DSAY) + log_dsay(log_text) + if(LOG_PDA) + log_pda(log_text) + if(LOG_CHAT) + log_chat(log_text) + if(LOG_COMMENT) + log_comment(log_text) + if(LOG_TELECOMMS) + log_telecomms(log_text) + if(LOG_OOC) + log_ooc(log_text) + if(LOG_ADMIN) + log_admin(log_text) + if(LOG_ADMIN_PRIVATE) + log_admin_private(log_text) + if(LOG_ASAY) + log_adminsay(log_text) + if(LOG_OWNERSHIP) + log_game(log_text) + if(LOG_GAME) + log_game(log_text) + else + stack_trace("Invalid individual logging type: [message_type]. Defaulting to [LOG_GAME] (LOG_GAME).") + log_game(log_text) + +// Helper for logging chat messages or other logs with arbitrary inputs (e.g. announcements) +/atom/proc/log_talk(message, message_type, tag=null, log_globally=TRUE, forced_by=null) + var/prefix = tag ? "([tag]) " : "" + var/suffix = forced_by ? " FORCED by [forced_by]" : "" + log_message("[prefix]\"[message]\"[suffix]", message_type, log_globally=log_globally) + +// Helper for logging of messages with only one sender and receiver +/proc/log_directed_talk(atom/source, atom/target, message, message_type, tag) + if(!tag) + stack_trace("Unspecified tag for private message") + tag = "UNKNOWN" + + source.log_talk(message, message_type, tag="[tag] to [key_name(target)]") + if(source != target) + target.log_talk(message, message_type, tag="[tag] from [key_name(source)]", log_globally=FALSE) + +/* +Proc for attack log creation, because really why not +1 argument is the actor performing the action +2 argument is the target of the action +3 is a verb describing the action (e.g. punched, throwed, kicked, etc.) +4 is a tool with which the action was made (usually an item) +5 is any additional text, which will be appended to the rest of the log line +*/ + +/proc/log_combat(atom/user, atom/target, what_done, atom/object=null, addition=null) + var/ssource = key_name(user) + var/starget = key_name(target) + + var/mob/living/living_target = target + var/hp = istype(living_target) ? " (NEWHP: [living_target.health]) " : "" + + var/sobject = "" + if(object) + sobject = " with [key_name(object)]" + var/saddition = "" + if(addition) + saddition = " [addition]" + + var/postfix = "[sobject][saddition][hp]" + + var/message = "has [what_done] [starget][postfix]" + user.log_message(message, LOG_ATTACK, color="red") + + if(user != target) + var/reverse_message = "has been [what_done] by [ssource][postfix]" + target.log_message(reverse_message, LOG_ATTACK, color="orange", log_globally=FALSE) + +// Filter stuff +/atom/movable/proc/add_filter(name,priority,list/params) + LAZYINITLIST(filter_data) + var/list/p = params.Copy() + p["priority"] = priority + filter_data[name] = p + update_filters() + +/atom/movable/proc/update_filters() + filters = null + filter_data = sortTim(filter_data, /proc/cmp_filter_data_priority, TRUE) + for(var/f in filter_data) + var/list/data = filter_data[f] + var/list/arguments = data.Copy() + arguments -= "priority" + filters += filter(arglist(arguments)) + +/atom/movable/proc/get_filter(name) + if(filter_data && filter_data[name]) + return filters[filter_data.Find(name)] + +/atom/movable/proc/remove_filter(name) + if(filter_data && filter_data[name]) + filter_data -= name + update_filters() + return TRUE + +/atom/proc/intercept_zImpact(atom/movable/AM, levels = 1) . |= SEND_SIGNAL(src, COMSIG_ATOM_INTERCEPT_Z_FALL, AM, levels) \ No newline at end of file diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 7c57de74a4..00a08d62b2 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1,874 +1,874 @@ -/atom/movable - layer = OBJ_LAYER - var/last_move = null - var/last_move_time = 0 - var/anchored = FALSE - var/datum/thrownthing/throwing = null - var/throw_speed = 2 //How many tiles to move per ds when being thrown. Float values are fully supported - var/throw_range = 7 - var/mob/pulledby = null - var/initial_language_holder = /datum/language_holder - var/datum/language_holder/language_holder - var/verb_say = "says" - var/verb_ask = "asks" - var/verb_exclaim = "exclaims" - var/verb_whisper = "whispers" - var/verb_yell = "yells" - var/speech_span - var/inertia_dir = 0 - var/atom/inertia_last_loc - var/inertia_moving = 0 - var/inertia_next_move = 0 - var/inertia_move_delay = 5 - var/pass_flags = 0 - var/moving_diagonally = 0 //0: not doing a diagonal move. 1 and 2: doing the first/second step of the diagonal move - var/list/client_mobs_in_contents // This contains all the client mobs within this container - var/list/acted_explosions //for explosion dodging - glide_size = 8 - appearance_flags = TILE_BOUND|PIXEL_SCALE - var/datum/forced_movement/force_moving = null //handled soley by forced_movement.dm - var/movement_type = GROUND //Incase you have multiple types, you automatically use the most useful one. IE: Skating on ice, flippers on water, flying over chasm/space, etc. - var/atom/movable/pulling - var/grab_state = 0 - var/throwforce = 0 - var/datum/component/orbiter/orbiting - var/can_be_z_moved = TRUE - - var/zfalling = FALSE - -/atom/movable/proc/can_zFall(turf/source, levels = 1, turf/target, direction) - if(!direction) - direction = DOWN - if(!source) - source = get_turf(src) - if(!source) - return FALSE - if(!target) - target = get_step_multiz(source, direction) - if(!target) - return FALSE - return !(movement_type & FLYING) && has_gravity(source) && !throwing - -/atom/movable/proc/onZImpact(turf/T, levels) - var/atom/highest = T - for(var/i in T.contents) - var/atom/A = i - if(!A.density) - continue - if(isobj(A) || ismob(A)) - if(A.layer > highest.layer) - highest = A - INVOKE_ASYNC(src, .proc/SpinAnimation, 5, 2) - throw_impact(highest) - return TRUE - -//For physical constraints to travelling up/down. -/atom/movable/proc/can_zTravel(turf/destination, direction) - var/turf/T = get_turf(src) - if(!T) - return FALSE - if(!direction) - if(!destination) - return FALSE - direction = get_dir(T, destination) - if(direction != UP && direction != DOWN) - return FALSE - if(!destination) - destination = get_step_multiz(src, direction) - if(!destination) - return FALSE - return T.zPassOut(src, direction, destination) && destination.zPassIn(src, direction, T) - -/atom/movable/vv_edit_var(var_name, var_value) - var/static/list/banned_edits = list("step_x", "step_y", "step_size") - var/static/list/careful_edits = list("bound_x", "bound_y", "bound_width", "bound_height") - if(var_name in banned_edits) - return FALSE //PLEASE no. - if((var_name in careful_edits) && (var_value % world.icon_size) != 0) - return FALSE - switch(var_name) - if("x") - var/turf/T = locate(var_value, y, z) - if(T) - forceMove(T) - return TRUE - return FALSE - if("y") - var/turf/T = locate(x, var_value, z) - if(T) - forceMove(T) - return TRUE - return FALSE - if("z") - var/turf/T = locate(x, y, var_value) - if(T) - forceMove(T) - return TRUE - return FALSE - if("loc") - if(istype(var_value, /atom)) - forceMove(var_value) - return TRUE - else if(isnull(var_value)) - moveToNullspace() - return TRUE - return FALSE - return ..() - -/atom/movable/proc/start_pulling(atom/movable/AM,gs) - if(QDELETED(AM)) - return FALSE - if(!(AM.can_be_pulled(src))) - return FALSE - - // If we're pulling something then drop what we're currently pulling and pull this instead. - if(pulling) - if(gs==0) - stop_pulling() - return FALSE - // Are we trying to pull something we are already pulling? Then enter grab cycle and end. - if(AM == pulling) - grab_state = gs - if(istype(AM,/mob/living)) - var/mob/living/AMob = AM - AMob.grabbedby(src) - return TRUE - stop_pulling() - if(AM.pulledby) - log_combat(AM, AM.pulledby, "pulled from", src) - AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once. - pulling = AM - AM.pulledby = src - grab_state = gs - if(ismob(AM)) - var/mob/M = AM - log_combat(src, M, "grabbed", addition="passive grab") - visible_message("[src] has grabbed [M] passively!") - return TRUE - -/atom/movable/proc/stop_pulling() - if(pulling) - pulling.pulledby = null - var/mob/living/ex_pulled = pulling - pulling = null - grab_state = 0 - if(isliving(ex_pulled)) - var/mob/living/L = ex_pulled - L.update_canmove()// mob gets up if it was lyng down in a chokehold - -/atom/movable/proc/Move_Pulled(atom/A) - if(!pulling) - return - if(pulling.anchored || !pulling.Adjacent(src)) - stop_pulling() - return - if(isliving(pulling)) - var/mob/living/L = pulling - if(L.buckled && L.buckled.buckle_prevents_pull) //if they're buckled to something that disallows pulling, prevent it - stop_pulling() - return - if(A == loc && pulling.density) - return - if(!Process_Spacemove(get_dir(pulling.loc, A))) - return - step(pulling, get_dir(pulling.loc, A)) - -/atom/movable/proc/check_pulling() - if(pulling) - var/atom/movable/pullee = pulling - if(pullee && get_dist(src, pullee) > 1) - stop_pulling() - return - if(!isturf(loc)) - stop_pulling() - return - if(pullee && !isturf(pullee.loc) && pullee.loc != loc) //to be removed once all code that changes an object's loc uses forceMove(). - log_game("DEBUG:[src]'s pull on [pullee] wasn't broken despite [pullee] being in [pullee.loc]. Pull stopped manually.") - stop_pulling() - return - if(pulling.anchored) - stop_pulling() - return - -//////////////////////////////////////// -// Here's where we rewrite how byond handles movement except slightly different -// To be removed on step_ conversion -// All this work to prevent a second bump -/atom/movable/Move(atom/newloc, direct=0) - . = FALSE - if(!newloc || newloc == loc) - return - - if(!direct) - direct = get_dir(src, newloc) - setDir(direct) - - if(!loc.Exit(src, newloc)) - return - - if(!newloc.Enter(src, src.loc)) - return - - // Past this is the point of no return - var/atom/oldloc = loc - var/area/oldarea = get_area(oldloc) - var/area/newarea = get_area(newloc) - loc = newloc - . = TRUE - oldloc.Exited(src, newloc) - if(oldarea != newarea) - oldarea.Exited(src, newloc) - - for(var/i in oldloc) - if(i == src) // Multi tile objects - continue - var/atom/movable/thing = i - thing.Uncrossed(src) - - newloc.Entered(src, oldloc) - if(oldarea != newarea) - newarea.Entered(src, oldloc) - - for(var/i in loc) - if(i == src) // Multi tile objects - continue - var/atom/movable/thing = i - thing.Crossed(src) -// -//////////////////////////////////////// - -/atom/movable/Move(atom/newloc, direct) - var/atom/movable/pullee = pulling - var/turf/T = loc - if(pulling) - if(pullee && get_dist(src, pullee) > 1) - stop_pulling() - - if(pullee && pullee.loc != loc && !isturf(pullee.loc) ) //to be removed once all code that changes an object's loc uses forceMove(). - log_game("DEBUG:[src]'s pull on [pullee] wasn't broken despite [pullee] being in [pullee.loc]. Pull stopped manually.") - stop_pulling() - if(!loc || !newloc) - return FALSE - var/atom/oldloc = loc - - if(loc != newloc) - if (!(direct & (direct - 1))) //Cardinal move - . = ..() - else //Diagonal move, split it into cardinal moves - moving_diagonally = FIRST_DIAG_STEP - var/first_step_dir - // The `&& moving_diagonally` checks are so that a forceMove taking - // place due to a Crossed, Bumped, etc. call will interrupt - // the second half of the diagonal movement, or the second attempt - // at a first half if step() fails because we hit something. - if (direct & NORTH) - if (direct & EAST) - if (step(src, NORTH) && moving_diagonally) - first_step_dir = NORTH - moving_diagonally = SECOND_DIAG_STEP - . = step(src, EAST) - else if (moving_diagonally && step(src, EAST)) - first_step_dir = EAST - moving_diagonally = SECOND_DIAG_STEP - . = step(src, NORTH) - else if (direct & WEST) - if (step(src, NORTH) && moving_diagonally) - first_step_dir = NORTH - moving_diagonally = SECOND_DIAG_STEP - . = step(src, WEST) - else if (moving_diagonally && step(src, WEST)) - first_step_dir = WEST - moving_diagonally = SECOND_DIAG_STEP - . = step(src, NORTH) - else if (direct & SOUTH) - if (direct & EAST) - if (step(src, SOUTH) && moving_diagonally) - first_step_dir = SOUTH - moving_diagonally = SECOND_DIAG_STEP - . = step(src, EAST) - else if (moving_diagonally && step(src, EAST)) - first_step_dir = EAST - moving_diagonally = SECOND_DIAG_STEP - . = step(src, SOUTH) - else if (direct & WEST) - if (step(src, SOUTH) && moving_diagonally) - first_step_dir = SOUTH - moving_diagonally = SECOND_DIAG_STEP - . = step(src, WEST) - else if (moving_diagonally && step(src, WEST)) - first_step_dir = WEST - moving_diagonally = SECOND_DIAG_STEP - . = step(src, SOUTH) - if(moving_diagonally == SECOND_DIAG_STEP) - if(!.) - setDir(first_step_dir) - else if (!inertia_moving) - inertia_next_move = world.time + inertia_move_delay - newtonian_move(direct) - moving_diagonally = 0 - return - - if(!loc || (loc == oldloc && oldloc != newloc)) - last_move = 0 - return - - if(.) - Moved(oldloc, direct) - if(. && pulling && pulling == pullee) //we were pulling a thing and didn't lose it during our move. - if(pulling.anchored) - stop_pulling() - else - var/pull_dir = get_dir(src, pulling) - //puller and pullee more than one tile away or in diagonal position - if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir))) - pulling.Move(T, get_dir(pulling, T)) //the pullee tries to reach our previous position - if(pulling && get_dist(src, pulling) > 1) //the pullee couldn't keep up - stop_pulling() - if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1)//separated from our puller and not in the middle of a diagonal move. - pulledby.stop_pulling() - - - last_move = direct - setDir(direct) - if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc,direct)) //movement failed due to buckled mob(s) - return FALSE - -//Called after a successful Move(). By this point, we've already moved -/atom/movable/proc/Moved(atom/OldLoc, Dir, Forced = FALSE) - SEND_SIGNAL(src, COMSIG_MOVABLE_MOVED, OldLoc, Dir, Forced) - if (!inertia_moving) - inertia_next_move = world.time + inertia_move_delay - newtonian_move(Dir) - if (length(client_mobs_in_contents)) - update_parallax_contents() - - return TRUE - -/atom/movable/Destroy(force) - QDEL_NULL(proximity_monitor) - QDEL_NULL(language_holder) - - unbuckle_all_mobs(force=1) - - . = ..() - if(loc) - //Restore air flow if we were blocking it (movables with ATMOS_PASS_PROC will need to do this manually if necessary) - if(((CanAtmosPass == ATMOS_PASS_DENSITY && density) || CanAtmosPass == ATMOS_PASS_NO) && isturf(loc)) - CanAtmosPass = ATMOS_PASS_YES - air_update_turf(TRUE) - loc.handle_atom_del(src) - for(var/atom/movable/AM in contents) - qdel(AM) - moveToNullspace() - invisibility = INVISIBILITY_ABSTRACT - if(pulledby) - pulledby.stop_pulling() - - if(orbiting) - orbiting.end_orbit(src) - orbiting = null - -// Make sure you know what you're doing if you call this, this is intended to only be called by byond directly. -// You probably want CanPass() -/atom/movable/Cross(atom/movable/AM) - . = TRUE - SEND_SIGNAL(src, COMSIG_MOVABLE_CROSS, AM) - return CanPass(AM, AM.loc, TRUE) - -//oldloc = old location on atom, inserted when forceMove is called and ONLY when forceMove is called! -/atom/movable/Crossed(atom/movable/AM, oldloc) - SEND_SIGNAL(src, COMSIG_MOVABLE_CROSSED, AM) - -/atom/movable/Uncross(atom/movable/AM, atom/newloc) - . = ..() - if(SEND_SIGNAL(src, COMSIG_MOVABLE_UNCROSS, AM) & COMPONENT_MOVABLE_BLOCK_UNCROSS) - return FALSE - if(isturf(newloc) && !CheckExit(AM, newloc)) - return FALSE - -/atom/movable/Uncrossed(atom/movable/AM) - SEND_SIGNAL(src, COMSIG_MOVABLE_UNCROSSED, AM) - -/atom/movable/Bump(atom/A) - if(!A) - CRASH("Bump was called with no argument.") - SEND_SIGNAL(src, COMSIG_MOVABLE_BUMP, A) - . = ..() - if(!QDELETED(throwing)) - throwing.hit_atom(A) - . = TRUE - if(QDELETED(A)) - return - A.Bumped(src) - -/atom/movable/proc/forceMove(atom/destination) - . = FALSE - if(destination) - . = doMove(destination) - else - CRASH("No valid destination passed into forceMove") - -/atom/movable/proc/moveToNullspace() - return doMove(null) - -/atom/movable/proc/doMove(atom/destination) - . = FALSE - if(destination) - if(pulledby) - pulledby.stop_pulling() - var/atom/oldloc = loc - var/same_loc = oldloc == destination - var/area/old_area = get_area(oldloc) - var/area/destarea = get_area(destination) - - loc = destination - moving_diagonally = 0 - - if(!same_loc) - if(oldloc) - oldloc.Exited(src, destination) - if(old_area && old_area != destarea) - old_area.Exited(src, destination) - for(var/atom/movable/AM in oldloc) - AM.Uncrossed(src) - var/turf/oldturf = get_turf(oldloc) - var/turf/destturf = get_turf(destination) - var/old_z = (oldturf ? oldturf.z : null) - var/dest_z = (destturf ? destturf.z : null) - if (old_z != dest_z) - onTransitZ(old_z, dest_z) - destination.Entered(src, oldloc) - if(destarea && old_area != destarea) - destarea.Entered(src, oldloc) - - for(var/atom/movable/AM in destination) - if(AM == src) - continue - AM.Crossed(src, oldloc) - - Moved(oldloc, NONE, TRUE) - . = TRUE - - //If no destination, move the atom into nullspace (don't do this unless you know what you're doing) - else - . = TRUE - if (loc) - var/atom/oldloc = loc - var/area/old_area = get_area(oldloc) - oldloc.Exited(src, null) - if(old_area) - old_area.Exited(src, null) - loc = null - -/atom/movable/proc/onTransitZ(old_z,new_z) - SEND_SIGNAL(src, COMSIG_MOVABLE_Z_CHANGED, old_z, new_z) - for (var/item in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care. - var/atom/movable/AM = item - AM.onTransitZ(old_z,new_z) - -/atom/movable/proc/setMovetype(newval) - movement_type = newval - -//Called whenever an object moves and by mobs when they attempt to move themselves through space -//And when an object or action applies a force on src, see newtonian_move() below -//Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting -//Mobs should return 1 if they should be able to move of their own volition, see client/Move() in mob_movement.dm -//movement_dir == 0 when stopping or any dir when trying to move -/atom/movable/proc/Process_Spacemove(movement_dir = 0) - if(has_gravity(src)) - return 1 - - if(pulledby) - return 1 - - if(throwing) - return 1 - - if(!isturf(loc)) - return 1 - - if(locate(/obj/structure/lattice) in range(1, get_turf(src))) //Not realistic but makes pushing things in space easier - return 1 - - return 0 - - -/atom/movable/proc/newtonian_move(direction) //Only moves the object if it's under no gravity - if(!loc || Process_Spacemove(0)) - inertia_dir = 0 - return 0 - - inertia_dir = direction - if(!direction) - return 1 - inertia_last_loc = loc - SSspacedrift.processing[src] = src - return 1 - -/atom/movable/proc/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) - set waitfor = 0 - SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum) - return hit_atom.hitby(src) - -/atom/movable/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked) - if(!anchored && hitpush) - step(src, AM.dir) - ..() - -/atom/movable/proc/safe_throw_at(atom/target, range, speed, mob/thrower, spin=TRUE, diagonals_first = FALSE, var/datum/callback/callback, messy_throw = TRUE) - return throw_at(target, range, speed, thrower, spin, diagonals_first, callback, messy_throw) - -/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin=TRUE, diagonals_first = FALSE, var/datum/callback/callback, messy_throw = TRUE) //If this returns FALSE then callback will not be called. - . = FALSE - if (!target || speed <= 0) - return - - if(SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_THROW, args) & COMPONENT_CANCEL_THROW) - return - - if (pulledby) - pulledby.stop_pulling() - - //They are moving! Wouldn't it be cool if we calculated their momentum and added it to the throw? - if (thrower && thrower.last_move && thrower.client && thrower.client.move_delay >= world.time + world.tick_lag*2) - var/user_momentum = thrower.movement_delay() - if (!user_momentum) //no movement_delay, this means they move once per byond tick, lets calculate from that instead. - user_momentum = world.tick_lag - - user_momentum = 1 / user_momentum // convert from ds to the tiles per ds that throw_at uses. - - if (get_dir(thrower, target) & last_move) - user_momentum = user_momentum //basically a noop, but needed - else if (get_dir(target, thrower) & last_move) - user_momentum = -user_momentum //we are moving away from the target, lets slowdown the throw accordingly - else - user_momentum = 0 - - - if (user_momentum) - //first lets add that momentum to range. - range *= (user_momentum / speed) + 1 - //then lets add it to speed - speed += user_momentum - if (speed <= 0) - return//no throw speed, the user was moving too fast. - - . = TRUE // No failure conditions past this point. - - var/datum/thrownthing/TT = new() - TT.thrownthing = src - TT.target = target - TT.target_turf = get_turf(target) - TT.init_dir = get_dir(src, target) - TT.maxrange = range - TT.speed = speed - TT.thrower = thrower - TT.diagonals_first = diagonals_first - TT.callback = callback - if(!QDELETED(thrower)) - TT.target_zone = thrower.zone_selected - - var/dist_x = abs(target.x - src.x) - var/dist_y = abs(target.y - src.y) - var/dx = (target.x > src.x) ? EAST : WEST - var/dy = (target.y > src.y) ? NORTH : SOUTH - - if (dist_x == dist_y) - TT.pure_diagonal = 1 - - else if(dist_x <= dist_y) - var/olddist_x = dist_x - var/olddx = dx - dist_x = dist_y - dist_y = olddist_x - dx = dy - dy = olddx - TT.dist_x = dist_x - TT.dist_y = dist_y - TT.dx = dx - TT.dy = dy - TT.diagonal_error = dist_x/2 - dist_y - TT.start_time = world.time - - if(pulledby) - pulledby.stop_pulling() - - throwing = TT - if(spin) - SpinAnimation(5, 1) - - SEND_SIGNAL(src, COMSIG_MOVABLE_POST_THROW, TT, spin) - SSthrowing.processing[src] = TT - if (SSthrowing.state == SS_PAUSED && length(SSthrowing.currentrun)) - SSthrowing.currentrun[src] = TT - TT.tick() - -/atom/movable/proc/handle_buckled_mob_movement(newloc,direct) - for(var/m in buckled_mobs) - var/mob/living/buckled_mob = m - if(!buckled_mob.Move(newloc, direct)) - forceMove(buckled_mob.loc) - last_move = buckled_mob.last_move - inertia_dir = last_move - buckled_mob.inertia_dir = last_move - return 0 - return 1 - -/atom/movable/CanPass(atom/movable/mover, turf/target) - if(mover in buckled_mobs) - return 1 - return ..() - -// called when this atom 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. -/atom/movable/proc/on_exit_storage(datum/component/storage/concrete/S) - return - -// called when this atom is added into a storage item, which is passed on as S. The loc variable is already set to the storage item. -/atom/movable/proc/on_enter_storage(datum/component/storage/concrete/S) - return - -/atom/movable/proc/get_spacemove_backup() - var/atom/movable/dense_object_backup - for(var/A in orange(1, get_turf(src))) - if(isarea(A)) - continue - else if(isturf(A)) - var/turf/turf = A - if(!turf.density) - continue - return turf - else - var/atom/movable/AM = A - if(!AM.CanPass(src) || AM.density) - if(AM.anchored) - return AM - dense_object_backup = AM - break - . = dense_object_backup - -//called when a mob resists while inside a container that is itself inside something. -/atom/movable/proc/relay_container_resist(mob/living/user, obj/O) - return - - -/atom/movable/proc/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) - if(!no_effect && (visual_effect_icon || used_item)) - do_item_attack_animation(A, visual_effect_icon, used_item) - - if(A == src) - return //don't do an animation if attacking self - var/pixel_x_diff = 0 - var/pixel_y_diff = 0 - - var/direction = get_dir(src, A) - if(direction & NORTH) - pixel_y_diff = 8 - else if(direction & SOUTH) - pixel_y_diff = -8 - - if(direction & EAST) - pixel_x_diff = 8 - else if(direction & WEST) - pixel_x_diff = -8 - - var/matrix/OM = matrix(transform) - var/matrix/M = matrix(transform) - M.Turn(pixel_x_diff ? pixel_x_diff*2 : pick(-16, 16)) - - animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, transform = M, time = 2) - animate(src, pixel_x = pixel_x - pixel_x_diff, pixel_y = pixel_y - pixel_y_diff, transform = OM, time = 2) - -/atom/movable/proc/do_item_attack_animation(atom/A, visual_effect_icon, obj/item/used_item) - var/image/I - if(visual_effect_icon) - I = image('icons/effects/effects.dmi', A, visual_effect_icon, A.layer + 0.1) - else if(used_item) - I = image(icon = used_item, loc = A, layer = A.layer + 0.1) - I.plane = GAME_PLANE - - // Scale the icon. - I.transform *= 0.75 - // The icon should not rotate. - I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA - - // Set the direction of the icon animation. - var/direction = get_dir(src, A) - if(direction & NORTH) - I.pixel_y = -16 - else if(direction & SOUTH) - I.pixel_y = 16 - - if(direction & EAST) - I.pixel_x = -16 - else if(direction & WEST) - I.pixel_x = 16 - - if(!direction) // Attacked self?! - I.pixel_z = 16 - - if(!I) - return - - flick_overlay(I, GLOB.clients, 5) // 5 ticks/half a second - - // And animate the attack! - animate(I, alpha = 175, pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 3) - -/atom/movable/vv_get_dropdown() - . = ..() - . -= "Jump to" - .["Follow"] = "?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(src)]" - .["Get"] = "?_src_=holder;[HrefToken()];admingetmovable=[REF(src)]" - -/atom/movable/proc/ex_check(ex_id) - if(!ex_id) - return TRUE - LAZYINITLIST(acted_explosions) - if(ex_id in acted_explosions) - return FALSE - acted_explosions += ex_id - return TRUE - -//TODO: Better floating -/atom/movable/proc/float(on) - if(throwing) - return - if(on && !(movement_type & FLOATING)) - animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1) - sleep(10) - animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1) - setMovetype(movement_type | FLOATING) - else if (!on && (movement_type & FLOATING)) - animate(src, pixel_y = initial(pixel_y), time = 10) - setMovetype(movement_type & ~FLOATING) - -/* Language procs */ -/atom/movable/proc/get_language_holder(shadow=TRUE) - if(language_holder) - return language_holder - else - language_holder = new initial_language_holder(src) - return language_holder - -/atom/movable/proc/grant_language(datum/language/dt, body = FALSE) - var/datum/language_holder/H = get_language_holder(!body) - H.grant_language(dt, body) - -/atom/movable/proc/grant_all_languages(omnitongue=FALSE) - var/datum/language_holder/H = get_language_holder() - H.grant_all_languages(omnitongue) - -/atom/movable/proc/get_random_understood_language() - var/datum/language_holder/H = get_language_holder() - . = H.get_random_understood_language() - -/atom/movable/proc/remove_language(datum/language/dt, body = FALSE) - var/datum/language_holder/H = get_language_holder(!body) - H.remove_language(dt, body) - -/atom/movable/proc/remove_all_languages() - var/datum/language_holder/H = get_language_holder() - H.remove_all_languages() - -/atom/movable/proc/has_language(datum/language/dt) - var/datum/language_holder/H = get_language_holder() - . = H.has_language(dt) - -/atom/movable/proc/copy_known_languages_from(thing, replace=FALSE) - var/datum/language_holder/H = get_language_holder() - . = H.copy_known_languages_from(thing, replace) - -// Whether an AM can speak in a language or not, independent of whether -// it KNOWS the language -/atom/movable/proc/could_speak_in_language(datum/language/dt) - . = TRUE - -/atom/movable/proc/can_speak_in_language(datum/language/dt) - var/datum/language_holder/H = get_language_holder() - - if(!H.has_language(dt)) - return FALSE - else if(H.omnitongue) - return TRUE - else if(could_speak_in_language(dt) && (!H.only_speaks_language || H.only_speaks_language == dt)) - return TRUE - else - return FALSE - -/atom/movable/proc/get_default_language() - // if no language is specified, and we want to say() something, which - // language do we use? - var/datum/language_holder/H = get_language_holder() - - if(H.selected_default_language) - if(can_speak_in_language(H.selected_default_language)) - return H.selected_default_language - else - H.selected_default_language = null - - - var/datum/language/chosen_langtype - var/highest_priority - - for(var/lt in H.languages) - var/datum/language/langtype = lt - if(!can_speak_in_language(langtype)) - continue - - var/pri = initial(langtype.default_priority) - if(!highest_priority || (pri > highest_priority)) - chosen_langtype = langtype - highest_priority = pri - - H.selected_default_language = . - . = chosen_langtype - -/* End language procs */ -/atom/movable/proc/ConveyorMove(movedir) - set waitfor = FALSE - if(!anchored && has_gravity()) - step(src, movedir) - -//Returns an atom's power cell, if it has one. Overload for individual items. -/atom/movable/proc/get_cell() - return - -/atom/movable/proc/can_be_pulled(user) - if(src == user || !isturf(loc)) - return FALSE - if(anchored || throwing) - return FALSE - return TRUE - - -/obj/item/proc/do_pickup_animation(atom/target) - set waitfor = FALSE - if(!istype(loc, /turf)) - return - var/image/I = image(icon = src, loc = loc, layer = layer + 0.1) - I.plane = GAME_PLANE - I.transform *= 0.75 - I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA - var/turf/T = get_turf(src) - var/direction - var/to_x = 0 - var/to_y = 0 - - if(!QDELETED(T) && !QDELETED(target)) - direction = get_dir(T, target) - if(direction & NORTH) - to_y = 32 - else if(direction & SOUTH) - to_y = -32 - if(direction & EAST) - to_x = 32 - else if(direction & WEST) - to_x = -32 - if(!direction) - to_y = 16 - flick_overlay(I, GLOB.clients, 6) - var/matrix/M = new - M.Turn(pick(-30, 30)) - animate(I, alpha = 175, pixel_x = to_x, pixel_y = to_y, time = 3, transform = M, easing = CUBIC_EASING) - sleep(1) - animate(I, alpha = 0, transform = matrix(), time = 1) +/atom/movable + layer = OBJ_LAYER + var/last_move = null + var/last_move_time = 0 + var/anchored = FALSE + var/datum/thrownthing/throwing = null + var/throw_speed = 2 //How many tiles to move per ds when being thrown. Float values are fully supported + var/throw_range = 7 + var/mob/pulledby = null + var/initial_language_holder = /datum/language_holder + var/datum/language_holder/language_holder + var/verb_say = "says" + var/verb_ask = "asks" + var/verb_exclaim = "exclaims" + var/verb_whisper = "whispers" + var/verb_yell = "yells" + var/speech_span + var/inertia_dir = 0 + var/atom/inertia_last_loc + var/inertia_moving = 0 + var/inertia_next_move = 0 + var/inertia_move_delay = 5 + var/pass_flags = 0 + var/moving_diagonally = 0 //0: not doing a diagonal move. 1 and 2: doing the first/second step of the diagonal move + var/list/client_mobs_in_contents // This contains all the client mobs within this container + var/list/acted_explosions //for explosion dodging + glide_size = 8 + appearance_flags = TILE_BOUND|PIXEL_SCALE + var/datum/forced_movement/force_moving = null //handled soley by forced_movement.dm + var/movement_type = GROUND //Incase you have multiple types, you automatically use the most useful one. IE: Skating on ice, flippers on water, flying over chasm/space, etc. + var/atom/movable/pulling + var/grab_state = 0 + var/throwforce = 0 + var/datum/component/orbiter/orbiting + var/can_be_z_moved = TRUE + + var/zfalling = FALSE + +/atom/movable/proc/can_zFall(turf/source, levels = 1, turf/target, direction) + if(!direction) + direction = DOWN + if(!source) + source = get_turf(src) + if(!source) + return FALSE + if(!target) + target = get_step_multiz(source, direction) + if(!target) + return FALSE + return !(movement_type & FLYING) && has_gravity(source) && !throwing + +/atom/movable/proc/onZImpact(turf/T, levels) + var/atom/highest = T + for(var/i in T.contents) + var/atom/A = i + if(!A.density) + continue + if(isobj(A) || ismob(A)) + if(A.layer > highest.layer) + highest = A + INVOKE_ASYNC(src, .proc/SpinAnimation, 5, 2) + throw_impact(highest) + return TRUE + +//For physical constraints to travelling up/down. +/atom/movable/proc/can_zTravel(turf/destination, direction) + var/turf/T = get_turf(src) + if(!T) + return FALSE + if(!direction) + if(!destination) + return FALSE + direction = get_dir(T, destination) + if(direction != UP && direction != DOWN) + return FALSE + if(!destination) + destination = get_step_multiz(src, direction) + if(!destination) + return FALSE + return T.zPassOut(src, direction, destination) && destination.zPassIn(src, direction, T) + +/atom/movable/vv_edit_var(var_name, var_value) + var/static/list/banned_edits = list("step_x", "step_y", "step_size") + var/static/list/careful_edits = list("bound_x", "bound_y", "bound_width", "bound_height") + if(var_name in banned_edits) + return FALSE //PLEASE no. + if((var_name in careful_edits) && (var_value % world.icon_size) != 0) + return FALSE + switch(var_name) + if("x") + var/turf/T = locate(var_value, y, z) + if(T) + forceMove(T) + return TRUE + return FALSE + if("y") + var/turf/T = locate(x, var_value, z) + if(T) + forceMove(T) + return TRUE + return FALSE + if("z") + var/turf/T = locate(x, y, var_value) + if(T) + forceMove(T) + return TRUE + return FALSE + if("loc") + if(istype(var_value, /atom)) + forceMove(var_value) + return TRUE + else if(isnull(var_value)) + moveToNullspace() + return TRUE + return FALSE + return ..() + +/atom/movable/proc/start_pulling(atom/movable/AM,gs) + if(QDELETED(AM)) + return FALSE + if(!(AM.can_be_pulled(src))) + return FALSE + + // If we're pulling something then drop what we're currently pulling and pull this instead. + if(pulling) + if(gs==0) + stop_pulling() + return FALSE + // Are we trying to pull something we are already pulling? Then enter grab cycle and end. + if(AM == pulling) + grab_state = gs + if(istype(AM,/mob/living)) + var/mob/living/AMob = AM + AMob.grabbedby(src) + return TRUE + stop_pulling() + if(AM.pulledby) + log_combat(AM, AM.pulledby, "pulled from", src) + AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once. + pulling = AM + AM.pulledby = src + grab_state = gs + if(ismob(AM)) + var/mob/M = AM + log_combat(src, M, "grabbed", addition="passive grab") + visible_message("[src] has grabbed [M] passively!") + return TRUE + +/atom/movable/proc/stop_pulling() + if(pulling) + pulling.pulledby = null + var/mob/living/ex_pulled = pulling + pulling = null + grab_state = 0 + if(isliving(ex_pulled)) + var/mob/living/L = ex_pulled + L.update_canmove()// mob gets up if it was lyng down in a chokehold + +/atom/movable/proc/Move_Pulled(atom/A) + if(!pulling) + return + if(pulling.anchored || !pulling.Adjacent(src)) + stop_pulling() + return + if(isliving(pulling)) + var/mob/living/L = pulling + if(L.buckled && L.buckled.buckle_prevents_pull) //if they're buckled to something that disallows pulling, prevent it + stop_pulling() + return + if(A == loc && pulling.density) + return + if(!Process_Spacemove(get_dir(pulling.loc, A))) + return + step(pulling, get_dir(pulling.loc, A)) + +/atom/movable/proc/check_pulling() + if(pulling) + var/atom/movable/pullee = pulling + if(pullee && get_dist(src, pullee) > 1) + stop_pulling() + return + if(!isturf(loc)) + stop_pulling() + return + if(pullee && !isturf(pullee.loc) && pullee.loc != loc) //to be removed once all code that changes an object's loc uses forceMove(). + log_game("DEBUG:[src]'s pull on [pullee] wasn't broken despite [pullee] being in [pullee.loc]. Pull stopped manually.") + stop_pulling() + return + if(pulling.anchored) + stop_pulling() + return + +//////////////////////////////////////// +// Here's where we rewrite how byond handles movement except slightly different +// To be removed on step_ conversion +// All this work to prevent a second bump +/atom/movable/Move(atom/newloc, direct=0) + . = FALSE + if(!newloc || newloc == loc) + return + + if(!direct) + direct = get_dir(src, newloc) + setDir(direct) + + if(!loc.Exit(src, newloc)) + return + + if(!newloc.Enter(src, src.loc)) + return + + // Past this is the point of no return + var/atom/oldloc = loc + var/area/oldarea = get_area(oldloc) + var/area/newarea = get_area(newloc) + loc = newloc + . = TRUE + oldloc.Exited(src, newloc) + if(oldarea != newarea) + oldarea.Exited(src, newloc) + + for(var/i in oldloc) + if(i == src) // Multi tile objects + continue + var/atom/movable/thing = i + thing.Uncrossed(src) + + newloc.Entered(src, oldloc) + if(oldarea != newarea) + newarea.Entered(src, oldloc) + + for(var/i in loc) + if(i == src) // Multi tile objects + continue + var/atom/movable/thing = i + thing.Crossed(src) +// +//////////////////////////////////////// + +/atom/movable/Move(atom/newloc, direct) + var/atom/movable/pullee = pulling + var/turf/T = loc + if(pulling) + if(pullee && get_dist(src, pullee) > 1) + stop_pulling() + + if(pullee && pullee.loc != loc && !isturf(pullee.loc) ) //to be removed once all code that changes an object's loc uses forceMove(). + log_game("DEBUG:[src]'s pull on [pullee] wasn't broken despite [pullee] being in [pullee.loc]. Pull stopped manually.") + stop_pulling() + if(!loc || !newloc) + return FALSE + var/atom/oldloc = loc + + if(loc != newloc) + if (!(direct & (direct - 1))) //Cardinal move + . = ..() + else //Diagonal move, split it into cardinal moves + moving_diagonally = FIRST_DIAG_STEP + var/first_step_dir + // The `&& moving_diagonally` checks are so that a forceMove taking + // place due to a Crossed, Bumped, etc. call will interrupt + // the second half of the diagonal movement, or the second attempt + // at a first half if step() fails because we hit something. + if (direct & NORTH) + if (direct & EAST) + if (step(src, NORTH) && moving_diagonally) + first_step_dir = NORTH + moving_diagonally = SECOND_DIAG_STEP + . = step(src, EAST) + else if (moving_diagonally && step(src, EAST)) + first_step_dir = EAST + moving_diagonally = SECOND_DIAG_STEP + . = step(src, NORTH) + else if (direct & WEST) + if (step(src, NORTH) && moving_diagonally) + first_step_dir = NORTH + moving_diagonally = SECOND_DIAG_STEP + . = step(src, WEST) + else if (moving_diagonally && step(src, WEST)) + first_step_dir = WEST + moving_diagonally = SECOND_DIAG_STEP + . = step(src, NORTH) + else if (direct & SOUTH) + if (direct & EAST) + if (step(src, SOUTH) && moving_diagonally) + first_step_dir = SOUTH + moving_diagonally = SECOND_DIAG_STEP + . = step(src, EAST) + else if (moving_diagonally && step(src, EAST)) + first_step_dir = EAST + moving_diagonally = SECOND_DIAG_STEP + . = step(src, SOUTH) + else if (direct & WEST) + if (step(src, SOUTH) && moving_diagonally) + first_step_dir = SOUTH + moving_diagonally = SECOND_DIAG_STEP + . = step(src, WEST) + else if (moving_diagonally && step(src, WEST)) + first_step_dir = WEST + moving_diagonally = SECOND_DIAG_STEP + . = step(src, SOUTH) + if(moving_diagonally == SECOND_DIAG_STEP) + if(!.) + setDir(first_step_dir) + else if (!inertia_moving) + inertia_next_move = world.time + inertia_move_delay + newtonian_move(direct) + moving_diagonally = 0 + return + + if(!loc || (loc == oldloc && oldloc != newloc)) + last_move = 0 + return + + if(.) + Moved(oldloc, direct) + if(. && pulling && pulling == pullee) //we were pulling a thing and didn't lose it during our move. + if(pulling.anchored) + stop_pulling() + else + var/pull_dir = get_dir(src, pulling) + //puller and pullee more than one tile away or in diagonal position + if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir))) + pulling.Move(T, get_dir(pulling, T)) //the pullee tries to reach our previous position + if(pulling && get_dist(src, pulling) > 1) //the pullee couldn't keep up + stop_pulling() + if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1)//separated from our puller and not in the middle of a diagonal move. + pulledby.stop_pulling() + + + last_move = direct + setDir(direct) + if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc,direct)) //movement failed due to buckled mob(s) + return FALSE + +//Called after a successful Move(). By this point, we've already moved +/atom/movable/proc/Moved(atom/OldLoc, Dir, Forced = FALSE) + SEND_SIGNAL(src, COMSIG_MOVABLE_MOVED, OldLoc, Dir, Forced) + if (!inertia_moving) + inertia_next_move = world.time + inertia_move_delay + newtonian_move(Dir) + if (length(client_mobs_in_contents)) + update_parallax_contents() + + return TRUE + +/atom/movable/Destroy(force) + QDEL_NULL(proximity_monitor) + QDEL_NULL(language_holder) + + unbuckle_all_mobs(force=1) + + . = ..() + if(loc) + //Restore air flow if we were blocking it (movables with ATMOS_PASS_PROC will need to do this manually if necessary) + if(((CanAtmosPass == ATMOS_PASS_DENSITY && density) || CanAtmosPass == ATMOS_PASS_NO) && isturf(loc)) + CanAtmosPass = ATMOS_PASS_YES + air_update_turf(TRUE) + loc.handle_atom_del(src) + for(var/atom/movable/AM in contents) + qdel(AM) + moveToNullspace() + invisibility = INVISIBILITY_ABSTRACT + if(pulledby) + pulledby.stop_pulling() + + if(orbiting) + orbiting.end_orbit(src) + orbiting = null + +// Make sure you know what you're doing if you call this, this is intended to only be called by byond directly. +// You probably want CanPass() +/atom/movable/Cross(atom/movable/AM) + . = TRUE + SEND_SIGNAL(src, COMSIG_MOVABLE_CROSS, AM) + return CanPass(AM, AM.loc, TRUE) + +//oldloc = old location on atom, inserted when forceMove is called and ONLY when forceMove is called! +/atom/movable/Crossed(atom/movable/AM, oldloc) + SEND_SIGNAL(src, COMSIG_MOVABLE_CROSSED, AM) + +/atom/movable/Uncross(atom/movable/AM, atom/newloc) + . = ..() + if(SEND_SIGNAL(src, COMSIG_MOVABLE_UNCROSS, AM) & COMPONENT_MOVABLE_BLOCK_UNCROSS) + return FALSE + if(isturf(newloc) && !CheckExit(AM, newloc)) + return FALSE + +/atom/movable/Uncrossed(atom/movable/AM) + SEND_SIGNAL(src, COMSIG_MOVABLE_UNCROSSED, AM) + +/atom/movable/Bump(atom/A) + if(!A) + CRASH("Bump was called with no argument.") + SEND_SIGNAL(src, COMSIG_MOVABLE_BUMP, A) + . = ..() + if(!QDELETED(throwing)) + throwing.hit_atom(A) + . = TRUE + if(QDELETED(A)) + return + A.Bumped(src) + +/atom/movable/proc/forceMove(atom/destination) + . = FALSE + if(destination) + . = doMove(destination) + else + CRASH("No valid destination passed into forceMove") + +/atom/movable/proc/moveToNullspace() + return doMove(null) + +/atom/movable/proc/doMove(atom/destination) + . = FALSE + if(destination) + if(pulledby) + pulledby.stop_pulling() + var/atom/oldloc = loc + var/same_loc = oldloc == destination + var/area/old_area = get_area(oldloc) + var/area/destarea = get_area(destination) + + loc = destination + moving_diagonally = 0 + + if(!same_loc) + if(oldloc) + oldloc.Exited(src, destination) + if(old_area && old_area != destarea) + old_area.Exited(src, destination) + for(var/atom/movable/AM in oldloc) + AM.Uncrossed(src) + var/turf/oldturf = get_turf(oldloc) + var/turf/destturf = get_turf(destination) + var/old_z = (oldturf ? oldturf.z : null) + var/dest_z = (destturf ? destturf.z : null) + if (old_z != dest_z) + onTransitZ(old_z, dest_z) + destination.Entered(src, oldloc) + if(destarea && old_area != destarea) + destarea.Entered(src, oldloc) + + for(var/atom/movable/AM in destination) + if(AM == src) + continue + AM.Crossed(src, oldloc) + + Moved(oldloc, NONE, TRUE) + . = TRUE + + //If no destination, move the atom into nullspace (don't do this unless you know what you're doing) + else + . = TRUE + if (loc) + var/atom/oldloc = loc + var/area/old_area = get_area(oldloc) + oldloc.Exited(src, null) + if(old_area) + old_area.Exited(src, null) + loc = null + +/atom/movable/proc/onTransitZ(old_z,new_z) + SEND_SIGNAL(src, COMSIG_MOVABLE_Z_CHANGED, old_z, new_z) + for (var/item in src) // Notify contents of Z-transition. This can be overridden IF we know the items contents do not care. + var/atom/movable/AM = item + AM.onTransitZ(old_z,new_z) + +/atom/movable/proc/setMovetype(newval) + movement_type = newval + +//Called whenever an object moves and by mobs when they attempt to move themselves through space +//And when an object or action applies a force on src, see newtonian_move() below +//Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting +//Mobs should return 1 if they should be able to move of their own volition, see client/Move() in mob_movement.dm +//movement_dir == 0 when stopping or any dir when trying to move +/atom/movable/proc/Process_Spacemove(movement_dir = 0) + if(has_gravity(src)) + return 1 + + if(pulledby) + return 1 + + if(throwing) + return 1 + + if(!isturf(loc)) + return 1 + + if(locate(/obj/structure/lattice) in range(1, get_turf(src))) //Not realistic but makes pushing things in space easier + return 1 + + return 0 + + +/atom/movable/proc/newtonian_move(direction) //Only moves the object if it's under no gravity + if(!loc || Process_Spacemove(0)) + inertia_dir = 0 + return 0 + + inertia_dir = direction + if(!direction) + return 1 + inertia_last_loc = loc + SSspacedrift.processing[src] = src + return 1 + +/atom/movable/proc/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) + set waitfor = 0 + SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, hit_atom, throwingdatum) + return hit_atom.hitby(src) + +/atom/movable/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked) + if(!anchored && hitpush) + step(src, AM.dir) + ..() + +/atom/movable/proc/safe_throw_at(atom/target, range, speed, mob/thrower, spin=TRUE, diagonals_first = FALSE, var/datum/callback/callback, messy_throw = TRUE) + return throw_at(target, range, speed, thrower, spin, diagonals_first, callback, messy_throw) + +/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin=TRUE, diagonals_first = FALSE, var/datum/callback/callback, messy_throw = TRUE) //If this returns FALSE then callback will not be called. + . = FALSE + if (!target || speed <= 0) + return + + if(SEND_SIGNAL(src, COMSIG_MOVABLE_PRE_THROW, args) & COMPONENT_CANCEL_THROW) + return + + if (pulledby) + pulledby.stop_pulling() + + //They are moving! Wouldn't it be cool if we calculated their momentum and added it to the throw? + if (thrower && thrower.last_move && thrower.client && thrower.client.move_delay >= world.time + world.tick_lag*2) + var/user_momentum = thrower.movement_delay() + if (!user_momentum) //no movement_delay, this means they move once per byond tick, lets calculate from that instead. + user_momentum = world.tick_lag + + user_momentum = 1 / user_momentum // convert from ds to the tiles per ds that throw_at uses. + + if (get_dir(thrower, target) & last_move) + user_momentum = user_momentum //basically a noop, but needed + else if (get_dir(target, thrower) & last_move) + user_momentum = -user_momentum //we are moving away from the target, lets slowdown the throw accordingly + else + user_momentum = 0 + + + if (user_momentum) + //first lets add that momentum to range. + range *= (user_momentum / speed) + 1 + //then lets add it to speed + speed += user_momentum + if (speed <= 0) + return//no throw speed, the user was moving too fast. + + . = TRUE // No failure conditions past this point. + + var/datum/thrownthing/TT = new() + TT.thrownthing = src + TT.target = target + TT.target_turf = get_turf(target) + TT.init_dir = get_dir(src, target) + TT.maxrange = range + TT.speed = speed + TT.thrower = thrower + TT.diagonals_first = diagonals_first + TT.callback = callback + if(!QDELETED(thrower)) + TT.target_zone = thrower.zone_selected + + var/dist_x = abs(target.x - src.x) + var/dist_y = abs(target.y - src.y) + var/dx = (target.x > src.x) ? EAST : WEST + var/dy = (target.y > src.y) ? NORTH : SOUTH + + if (dist_x == dist_y) + TT.pure_diagonal = 1 + + else if(dist_x <= dist_y) + var/olddist_x = dist_x + var/olddx = dx + dist_x = dist_y + dist_y = olddist_x + dx = dy + dy = olddx + TT.dist_x = dist_x + TT.dist_y = dist_y + TT.dx = dx + TT.dy = dy + TT.diagonal_error = dist_x/2 - dist_y + TT.start_time = world.time + + if(pulledby) + pulledby.stop_pulling() + + throwing = TT + if(spin) + SpinAnimation(5, 1) + + SEND_SIGNAL(src, COMSIG_MOVABLE_POST_THROW, TT, spin) + SSthrowing.processing[src] = TT + if (SSthrowing.state == SS_PAUSED && length(SSthrowing.currentrun)) + SSthrowing.currentrun[src] = TT + TT.tick() + +/atom/movable/proc/handle_buckled_mob_movement(newloc,direct) + for(var/m in buckled_mobs) + var/mob/living/buckled_mob = m + if(!buckled_mob.Move(newloc, direct)) + forceMove(buckled_mob.loc) + last_move = buckled_mob.last_move + inertia_dir = last_move + buckled_mob.inertia_dir = last_move + return 0 + return 1 + +/atom/movable/CanPass(atom/movable/mover, turf/target) + if(mover in buckled_mobs) + return 1 + return ..() + +// called when this atom 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. +/atom/movable/proc/on_exit_storage(datum/component/storage/concrete/S) + return + +// called when this atom is added into a storage item, which is passed on as S. The loc variable is already set to the storage item. +/atom/movable/proc/on_enter_storage(datum/component/storage/concrete/S) + return + +/atom/movable/proc/get_spacemove_backup() + var/atom/movable/dense_object_backup + for(var/A in orange(1, get_turf(src))) + if(isarea(A)) + continue + else if(isturf(A)) + var/turf/turf = A + if(!turf.density) + continue + return turf + else + var/atom/movable/AM = A + if(!AM.CanPass(src) || AM.density) + if(AM.anchored) + return AM + dense_object_backup = AM + break + . = dense_object_backup + +//called when a mob resists while inside a container that is itself inside something. +/atom/movable/proc/relay_container_resist(mob/living/user, obj/O) + return + + +/atom/movable/proc/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect) + if(!no_effect && (visual_effect_icon || used_item)) + do_item_attack_animation(A, visual_effect_icon, used_item) + + if(A == src) + return //don't do an animation if attacking self + var/pixel_x_diff = 0 + var/pixel_y_diff = 0 + + var/direction = get_dir(src, A) + if(direction & NORTH) + pixel_y_diff = 8 + else if(direction & SOUTH) + pixel_y_diff = -8 + + if(direction & EAST) + pixel_x_diff = 8 + else if(direction & WEST) + pixel_x_diff = -8 + + var/matrix/OM = matrix(transform) + var/matrix/M = matrix(transform) + M.Turn(pixel_x_diff ? pixel_x_diff*2 : pick(-16, 16)) + + animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff, transform = M, time = 2) + animate(src, pixel_x = pixel_x - pixel_x_diff, pixel_y = pixel_y - pixel_y_diff, transform = OM, time = 2) + +/atom/movable/proc/do_item_attack_animation(atom/A, visual_effect_icon, obj/item/used_item) + var/image/I + if(visual_effect_icon) + I = image('icons/effects/effects.dmi', A, visual_effect_icon, A.layer + 0.1) + else if(used_item) + I = image(icon = used_item, loc = A, layer = A.layer + 0.1) + I.plane = GAME_PLANE + + // Scale the icon. + I.transform *= 0.75 + // The icon should not rotate. + I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA + + // Set the direction of the icon animation. + var/direction = get_dir(src, A) + if(direction & NORTH) + I.pixel_y = -16 + else if(direction & SOUTH) + I.pixel_y = 16 + + if(direction & EAST) + I.pixel_x = -16 + else if(direction & WEST) + I.pixel_x = 16 + + if(!direction) // Attacked self?! + I.pixel_z = 16 + + if(!I) + return + + flick_overlay(I, GLOB.clients, 5) // 5 ticks/half a second + + // And animate the attack! + animate(I, alpha = 175, pixel_x = 0, pixel_y = 0, pixel_z = 0, time = 3) + +/atom/movable/vv_get_dropdown() + . = ..() + . -= "Jump to" + .["Follow"] = "?_src_=holder;[HrefToken()];adminplayerobservefollow=[REF(src)]" + .["Get"] = "?_src_=holder;[HrefToken()];admingetmovable=[REF(src)]" + +/atom/movable/proc/ex_check(ex_id) + if(!ex_id) + return TRUE + LAZYINITLIST(acted_explosions) + if(ex_id in acted_explosions) + return FALSE + acted_explosions += ex_id + return TRUE + +//TODO: Better floating +/atom/movable/proc/float(on) + if(throwing) + return + if(on && !(movement_type & FLOATING)) + animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1) + sleep(10) + animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1) + setMovetype(movement_type | FLOATING) + else if (!on && (movement_type & FLOATING)) + animate(src, pixel_y = initial(pixel_y), time = 10) + setMovetype(movement_type & ~FLOATING) + +/* Language procs */ +/atom/movable/proc/get_language_holder(shadow=TRUE) + if(language_holder) + return language_holder + else + language_holder = new initial_language_holder(src) + return language_holder + +/atom/movable/proc/grant_language(datum/language/dt, body = FALSE) + var/datum/language_holder/H = get_language_holder(!body) + H.grant_language(dt, body) + +/atom/movable/proc/grant_all_languages(omnitongue=FALSE) + var/datum/language_holder/H = get_language_holder() + H.grant_all_languages(omnitongue) + +/atom/movable/proc/get_random_understood_language() + var/datum/language_holder/H = get_language_holder() + . = H.get_random_understood_language() + +/atom/movable/proc/remove_language(datum/language/dt, body = FALSE) + var/datum/language_holder/H = get_language_holder(!body) + H.remove_language(dt, body) + +/atom/movable/proc/remove_all_languages() + var/datum/language_holder/H = get_language_holder() + H.remove_all_languages() + +/atom/movable/proc/has_language(datum/language/dt) + var/datum/language_holder/H = get_language_holder() + . = H.has_language(dt) + +/atom/movable/proc/copy_known_languages_from(thing, replace=FALSE) + var/datum/language_holder/H = get_language_holder() + . = H.copy_known_languages_from(thing, replace) + +// Whether an AM can speak in a language or not, independent of whether +// it KNOWS the language +/atom/movable/proc/could_speak_in_language(datum/language/dt) + . = TRUE + +/atom/movable/proc/can_speak_in_language(datum/language/dt) + var/datum/language_holder/H = get_language_holder() + + if(!H.has_language(dt)) + return FALSE + else if(H.omnitongue) + return TRUE + else if(could_speak_in_language(dt) && (!H.only_speaks_language || H.only_speaks_language == dt)) + return TRUE + else + return FALSE + +/atom/movable/proc/get_default_language() + // if no language is specified, and we want to say() something, which + // language do we use? + var/datum/language_holder/H = get_language_holder() + + if(H.selected_default_language) + if(can_speak_in_language(H.selected_default_language)) + return H.selected_default_language + else + H.selected_default_language = null + + + var/datum/language/chosen_langtype + var/highest_priority + + for(var/lt in H.languages) + var/datum/language/langtype = lt + if(!can_speak_in_language(langtype)) + continue + + var/pri = initial(langtype.default_priority) + if(!highest_priority || (pri > highest_priority)) + chosen_langtype = langtype + highest_priority = pri + + H.selected_default_language = . + . = chosen_langtype + +/* End language procs */ +/atom/movable/proc/ConveyorMove(movedir) + set waitfor = FALSE + if(!anchored && has_gravity()) + step(src, movedir) + +//Returns an atom's power cell, if it has one. Overload for individual items. +/atom/movable/proc/get_cell() + return + +/atom/movable/proc/can_be_pulled(user) + if(src == user || !isturf(loc)) + return FALSE + if(anchored || throwing) + return FALSE + return TRUE + + +/obj/item/proc/do_pickup_animation(atom/target) + set waitfor = FALSE + if(!istype(loc, /turf)) + return + var/image/I = image(icon = src, loc = loc, layer = layer + 0.1) + I.plane = GAME_PLANE + I.transform *= 0.75 + I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA + var/turf/T = get_turf(src) + var/direction + var/to_x = 0 + var/to_y = 0 + + if(!QDELETED(T) && !QDELETED(target)) + direction = get_dir(T, target) + if(direction & NORTH) + to_y = 32 + else if(direction & SOUTH) + to_y = -32 + if(direction & EAST) + to_x = 32 + else if(direction & WEST) + to_x = -32 + if(!direction) + to_y = 16 + flick_overlay(I, GLOB.clients, 6) + var/matrix/M = new + M.Turn(pick(-30, 30)) + animate(I, alpha = 175, pixel_x = to_x, pixel_y = to_y, time = 3, transform = M, easing = CUBIC_EASING) + sleep(1) + animate(I, alpha = 0, transform = matrix(), time = 1) diff --git a/code/game/communications.dm b/code/game/communications.dm index ed470473d9..696b942434 100644 --- a/code/game/communications.dm +++ b/code/game/communications.dm @@ -1,199 +1,199 @@ -/* - HOW IT WORKS - - The SSradio is a global object maintaining all radio transmissions, think about it as about "ether". - Note that walkie-talkie, intercoms and headsets handle transmission using nonstandard way. - procs: - - add_object(obj/device as obj, var/new_frequency as num, var/filter as text|null = null) - Adds listening object. - parameters: - device - device receiving signals, must have proc receive_signal (see description below). - one device may listen several frequencies, but not same frequency twice. - new_frequency - see possibly frequencies below; - filter - thing for optimization. Optional, but recommended. - All filters should be consolidated in this file, see defines later. - Device without listening filter will receive all signals (on specified frequency). - Device with filter will receive any signals sent without filter. - Device with filter will not receive any signals sent with different filter. - returns: - Reference to frequency object. - - remove_object (obj/device, old_frequency) - Obliviously, after calling this proc, device will not receive any signals on old_frequency. - Other frequencies will left unaffected. - - return_frequency(var/frequency as num) - returns: - Reference to frequency object. Use it if you need to send and do not need to listen. - - radio_frequency is a global object maintaining list of devices that listening specific frequency. - procs: - - post_signal(obj/source as obj|null, datum/signal/signal, var/filter as text|null = null, var/range as num|null = null) - Sends signal to all devices that wants such signal. - parameters: - source - object, emitted signal. Usually, devices will not receive their own signals. - signal - see description below. - filter - described above. - range - radius of regular byond's square circle on that z-level. null means everywhere, on all z-levels. - - obj/proc/receive_signal(datum/signal/signal, var/receive_method as num, var/receive_param) - Handler from received signals. By default does nothing. Define your own for your object. - Avoid of sending signals directly from this proc, use spawn(0). Do not use sleep() here please. - parameters: - signal - see description below. Extract all needed data from the signal before doing sleep(), spawn() or return! - receive_method - may be TRANSMISSION_WIRE or TRANSMISSION_RADIO. - TRANSMISSION_WIRE is currently unused. - receive_param - for TRANSMISSION_RADIO here comes frequency. - - datum/signal - vars: - source - an object that emitted signal. Used for debug and bearing. - data - list with transmitting data. Usual use pattern: - data["msg"] = "hello world" - encryption - Some number symbolizing "encryption key". - Note that game actually do not use any cryptography here. - If receiving object don't know right key, it must ignore encrypted signal in its receive_signal. - -*/ -/* the radio controller is a confusing piece of shit and didnt work - so i made radios not use the radio controller. -*/ -GLOBAL_LIST_EMPTY(all_radios) -/proc/add_radio(obj/item/radio, freq) - if(!freq || !radio) - return - if(!GLOB.all_radios["[freq]"]) - GLOB.all_radios["[freq]"] = list(radio) - return freq - - GLOB.all_radios["[freq]"] |= radio - return freq - -/proc/remove_radio(obj/item/radio, freq) - if(!freq || !radio) - return - if(!GLOB.all_radios["[freq]"]) - return - - GLOB.all_radios["[freq]"] -= radio - -/proc/remove_radio_all(obj/item/radio) - for(var/freq in GLOB.all_radios) - GLOB.all_radios["[freq]"] -= radio - -// For information on what objects or departments use what frequencies, -// see __DEFINES/radio.dm. Mappers may also select additional frequencies for -// use in maps, such as in intercoms. - -GLOBAL_LIST_INIT(radiochannels, list( - RADIO_CHANNEL_COMMON = FREQ_COMMON, - RADIO_CHANNEL_SCIENCE = FREQ_SCIENCE, - RADIO_CHANNEL_COMMAND = FREQ_COMMAND, - RADIO_CHANNEL_MEDICAL = FREQ_MEDICAL, - RADIO_CHANNEL_ENGINEERING = FREQ_ENGINEERING, - RADIO_CHANNEL_SECURITY = FREQ_SECURITY, - RADIO_CHANNEL_CENTCOM = FREQ_CENTCOM, - RADIO_CHANNEL_SYNDICATE = FREQ_SYNDICATE, - RADIO_CHANNEL_SUPPLY = FREQ_SUPPLY, - RADIO_CHANNEL_SERVICE = FREQ_SERVICE, - RADIO_CHANNEL_AI_PRIVATE = FREQ_AI_PRIVATE, - RADIO_CHANNEL_CTF_RED = FREQ_CTF_RED, - RADIO_CHANNEL_CTF_BLUE = FREQ_CTF_BLUE -)) - -GLOBAL_LIST_INIT(reverseradiochannels, list( - "[FREQ_COMMON]" = RADIO_CHANNEL_COMMON, - "[FREQ_SCIENCE]" = RADIO_CHANNEL_SCIENCE, - "[FREQ_COMMAND]" = RADIO_CHANNEL_COMMAND, - "[FREQ_MEDICAL]" = RADIO_CHANNEL_MEDICAL, - "[FREQ_ENGINEERING]" = RADIO_CHANNEL_ENGINEERING, - "[FREQ_SECURITY]" = RADIO_CHANNEL_SECURITY, - "[FREQ_CENTCOM]" = RADIO_CHANNEL_CENTCOM, - "[FREQ_SYNDICATE]" = RADIO_CHANNEL_SYNDICATE, - "[FREQ_SUPPLY]" = RADIO_CHANNEL_SUPPLY, - "[FREQ_SERVICE]" = RADIO_CHANNEL_SERVICE, - "[FREQ_AI_PRIVATE]" = RADIO_CHANNEL_AI_PRIVATE, - "[FREQ_CTF_RED]" = RADIO_CHANNEL_CTF_RED, - "[FREQ_CTF_BLUE]" = RADIO_CHANNEL_CTF_BLUE -)) - -/datum/radio_frequency - var/frequency as num - var/list/list/obj/devices = list() - -/datum/radio_frequency/New(freq) - frequency = freq - -//If range > 0, only post to devices on the same z_level and within range -//Use range = -1, to restrain to the same z_level without limiting range -/datum/radio_frequency/proc/post_signal(obj/source as obj|null, datum/signal/signal, filter = null as text|null, range = null as num|null) - // Ensure the signal's data is fully filled - signal.source = source - signal.frequency = frequency - - //Apply filter to the signal. If none supply, broadcast to every devices - //_default channel is always checked - var/list/filter_list - - if(filter) - filter_list = list(filter,"_default") - else - filter_list = devices - - //If checking range, find the source turf - var/turf/start_point - if(range) - start_point = get_turf(source) - if(!start_point) - return 0 - - //Send the data - for(var/current_filter in filter_list) - for(var/obj/device in devices[current_filter]) - if(device == source) - continue - if(range) - var/turf/end_point = get_turf(device) - if(!end_point) - continue - if(start_point.z != end_point.z || (range > 0 && get_dist(start_point, end_point) > range)) - continue - device.receive_signal(signal) - -/datum/radio_frequency/proc/add_listener(obj/device, filter as text|null) - if (!filter) - filter = "_default" - - var/list/devices_line = devices[filter] - if(!devices_line) - devices[filter] = devices_line = list() - devices_line += device - - -/datum/radio_frequency/proc/remove_listener(obj/device) - for(var/devices_filter in devices) - var/list/devices_line = devices[devices_filter] - if(!devices_line) - devices -= devices_filter - devices_line -= device - if(!devices_line.len) - devices -= devices_filter - - -/obj/proc/receive_signal(datum/signal/signal) - return - -/datum/signal - var/obj/source - var/frequency = 0 - var/transmission_method - var/list/data - -/datum/signal/New(data, transmission_method = TRANSMISSION_RADIO) - src.data = data || list() - src.transmission_method = transmission_method +/* + HOW IT WORKS + + The SSradio is a global object maintaining all radio transmissions, think about it as about "ether". + Note that walkie-talkie, intercoms and headsets handle transmission using nonstandard way. + procs: + + add_object(obj/device as obj, var/new_frequency as num, var/filter as text|null = null) + Adds listening object. + parameters: + device - device receiving signals, must have proc receive_signal (see description below). + one device may listen several frequencies, but not same frequency twice. + new_frequency - see possibly frequencies below; + filter - thing for optimization. Optional, but recommended. + All filters should be consolidated in this file, see defines later. + Device without listening filter will receive all signals (on specified frequency). + Device with filter will receive any signals sent without filter. + Device with filter will not receive any signals sent with different filter. + returns: + Reference to frequency object. + + remove_object (obj/device, old_frequency) + Obliviously, after calling this proc, device will not receive any signals on old_frequency. + Other frequencies will left unaffected. + + return_frequency(var/frequency as num) + returns: + Reference to frequency object. Use it if you need to send and do not need to listen. + + radio_frequency is a global object maintaining list of devices that listening specific frequency. + procs: + + post_signal(obj/source as obj|null, datum/signal/signal, var/filter as text|null = null, var/range as num|null = null) + Sends signal to all devices that wants such signal. + parameters: + source - object, emitted signal. Usually, devices will not receive their own signals. + signal - see description below. + filter - described above. + range - radius of regular byond's square circle on that z-level. null means everywhere, on all z-levels. + + obj/proc/receive_signal(datum/signal/signal, var/receive_method as num, var/receive_param) + Handler from received signals. By default does nothing. Define your own for your object. + Avoid of sending signals directly from this proc, use spawn(0). Do not use sleep() here please. + parameters: + signal - see description below. Extract all needed data from the signal before doing sleep(), spawn() or return! + receive_method - may be TRANSMISSION_WIRE or TRANSMISSION_RADIO. + TRANSMISSION_WIRE is currently unused. + receive_param - for TRANSMISSION_RADIO here comes frequency. + + datum/signal + vars: + source + an object that emitted signal. Used for debug and bearing. + data + list with transmitting data. Usual use pattern: + data["msg"] = "hello world" + encryption + Some number symbolizing "encryption key". + Note that game actually do not use any cryptography here. + If receiving object don't know right key, it must ignore encrypted signal in its receive_signal. + +*/ +/* the radio controller is a confusing piece of shit and didnt work + so i made radios not use the radio controller. +*/ +GLOBAL_LIST_EMPTY(all_radios) +/proc/add_radio(obj/item/radio, freq) + if(!freq || !radio) + return + if(!GLOB.all_radios["[freq]"]) + GLOB.all_radios["[freq]"] = list(radio) + return freq + + GLOB.all_radios["[freq]"] |= radio + return freq + +/proc/remove_radio(obj/item/radio, freq) + if(!freq || !radio) + return + if(!GLOB.all_radios["[freq]"]) + return + + GLOB.all_radios["[freq]"] -= radio + +/proc/remove_radio_all(obj/item/radio) + for(var/freq in GLOB.all_radios) + GLOB.all_radios["[freq]"] -= radio + +// For information on what objects or departments use what frequencies, +// see __DEFINES/radio.dm. Mappers may also select additional frequencies for +// use in maps, such as in intercoms. + +GLOBAL_LIST_INIT(radiochannels, list( + RADIO_CHANNEL_COMMON = FREQ_COMMON, + RADIO_CHANNEL_SCIENCE = FREQ_SCIENCE, + RADIO_CHANNEL_COMMAND = FREQ_COMMAND, + RADIO_CHANNEL_MEDICAL = FREQ_MEDICAL, + RADIO_CHANNEL_ENGINEERING = FREQ_ENGINEERING, + RADIO_CHANNEL_SECURITY = FREQ_SECURITY, + RADIO_CHANNEL_CENTCOM = FREQ_CENTCOM, + RADIO_CHANNEL_SYNDICATE = FREQ_SYNDICATE, + RADIO_CHANNEL_SUPPLY = FREQ_SUPPLY, + RADIO_CHANNEL_SERVICE = FREQ_SERVICE, + RADIO_CHANNEL_AI_PRIVATE = FREQ_AI_PRIVATE, + RADIO_CHANNEL_CTF_RED = FREQ_CTF_RED, + RADIO_CHANNEL_CTF_BLUE = FREQ_CTF_BLUE +)) + +GLOBAL_LIST_INIT(reverseradiochannels, list( + "[FREQ_COMMON]" = RADIO_CHANNEL_COMMON, + "[FREQ_SCIENCE]" = RADIO_CHANNEL_SCIENCE, + "[FREQ_COMMAND]" = RADIO_CHANNEL_COMMAND, + "[FREQ_MEDICAL]" = RADIO_CHANNEL_MEDICAL, + "[FREQ_ENGINEERING]" = RADIO_CHANNEL_ENGINEERING, + "[FREQ_SECURITY]" = RADIO_CHANNEL_SECURITY, + "[FREQ_CENTCOM]" = RADIO_CHANNEL_CENTCOM, + "[FREQ_SYNDICATE]" = RADIO_CHANNEL_SYNDICATE, + "[FREQ_SUPPLY]" = RADIO_CHANNEL_SUPPLY, + "[FREQ_SERVICE]" = RADIO_CHANNEL_SERVICE, + "[FREQ_AI_PRIVATE]" = RADIO_CHANNEL_AI_PRIVATE, + "[FREQ_CTF_RED]" = RADIO_CHANNEL_CTF_RED, + "[FREQ_CTF_BLUE]" = RADIO_CHANNEL_CTF_BLUE +)) + +/datum/radio_frequency + var/frequency as num + var/list/list/obj/devices = list() + +/datum/radio_frequency/New(freq) + frequency = freq + +//If range > 0, only post to devices on the same z_level and within range +//Use range = -1, to restrain to the same z_level without limiting range +/datum/radio_frequency/proc/post_signal(obj/source as obj|null, datum/signal/signal, filter = null as text|null, range = null as num|null) + // Ensure the signal's data is fully filled + signal.source = source + signal.frequency = frequency + + //Apply filter to the signal. If none supply, broadcast to every devices + //_default channel is always checked + var/list/filter_list + + if(filter) + filter_list = list(filter,"_default") + else + filter_list = devices + + //If checking range, find the source turf + var/turf/start_point + if(range) + start_point = get_turf(source) + if(!start_point) + return 0 + + //Send the data + for(var/current_filter in filter_list) + for(var/obj/device in devices[current_filter]) + if(device == source) + continue + if(range) + var/turf/end_point = get_turf(device) + if(!end_point) + continue + if(start_point.z != end_point.z || (range > 0 && get_dist(start_point, end_point) > range)) + continue + device.receive_signal(signal) + +/datum/radio_frequency/proc/add_listener(obj/device, filter as text|null) + if (!filter) + filter = "_default" + + var/list/devices_line = devices[filter] + if(!devices_line) + devices[filter] = devices_line = list() + devices_line += device + + +/datum/radio_frequency/proc/remove_listener(obj/device) + for(var/devices_filter in devices) + var/list/devices_line = devices[devices_filter] + if(!devices_line) + devices -= devices_filter + devices_line -= device + if(!devices_line.len) + devices -= devices_filter + + +/obj/proc/receive_signal(datum/signal/signal) + return + +/datum/signal + var/obj/source + var/frequency = 0 + var/transmission_method + var/list/data + +/datum/signal/New(data, transmission_method = TRANSMISSION_RADIO) + src.data = data || list() + src.transmission_method = transmission_method diff --git a/code/game/gamemodes/brother/traitor_bro.dm b/code/game/gamemodes/brother/traitor_bro.dm index 8bbe7f54ed..df4a38cf60 100644 --- a/code/game/gamemodes/brother/traitor_bro.dm +++ b/code/game/gamemodes/brother/traitor_bro.dm @@ -1,72 +1,72 @@ -/datum/game_mode - var/list/datum/mind/brothers = list() - var/list/datum/team/brother_team/brother_teams = list() - -/datum/game_mode/traitor/bros - name = "traitor+brothers" - config_tag = "traitorbro" - restricted_jobs = list("AI", "Cyborg") - protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") - - announce_span = "danger" - announce_text = "There are Syndicate agents and Blood Brothers on the station!\n\ - Traitors: Accomplish your objectives.\n\ - Blood Brothers: Accomplish your objectives.\n\ - Crew: Do not let the traitors or brothers succeed!" - - var/list/datum/team/brother_team/pre_brother_teams = list() - var/const/team_amount = 2 //hard limit on brother teams if scaling is turned off - var/const/min_team_size = 2 - traitors_required = FALSE //Only teams are possible - -/datum/game_mode/traitor/bros/pre_setup() - if(CONFIG_GET(flag/protect_roles_from_antagonist)) - restricted_jobs += protected_jobs - if(CONFIG_GET(flag/protect_assistant_from_antagonist)) - restricted_jobs += "Assistant" - - var/list/datum/mind/possible_brothers = get_players_for_role(ROLE_BROTHER) - - var/num_teams = team_amount - var/bsc = CONFIG_GET(number/brother_scaling_coeff) - if(bsc) - num_teams = max(1, round(num_players() / bsc)) - - for(var/j = 1 to num_teams) - if(possible_brothers.len < min_team_size || antag_candidates.len <= required_enemies) - break - var/datum/team/brother_team/team = new - var/team_size = prob(10) ? min(3, possible_brothers.len) : 2 - for(var/k = 1 to team_size) - var/datum/mind/bro = antag_pick(possible_brothers) - possible_brothers -= bro - antag_candidates -= bro - team.add_member(bro) - bro.special_role = "brother" - bro.restricted_roles = restricted_jobs - log_game("[key_name(bro)] has been selected as a Brother") - pre_brother_teams += team - return ..() - -/datum/game_mode/traitor/bros/post_setup() - for(var/datum/team/brother_team/team in pre_brother_teams) - team.pick_meeting_area() - team.forge_brother_objectives() - for(var/datum/mind/M in team.members) - M.add_antag_datum(/datum/antagonist/brother, team) - team.update_name() - brother_teams += pre_brother_teams - return ..() - -/datum/game_mode/traitor/bros/generate_report() - return "It's Syndicate recruiting season. Be alert for potential Syndicate infiltrators, but also watch out for disgruntled employees trying to defect. Unlike Nanotrasen, the Syndicate prides itself in teamwork and will only recruit pairs that share a brotherly trust." - -/datum/game_mode/proc/update_brother_icons_added(datum/mind/brother_mind) - var/datum/atom_hud/antag/brotherhud = GLOB.huds[ANTAG_HUD_BROTHER] - brotherhud.join_hud(brother_mind.current) - set_antag_hud(brother_mind.current, "brother") - -/datum/game_mode/proc/update_brother_icons_removed(datum/mind/brother_mind) - var/datum/atom_hud/antag/brotherhud = GLOB.huds[ANTAG_HUD_BROTHER] - brotherhud.leave_hud(brother_mind.current) - set_antag_hud(brother_mind.current, null) +/datum/game_mode + var/list/datum/mind/brothers = list() + var/list/datum/team/brother_team/brother_teams = list() + +/datum/game_mode/traitor/bros + name = "traitor+brothers" + config_tag = "traitorbro" + restricted_jobs = list("AI", "Cyborg") + protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") + + announce_span = "danger" + announce_text = "There are Syndicate agents and Blood Brothers on the station!\n\ + Traitors: Accomplish your objectives.\n\ + Blood Brothers: Accomplish your objectives.\n\ + Crew: Do not let the traitors or brothers succeed!" + + var/list/datum/team/brother_team/pre_brother_teams = list() + var/const/team_amount = 2 //hard limit on brother teams if scaling is turned off + var/const/min_team_size = 2 + traitors_required = FALSE //Only teams are possible + +/datum/game_mode/traitor/bros/pre_setup() + if(CONFIG_GET(flag/protect_roles_from_antagonist)) + restricted_jobs += protected_jobs + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) + restricted_jobs += "Assistant" + + var/list/datum/mind/possible_brothers = get_players_for_role(ROLE_BROTHER) + + var/num_teams = team_amount + var/bsc = CONFIG_GET(number/brother_scaling_coeff) + if(bsc) + num_teams = max(1, round(num_players() / bsc)) + + for(var/j = 1 to num_teams) + if(possible_brothers.len < min_team_size || antag_candidates.len <= required_enemies) + break + var/datum/team/brother_team/team = new + var/team_size = prob(10) ? min(3, possible_brothers.len) : 2 + for(var/k = 1 to team_size) + var/datum/mind/bro = antag_pick(possible_brothers) + possible_brothers -= bro + antag_candidates -= bro + team.add_member(bro) + bro.special_role = "brother" + bro.restricted_roles = restricted_jobs + log_game("[key_name(bro)] has been selected as a Brother") + pre_brother_teams += team + return ..() + +/datum/game_mode/traitor/bros/post_setup() + for(var/datum/team/brother_team/team in pre_brother_teams) + team.pick_meeting_area() + team.forge_brother_objectives() + for(var/datum/mind/M in team.members) + M.add_antag_datum(/datum/antagonist/brother, team) + team.update_name() + brother_teams += pre_brother_teams + return ..() + +/datum/game_mode/traitor/bros/generate_report() + return "It's Syndicate recruiting season. Be alert for potential Syndicate infiltrators, but also watch out for disgruntled employees trying to defect. Unlike Nanotrasen, the Syndicate prides itself in teamwork and will only recruit pairs that share a brotherly trust." + +/datum/game_mode/proc/update_brother_icons_added(datum/mind/brother_mind) + var/datum/atom_hud/antag/brotherhud = GLOB.huds[ANTAG_HUD_BROTHER] + brotherhud.join_hud(brother_mind.current) + set_antag_hud(brother_mind.current, "brother") + +/datum/game_mode/proc/update_brother_icons_removed(datum/mind/brother_mind) + var/datum/atom_hud/antag/brotherhud = GLOB.huds[ANTAG_HUD_BROTHER] + brotherhud.leave_hud(brother_mind.current) + set_antag_hud(brother_mind.current, null) diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm index d6131ce58e..14fe960422 100644 --- a/code/game/gamemodes/changeling/changeling.dm +++ b/code/game/gamemodes/changeling/changeling.dm @@ -1,127 +1,127 @@ -GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","Epsilon","Zeta","Eta","Theta","Iota","Kappa","Lambda","Mu","Nu","Xi","Omicron","Pi","Rho","Sigma","Tau","Upsilon","Phi","Chi","Psi","Omega")) -GLOBAL_LIST_INIT(slots, list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store")) -GLOBAL_LIST_INIT(slot2slot, list("head" = SLOT_HEAD, "wear_mask" = SLOT_WEAR_MASK, "neck" = SLOT_NECK, "back" = SLOT_BACK, "wear_suit" = SLOT_WEAR_SUIT, "w_uniform" = SLOT_W_UNIFORM, "shoes" = SLOT_SHOES, "belt" = SLOT_BELT, "gloves" = SLOT_GLOVES, "glasses" = SLOT_GLASSES, "ears" = SLOT_EARS, "wear_id" = SLOT_WEAR_ID, "s_store" = SLOT_S_STORE)) -GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "wear_mask" = /obj/item/clothing/mask/changeling, "back" = /obj/item/changeling, "wear_suit" = /obj/item/clothing/suit/changeling, "w_uniform" = /obj/item/clothing/under/changeling, "shoes" = /obj/item/clothing/shoes/changeling, "belt" = /obj/item/changeling, "gloves" = /obj/item/clothing/gloves/changeling, "glasses" = /obj/item/clothing/glasses/changeling, "ears" = /obj/item/changeling, "wear_id" = /obj/item/changeling, "s_store" = /obj/item/changeling)) -GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our this objective to all lings - - -/datum/game_mode/changeling - name = "changeling" - config_tag = "changeling" - antag_flag = ROLE_CHANGELING - false_report_weight = 10 - restricted_jobs = list("AI", "Cyborg") - protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") //citadel change - adds HoP, CE, CMO, and RD to ling role blacklist - required_players = 15 - required_enemies = 1 - recommended_enemies = 4 - reroll_friendly = 1 - - announce_span = "green" - announce_text = "Alien changelings have infiltrated the crew!\n\ - Changelings: Accomplish the objectives assigned to you.\n\ - Crew: Root out and eliminate the changeling menace." - - var/const/changeling_amount = 4 //hard limit on changelings if scaling is turned off - var/list/changelings = list() - -/datum/game_mode/changeling/pre_setup() - - if(CONFIG_GET(flag/protect_roles_from_antagonist)) - restricted_jobs += protected_jobs - - if(CONFIG_GET(flag/protect_assistant_from_antagonist)) - restricted_jobs += "Assistant" - - var/num_changelings = 1 - - var/csc = CONFIG_GET(number/changeling_scaling_coeff) - if(csc) - num_changelings = max(1, min(round(num_players() / (csc * 2)) + 2, round(num_players() / csc))) - else - num_changelings = max(1, min(num_players(), changeling_amount)) - - if(antag_candidates.len>0) - for(var/i = 0, i < num_changelings, i++) - if(!antag_candidates.len) - break - var/datum/mind/changeling = antag_pick(antag_candidates) - antag_candidates -= changeling - changelings += changeling - changeling.special_role = ROLE_CHANGELING - changeling.restricted_roles = restricted_jobs - return 1 - else - setup_error = "Not enough changeling candidates" - return 0 - -/datum/game_mode/changeling/post_setup() - for(var/datum/mind/changeling in changelings) - log_game("[key_name(changeling)] has been selected as a changeling") - var/datum/antagonist/changeling/new_antag = new() - new_antag.team_mode = TRUE - changeling.add_antag_datum(new_antag) - ..() - -/datum/game_mode/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners - var/csc = CONFIG_GET(number/changeling_scaling_coeff) - var/changelingcap = min(round(GLOB.joined_player_list.len / (csc * 2)) + 2, round(GLOB.joined_player_list.len / csc)) - if(changelings.len >= changelingcap) //Caps number of latejoin antagonists - return - if(changelings.len <= (changelingcap - 2) || prob(100 - (csc * 2))) - if(ROLE_CHANGELING in character.client.prefs.be_special) - if(!jobban_isbanned(character, ROLE_CHANGELING) && !QDELETED(character) && !jobban_isbanned(character, ROLE_SYNDICATE) && !QDELETED(character)) - if(age_check(character.client)) - if(!(character.job in restricted_jobs)) - character.mind.make_Changeling() - changelings += character.mind - -/datum/game_mode/changeling/generate_report() - return "The Gorlex Marauders have announced the successful raid and destruction of Central Command containment ship #S-[rand(1111, 9999)]. This ship housed only a single prisoner - \ - codenamed \"Thing\", and it was highly adaptive and extremely dangerous. We have reason to believe that the Thing has allied with the Syndicate, and you should note that likelihood \ - of the Thing being sent to a station in this sector is highly likely. It may be in the guise of any crew member. Trust nobody - suspect everybody. Do not announce this to the crew, \ - as paranoia may spread and inhibit workplace efficiency." - -/proc/changeling_transform(mob/living/carbon/human/user, datum/changelingprofile/chosen_prof) - var/datum/dna/chosen_dna = chosen_prof.dna - user.real_name = chosen_prof.name - user.underwear = chosen_prof.underwear - user.undie_color = chosen_prof.undie_color - user.undershirt = chosen_prof.undershirt - user.shirt_color =chosen_prof.shirt_color - user.socks = chosen_prof.socks - user.socks_color =chosen_prof.socks_color - - chosen_dna.transfer_identity(user, 1) - user.updateappearance(mutcolor_update=1) - user.update_body() - user.domutcheck() - - //vars hackery. not pretty, but better than the alternative. - for(var/slot in GLOB.slots) - if(istype(user.vars[slot], GLOB.slot2type[slot]) && !(chosen_prof.exists_list[slot])) //remove unnecessary flesh items - qdel(user.vars[slot]) - continue - - if((user.vars[slot] && !istype(user.vars[slot], GLOB.slot2type[slot])) || !(chosen_prof.exists_list[slot])) - continue - - var/obj/item/C - var/equip = 0 - if(!user.vars[slot]) - var/thetype = GLOB.slot2type[slot] - equip = 1 - C = new thetype(user) - - else if(istype(user.vars[slot], GLOB.slot2type[slot])) - C = user.vars[slot] - - C.appearance = chosen_prof.appearance_list[slot] - C.name = chosen_prof.name_list[slot] - C.flags_cover = chosen_prof.flags_cover_list[slot] - C.item_color = chosen_prof.item_color_list[slot] - C.item_state = chosen_prof.item_state_list[slot] - if(equip) - user.equip_to_slot_or_del(C, GLOB.slot2slot[slot]) - - user.regenerate_icons() +GLOBAL_LIST_INIT(possible_changeling_IDs, list("Alpha","Beta","Gamma","Delta","Epsilon","Zeta","Eta","Theta","Iota","Kappa","Lambda","Mu","Nu","Xi","Omicron","Pi","Rho","Sigma","Tau","Upsilon","Phi","Chi","Psi","Omega")) +GLOBAL_LIST_INIT(slots, list("head", "wear_mask", "back", "wear_suit", "w_uniform", "shoes", "belt", "gloves", "glasses", "ears", "wear_id", "s_store")) +GLOBAL_LIST_INIT(slot2slot, list("head" = SLOT_HEAD, "wear_mask" = SLOT_WEAR_MASK, "neck" = SLOT_NECK, "back" = SLOT_BACK, "wear_suit" = SLOT_WEAR_SUIT, "w_uniform" = SLOT_W_UNIFORM, "shoes" = SLOT_SHOES, "belt" = SLOT_BELT, "gloves" = SLOT_GLOVES, "glasses" = SLOT_GLASSES, "ears" = SLOT_EARS, "wear_id" = SLOT_WEAR_ID, "s_store" = SLOT_S_STORE)) +GLOBAL_LIST_INIT(slot2type, list("head" = /obj/item/clothing/head/changeling, "wear_mask" = /obj/item/clothing/mask/changeling, "back" = /obj/item/changeling, "wear_suit" = /obj/item/clothing/suit/changeling, "w_uniform" = /obj/item/clothing/under/changeling, "shoes" = /obj/item/clothing/shoes/changeling, "belt" = /obj/item/changeling, "gloves" = /obj/item/clothing/gloves/changeling, "glasses" = /obj/item/clothing/glasses/changeling, "ears" = /obj/item/changeling, "wear_id" = /obj/item/changeling, "s_store" = /obj/item/changeling)) +GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our this objective to all lings + + +/datum/game_mode/changeling + name = "changeling" + config_tag = "changeling" + antag_flag = ROLE_CHANGELING + false_report_weight = 10 + restricted_jobs = list("AI", "Cyborg") + protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") //citadel change - adds HoP, CE, CMO, and RD to ling role blacklist + required_players = 15 + required_enemies = 1 + recommended_enemies = 4 + reroll_friendly = 1 + + announce_span = "green" + announce_text = "Alien changelings have infiltrated the crew!\n\ + Changelings: Accomplish the objectives assigned to you.\n\ + Crew: Root out and eliminate the changeling menace." + + var/const/changeling_amount = 4 //hard limit on changelings if scaling is turned off + var/list/changelings = list() + +/datum/game_mode/changeling/pre_setup() + + if(CONFIG_GET(flag/protect_roles_from_antagonist)) + restricted_jobs += protected_jobs + + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) + restricted_jobs += "Assistant" + + var/num_changelings = 1 + + var/csc = CONFIG_GET(number/changeling_scaling_coeff) + if(csc) + num_changelings = max(1, min(round(num_players() / (csc * 2)) + 2, round(num_players() / csc))) + else + num_changelings = max(1, min(num_players(), changeling_amount)) + + if(antag_candidates.len>0) + for(var/i = 0, i < num_changelings, i++) + if(!antag_candidates.len) + break + var/datum/mind/changeling = antag_pick(antag_candidates) + antag_candidates -= changeling + changelings += changeling + changeling.special_role = ROLE_CHANGELING + changeling.restricted_roles = restricted_jobs + return 1 + else + setup_error = "Not enough changeling candidates" + return 0 + +/datum/game_mode/changeling/post_setup() + for(var/datum/mind/changeling in changelings) + log_game("[key_name(changeling)] has been selected as a changeling") + var/datum/antagonist/changeling/new_antag = new() + new_antag.team_mode = TRUE + changeling.add_antag_datum(new_antag) + ..() + +/datum/game_mode/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners + var/csc = CONFIG_GET(number/changeling_scaling_coeff) + var/changelingcap = min(round(GLOB.joined_player_list.len / (csc * 2)) + 2, round(GLOB.joined_player_list.len / csc)) + if(changelings.len >= changelingcap) //Caps number of latejoin antagonists + return + if(changelings.len <= (changelingcap - 2) || prob(100 - (csc * 2))) + if(ROLE_CHANGELING in character.client.prefs.be_special) + if(!jobban_isbanned(character, ROLE_CHANGELING) && !QDELETED(character) && !jobban_isbanned(character, ROLE_SYNDICATE) && !QDELETED(character)) + if(age_check(character.client)) + if(!(character.job in restricted_jobs)) + character.mind.make_Changeling() + changelings += character.mind + +/datum/game_mode/changeling/generate_report() + return "The Gorlex Marauders have announced the successful raid and destruction of Central Command containment ship #S-[rand(1111, 9999)]. This ship housed only a single prisoner - \ + codenamed \"Thing\", and it was highly adaptive and extremely dangerous. We have reason to believe that the Thing has allied with the Syndicate, and you should note that likelihood \ + of the Thing being sent to a station in this sector is highly likely. It may be in the guise of any crew member. Trust nobody - suspect everybody. Do not announce this to the crew, \ + as paranoia may spread and inhibit workplace efficiency." + +/proc/changeling_transform(mob/living/carbon/human/user, datum/changelingprofile/chosen_prof) + var/datum/dna/chosen_dna = chosen_prof.dna + user.real_name = chosen_prof.name + user.underwear = chosen_prof.underwear + user.undie_color = chosen_prof.undie_color + user.undershirt = chosen_prof.undershirt + user.shirt_color =chosen_prof.shirt_color + user.socks = chosen_prof.socks + user.socks_color =chosen_prof.socks_color + + chosen_dna.transfer_identity(user, 1) + user.updateappearance(mutcolor_update=1) + user.update_body() + user.domutcheck() + + //vars hackery. not pretty, but better than the alternative. + for(var/slot in GLOB.slots) + if(istype(user.vars[slot], GLOB.slot2type[slot]) && !(chosen_prof.exists_list[slot])) //remove unnecessary flesh items + qdel(user.vars[slot]) + continue + + if((user.vars[slot] && !istype(user.vars[slot], GLOB.slot2type[slot])) || !(chosen_prof.exists_list[slot])) + continue + + var/obj/item/C + var/equip = 0 + if(!user.vars[slot]) + var/thetype = GLOB.slot2type[slot] + equip = 1 + C = new thetype(user) + + else if(istype(user.vars[slot], GLOB.slot2type[slot])) + C = user.vars[slot] + + C.appearance = chosen_prof.appearance_list[slot] + C.name = chosen_prof.name_list[slot] + C.flags_cover = chosen_prof.flags_cover_list[slot] + C.item_color = chosen_prof.item_color_list[slot] + C.item_state = chosen_prof.item_state_list[slot] + if(equip) + user.equip_to_slot_or_del(C, GLOB.slot2slot[slot]) + + user.regenerate_icons() diff --git a/code/game/gamemodes/changeling/traitor_chan.dm b/code/game/gamemodes/changeling/traitor_chan.dm index 3f5abe531b..b010b08bc3 100644 --- a/code/game/gamemodes/changeling/traitor_chan.dm +++ b/code/game/gamemodes/changeling/traitor_chan.dm @@ -1,84 +1,84 @@ -/datum/game_mode/traitor/changeling - name = "traitor+changeling" - config_tag = "traitorchan" - false_report_weight = 10 - traitors_possible = 3 //hard limit on traitors if scaling is turned off - restricted_jobs = list("AI", "Cyborg") - required_players = 25 - required_enemies = 1 // how many of each type are required - recommended_enemies = 3 - reroll_friendly = 1 - - var/list/possible_changelings = list() - var/list/changelings = list() - var/const/changeling_amount = 1 //hard limit on changelings if scaling is turned off - -/datum/game_mode/traitor/changeling/announce() - to_chat(world, "The current game mode is - Traitor+Changeling!") - to_chat(world, "There are alien creatures on the station along with some syndicate operatives out for their own gain! Do not let the changelings or the traitors succeed!") - -/datum/game_mode/traitor/changeling/can_start() - if(!..()) - return 0 - possible_changelings = get_players_for_role(ROLE_CHANGELING) - if(possible_changelings.len < required_enemies) - return 0 - return 1 - -/datum/game_mode/traitor/changeling/pre_setup() - if(CONFIG_GET(flag/protect_roles_from_antagonist)) - restricted_jobs += protected_jobs - - if(CONFIG_GET(flag/protect_assistant_from_antagonist)) - restricted_jobs += "Assistant" - - var/list/datum/mind/possible_changelings = get_players_for_role(ROLE_CHANGELING) - - var/num_changelings = 1 - - var/csc = CONFIG_GET(number/changeling_scaling_coeff) - if(csc) - num_changelings = max(1, min(round(num_players() / (csc * 4)) + 2, round(num_players() / (csc * 2)))) - else - num_changelings = max(1, min(num_players(), changeling_amount/2)) - - if(possible_changelings.len>0) - for(var/j = 0, j < num_changelings, j++) - if(!possible_changelings.len) - break - var/datum/mind/changeling = antag_pick(possible_changelings) - antag_candidates -= changeling - possible_changelings -= changeling - changeling.special_role = ROLE_CHANGELING - changelings += changeling - changeling.restricted_roles = restricted_jobs - return ..() - else - return 0 - -/datum/game_mode/traitor/changeling/post_setup() - for(var/datum/mind/changeling in changelings) - changeling.add_antag_datum(/datum/antagonist/changeling) - return ..() - -/datum/game_mode/traitor/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners - var/csc = CONFIG_GET(number/changeling_scaling_coeff) - var/changelingcap = min( round(GLOB.joined_player_list.len / (csc * 4)) + 2, round(GLOB.joined_player_list.len / (csc * 2))) - if(changelings.len >= changelingcap) //Caps number of latejoin antagonists - ..() - return - if(changelings.len <= (changelingcap - 2) || prob(100 / (csc * 4))) - if(ROLE_CHANGELING in character.client.prefs.be_special) - if(!jobban_isbanned(character, ROLE_CHANGELING) && !QDELETED(character) && !jobban_isbanned(character, ROLE_SYNDICATE) && !QDELETED(character)) - if(age_check(character.client)) - if(!(character.job in restricted_jobs)) - character.mind.make_Changeling() - changelings += character.mind - if(QDELETED(character)) - return - ..() - -/datum/game_mode/traitor/changeling/generate_report() - return "The Syndicate has started some experimental research regarding humanoid shapeshifting. There are rumors that this technology will be field tested on a Nanotrasen station \ - for infiltration purposes. Be advised that support personel may also be deployed to defend these shapeshifters. Trust nobody - suspect everybody. Do not announce this to the crew, \ - as paranoia may spread and inhibit workplace efficiency." +/datum/game_mode/traitor/changeling + name = "traitor+changeling" + config_tag = "traitorchan" + false_report_weight = 10 + traitors_possible = 3 //hard limit on traitors if scaling is turned off + restricted_jobs = list("AI", "Cyborg") + required_players = 25 + required_enemies = 1 // how many of each type are required + recommended_enemies = 3 + reroll_friendly = 1 + + var/list/possible_changelings = list() + var/list/changelings = list() + var/const/changeling_amount = 1 //hard limit on changelings if scaling is turned off + +/datum/game_mode/traitor/changeling/announce() + to_chat(world, "The current game mode is - Traitor+Changeling!") + to_chat(world, "There are alien creatures on the station along with some syndicate operatives out for their own gain! Do not let the changelings or the traitors succeed!") + +/datum/game_mode/traitor/changeling/can_start() + if(!..()) + return 0 + possible_changelings = get_players_for_role(ROLE_CHANGELING) + if(possible_changelings.len < required_enemies) + return 0 + return 1 + +/datum/game_mode/traitor/changeling/pre_setup() + if(CONFIG_GET(flag/protect_roles_from_antagonist)) + restricted_jobs += protected_jobs + + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) + restricted_jobs += "Assistant" + + var/list/datum/mind/possible_changelings = get_players_for_role(ROLE_CHANGELING) + + var/num_changelings = 1 + + var/csc = CONFIG_GET(number/changeling_scaling_coeff) + if(csc) + num_changelings = max(1, min(round(num_players() / (csc * 4)) + 2, round(num_players() / (csc * 2)))) + else + num_changelings = max(1, min(num_players(), changeling_amount/2)) + + if(possible_changelings.len>0) + for(var/j = 0, j < num_changelings, j++) + if(!possible_changelings.len) + break + var/datum/mind/changeling = antag_pick(possible_changelings) + antag_candidates -= changeling + possible_changelings -= changeling + changeling.special_role = ROLE_CHANGELING + changelings += changeling + changeling.restricted_roles = restricted_jobs + return ..() + else + return 0 + +/datum/game_mode/traitor/changeling/post_setup() + for(var/datum/mind/changeling in changelings) + changeling.add_antag_datum(/datum/antagonist/changeling) + return ..() + +/datum/game_mode/traitor/changeling/make_antag_chance(mob/living/carbon/human/character) //Assigns changeling to latejoiners + var/csc = CONFIG_GET(number/changeling_scaling_coeff) + var/changelingcap = min( round(GLOB.joined_player_list.len / (csc * 4)) + 2, round(GLOB.joined_player_list.len / (csc * 2))) + if(changelings.len >= changelingcap) //Caps number of latejoin antagonists + ..() + return + if(changelings.len <= (changelingcap - 2) || prob(100 / (csc * 4))) + if(ROLE_CHANGELING in character.client.prefs.be_special) + if(!jobban_isbanned(character, ROLE_CHANGELING) && !QDELETED(character) && !jobban_isbanned(character, ROLE_SYNDICATE) && !QDELETED(character)) + if(age_check(character.client)) + if(!(character.job in restricted_jobs)) + character.mind.make_Changeling() + changelings += character.mind + if(QDELETED(character)) + return + ..() + +/datum/game_mode/traitor/changeling/generate_report() + return "The Syndicate has started some experimental research regarding humanoid shapeshifting. There are rumors that this technology will be field tested on a Nanotrasen station \ + for infiltration purposes. Be advised that support personel may also be deployed to defend these shapeshifters. Trust nobody - suspect everybody. Do not announce this to the crew, \ + as paranoia may spread and inhibit workplace efficiency." diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index 8d3254933a..d010da465e 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -1,82 +1,82 @@ -/proc/power_failure() - priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", "poweroff") - for(var/obj/machinery/power/smes/S in GLOB.machines) - if(istype(get_area(S), /area/ai_monitored/turret_protected) || !is_station_level(S.z)) - continue - S.charge = 0 - S.output_level = 0 - S.output_attempt = 0 - S.update_icon() - S.power_change() - - var/list/skipped_areas = list(/area/engine/engineering, /area/engine/supermatter, /area/engine/atmospherics_engine, /area/ai_monitored/turret_protected/ai) - - for(var/area/A in world) - if( !A.requires_power || A.always_unpowered ) - continue - - var/skip = 0 - for(var/area_type in skipped_areas) - if(istype(A,area_type)) - skip = 1 - break - if(A.contents) - for(var/atom/AT in A.contents) - if(!is_station_level(AT.z)) //Only check one, it's enough. - skip = 1 - break - if(skip) - continue - A.power_light = FALSE - A.power_equip = FALSE - A.power_environ = FALSE - A.power_change() - - for(var/obj/machinery/power/apc/C in GLOB.apcs_list) - if(C.cell && is_station_level(C.z)) - var/area/A = C.area - - var/skip = 0 - for(var/area_type in skipped_areas) - if(istype(A,area_type)) - skip = 1 - break - if(skip) - continue - - C.cell.charge = 0 - -/proc/power_restore() - - priority_announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", "poweron") - for(var/obj/machinery/power/apc/C in GLOB.machines) - if(C.cell && is_station_level(C.z)) - C.cell.charge = C.cell.maxcharge - C.failure_timer = 0 - for(var/obj/machinery/power/smes/S in GLOB.machines) - if(!is_station_level(S.z)) - continue - S.charge = S.capacity - S.output_level = S.output_level_max - S.output_attempt = 1 - S.update_icon() - S.power_change() - for(var/area/A in world) - if(!istype(A, /area/space) && !istype(A, /area/shuttle) && !istype(A, /area/arrival)) - A.power_light = TRUE - A.power_equip = TRUE - A.power_environ = TRUE - A.power_change() - -/proc/power_restore_quick() - - priority_announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", "poweron") - for(var/obj/machinery/power/smes/S in GLOB.machines) - if(!is_station_level(S.z)) - continue - S.charge = S.capacity - S.output_level = S.output_level_max - S.output_attempt = 1 - S.update_icon() - S.power_change() - +/proc/power_failure() + priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", "poweroff") + for(var/obj/machinery/power/smes/S in GLOB.machines) + if(istype(get_area(S), /area/ai_monitored/turret_protected) || !is_station_level(S.z)) + continue + S.charge = 0 + S.output_level = 0 + S.output_attempt = 0 + S.update_icon() + S.power_change() + + var/list/skipped_areas = list(/area/engine/engineering, /area/engine/supermatter, /area/engine/atmospherics_engine, /area/ai_monitored/turret_protected/ai) + + for(var/area/A in world) + if( !A.requires_power || A.always_unpowered ) + continue + + var/skip = 0 + for(var/area_type in skipped_areas) + if(istype(A,area_type)) + skip = 1 + break + if(A.contents) + for(var/atom/AT in A.contents) + if(!is_station_level(AT.z)) //Only check one, it's enough. + skip = 1 + break + if(skip) + continue + A.power_light = FALSE + A.power_equip = FALSE + A.power_environ = FALSE + A.power_change() + + for(var/obj/machinery/power/apc/C in GLOB.apcs_list) + if(C.cell && is_station_level(C.z)) + var/area/A = C.area + + var/skip = 0 + for(var/area_type in skipped_areas) + if(istype(A,area_type)) + skip = 1 + break + if(skip) + continue + + C.cell.charge = 0 + +/proc/power_restore() + + priority_announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", "poweron") + for(var/obj/machinery/power/apc/C in GLOB.machines) + if(C.cell && is_station_level(C.z)) + C.cell.charge = C.cell.maxcharge + C.failure_timer = 0 + for(var/obj/machinery/power/smes/S in GLOB.machines) + if(!is_station_level(S.z)) + continue + S.charge = S.capacity + S.output_level = S.output_level_max + S.output_attempt = 1 + S.update_icon() + S.power_change() + for(var/area/A in world) + if(!istype(A, /area/space) && !istype(A, /area/shuttle) && !istype(A, /area/arrival)) + A.power_light = TRUE + A.power_equip = TRUE + A.power_environ = TRUE + A.power_change() + +/proc/power_restore_quick() + + priority_announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", "poweron") + for(var/obj/machinery/power/smes/S in GLOB.machines) + if(!is_station_level(S.z)) + continue + S.charge = S.capacity + S.output_level = S.output_level_max + S.output_attempt = 1 + S.update_icon() + S.power_change() + diff --git a/code/game/gamemodes/extended/extended.dm b/code/game/gamemodes/extended/extended.dm index 1229a9cf8c..976f3e3eca 100644 --- a/code/game/gamemodes/extended/extended.dm +++ b/code/game/gamemodes/extended/extended.dm @@ -1,32 +1,32 @@ -/datum/game_mode/extended - name = "secret extended" - config_tag = "secret_extended" - false_report_weight = 5 - required_players = 0 - - announce_span = "notice" - announce_text = "Just have fun and enjoy the game!" - -/datum/game_mode/extended/pre_setup() - return 1 - -/datum/game_mode/extended/generate_report() - return "The transmission mostly failed to mention your sector. It is possible that there is nothing in the Syndicate that could threaten your station during this shift." - -/datum/game_mode/extended/announced - name = "extended" - config_tag = "extended" - false_report_weight = 0 - -/datum/game_mode/extended/announced/generate_station_goals() - if(flipseclevel) //CIT CHANGE - allows the sec level to be flipped roundstart - return ..() - for(var/T in subtypesof(/datum/station_goal)) - var/datum/station_goal/G = new T - station_goals += G - G.on_report() - -/datum/game_mode/extended/announced/send_intercept(report = 0) - if(flipseclevel) //CIT CHANGE - allows the sec level to be flipped roundstart - return ..() - priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", "commandreport") +/datum/game_mode/extended + name = "secret extended" + config_tag = "secret_extended" + false_report_weight = 5 + required_players = 0 + + announce_span = "notice" + announce_text = "Just have fun and enjoy the game!" + +/datum/game_mode/extended/pre_setup() + return 1 + +/datum/game_mode/extended/generate_report() + return "The transmission mostly failed to mention your sector. It is possible that there is nothing in the Syndicate that could threaten your station during this shift." + +/datum/game_mode/extended/announced + name = "extended" + config_tag = "extended" + false_report_weight = 0 + +/datum/game_mode/extended/announced/generate_station_goals() + if(flipseclevel) //CIT CHANGE - allows the sec level to be flipped roundstart + return ..() + for(var/T in subtypesof(/datum/station_goal)) + var/datum/station_goal/G = new T + station_goals += G + G.on_report() + +/datum/game_mode/extended/announced/send_intercept(report = 0) + if(flipseclevel) //CIT CHANGE - allows the sec level to be flipped roundstart + return ..() + priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", "commandreport") diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 3a258599b7..b98462d4d4 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -1,606 +1,606 @@ - - -/* - * GAMEMODES (by Rastaf0) - * - * In the new mode system all special roles are fully supported. - * You can have proper wizards/traitors/changelings/cultists during any mode. - * Only two things really depends on gamemode: - * 1. Starting roles, equipment and preparations - * 2. Conditions of finishing the round. - * - */ - - -/datum/game_mode - var/name = "invalid" - var/config_tag = null - var/votable = 1 - var/probability = 0 - var/false_report_weight = 0 //How often will this show up incorrectly in a centcom report? - var/station_was_nuked = 0 //see nuclearbomb.dm and malfunction.dm - var/nuke_off_station = 0 //Used for tracking where the nuke hit - var/round_ends_with_antag_death = 0 //flags the "one verse the station" antags as such - var/list/datum/mind/antag_candidates = list() // List of possible starting antags goes here - var/list/restricted_jobs = list() // Jobs it doesn't make sense to be. I.E chaplain or AI cultist - var/list/protected_jobs = list() // Jobs that can't be traitors because - var/list/required_jobs = list() // alternative required job groups eg list(list(cap=1),list(hos=1,sec=2)) translates to one captain OR one hos and two secmans - var/required_players = 0 - var/maximum_players = -1 // -1 is no maximum, positive numbers limit the selection of a mode on overstaffed stations - var/required_enemies = 0 - var/recommended_enemies = 0 - var/antag_flag = null //preferences flag such as BE_WIZARD that need to be turned on for players to be antag - var/mob/living/living_antag_player = null - var/datum/game_mode/replacementmode = null - var/round_converted = 0 //0: round not converted, 1: round going to convert, 2: round converted - var/reroll_friendly //During mode conversion only these are in the running - var/continuous_sanity_checked //Catches some cases where config options could be used to suggest that modes without antagonists should end when all antagonists die - var/enemy_minimum_age = 7 //How many days must players have been playing before they can play this antagonist - - var/announce_span = "warning" //The gamemode's name will be in this span during announcement. - var/announce_text = "This gamemode forgot to set a descriptive text! Uh oh!" //Used to describe a gamemode when it's announced. - - var/const/waittime_l = 600 - var/const/waittime_h = 1800 // started at 1800 - - var/list/datum/station_goal/station_goals = list() - - var/allow_persistence_save = TRUE - - var/gamemode_ready = FALSE //Is the gamemode all set up and ready to start checking for ending conditions. - var/setup_error //What stopepd setting up the mode. - var/flipseclevel = FALSE //CIT CHANGE - adds a 10% chance for the alert level to be the opposite of what the gamemode is supposed to have - -/datum/game_mode/proc/announce() //Shows the gamemode's name and a fast description. - to_chat(world, "The gamemode is: [name]!") - to_chat(world, "[announce_text]") - - -///Checks to see if the game can be setup and ran with the current number of players or whatnot. -/datum/game_mode/proc/can_start() - var/playerC = 0 - for(var/mob/dead/new_player/player in GLOB.player_list) - if((player.client)&&(player.ready == PLAYER_READY_TO_PLAY)) - playerC++ - if(!GLOB.Debug2) - if(playerC < required_players || (maximum_players >= 0 && playerC > maximum_players)) - return 0 - antag_candidates = get_players_for_role(antag_flag) - if(!GLOB.Debug2) - if(antag_candidates.len < required_enemies) - return 0 - return 1 - else - message_admins("DEBUG: GAME STARTING WITHOUT PLAYER NUMBER CHECKS, THIS WILL PROBABLY BREAK SHIT.") - return 1 - - -///Attempts to select players for special roles the mode might have. -/datum/game_mode/proc/pre_setup() - return 1 - -///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things -/datum/game_mode/proc/post_setup(report) //Gamemodes can override the intercept report. Passing TRUE as the argument will force a report. - //finalize_monster_hunters() Disabled for now - if(!report) - report = !CONFIG_GET(flag/no_intercept_report) - addtimer(CALLBACK(GLOBAL_PROC, .proc/display_roundstart_logout_report), ROUNDSTART_LOGOUT_REPORT_TIME) - - if(prob(20)) //CIT CHANGE - adds a 20% chance for the security level to be the opposite of what it normally is - flipseclevel = TRUE - if(SSdbcore.Connect()) - var/sql - if(SSticker.mode) - sql += "game_mode = '[SSticker.mode]'" - if(GLOB.revdata.originmastercommit) - if(sql) - sql += ", " - sql += "commit_hash = '[GLOB.revdata.originmastercommit]'" - if(sql) - var/datum/DBQuery/query_round_game_mode = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET [sql] WHERE id = [GLOB.round_id]") - query_round_game_mode.Execute() - qdel(query_round_game_mode) - if(report) - addtimer(CALLBACK(src, .proc/send_intercept, 0), rand(waittime_l, waittime_h)) - generate_station_goals() - gamemode_ready = TRUE - return 1 - - -///Handles late-join antag assignments -/datum/game_mode/proc/make_antag_chance(mob/living/carbon/human/character) - if(replacementmode && round_converted == 2) - replacementmode.make_antag_chance(character) - return - - -///Allows rounds to basically be "rerolled" should the initial premise fall through. Also known as mulligan antags. -/datum/game_mode/proc/convert_roundtype() - set waitfor = FALSE - var/list/living_crew = list() - - for(var/mob/Player in GLOB.mob_list) - if(Player.mind && Player.stat != DEAD && !isnewplayer(Player) && !isbrain(Player) && Player.client) - living_crew += Player - var/malc = CONFIG_GET(number/midround_antag_life_check) - if(living_crew.len / GLOB.joined_player_list.len <= malc) //If a lot of the player base died, we start fresh - message_admins("Convert_roundtype failed due to too many dead people. Limit is [malc * 100]% living crew") - return null - - var/list/datum/game_mode/runnable_modes = config.get_runnable_midround_modes(living_crew.len) - var/list/datum/game_mode/usable_modes = list() - for(var/datum/game_mode/G in runnable_modes) - if(G.reroll_friendly && living_crew.len >= G.required_players) - usable_modes += G - else - qdel(G) - - if(!usable_modes) - message_admins("Convert_roundtype failed due to no valid modes to convert to. Please report this error to the Coders.") - return null - - replacementmode = pickweight(usable_modes) - - switch(SSshuttle.emergency.mode) //Rounds on the verge of ending don't get new antags, they just run out - if(SHUTTLE_STRANDED, SHUTTLE_ESCAPE) - return 1 - if(SHUTTLE_CALL) - if(SSshuttle.emergency.timeLeft(1) < initial(SSshuttle.emergencyCallTime)*0.5) - return 1 - - var/matc = CONFIG_GET(number/midround_antag_time_check) - if(world.time >= (matc * 600)) - message_admins("Convert_roundtype failed due to round length. Limit is [matc] minutes.") - return null - - var/list/antag_candidates = list() - - for(var/mob/living/carbon/human/H in living_crew) - if(H.client && H.client.prefs.allow_midround_antag) - antag_candidates += H - - if(!antag_candidates) - message_admins("Convert_roundtype failed due to no antag candidates.") - return null - - antag_candidates = shuffle(antag_candidates) - - if(CONFIG_GET(flag/protect_roles_from_antagonist)) - replacementmode.restricted_jobs += replacementmode.protected_jobs - if(CONFIG_GET(flag/protect_assistant_from_antagonist)) - replacementmode.restricted_jobs += "Assistant" - - message_admins("The roundtype will be converted. If you have other plans for the station or feel the station is too messed up to inhabit stop the creation of antags or end the round now.") - log_game("Roundtype converted to [replacementmode.name]") - - . = 1 - - sleep(rand(600,1800)) - if(!SSticker.IsRoundInProgress()) - message_admins("Roundtype conversion cancelled, the game appears to have finished!") - round_converted = 0 - return - //somewhere between 1 and 3 minutes from now - if(!CONFIG_GET(keyed_list/midround_antag)[SSticker.mode.config_tag]) - round_converted = 0 - return 1 - for(var/mob/living/carbon/human/H in antag_candidates) - if(H.client) - replacementmode.make_antag_chance(H) - replacementmode.gamemode_ready = TRUE //Awful but we're not doing standard setup here. - round_converted = 2 - message_admins("-- IMPORTANT: The roundtype has been converted to [replacementmode.name], antagonists may have been created! --") - - -///Called by the gameSSticker -/datum/game_mode/process() - return 0 - -//For things that do not die easily -/datum/game_mode/proc/are_special_antags_dead() - return TRUE - - -/datum/game_mode/proc/check_finished(force_ending) //to be called by SSticker - if(!SSticker.setup_done || !gamemode_ready) - return FALSE - if(replacementmode && round_converted == 2) - return replacementmode.check_finished() - if(SSshuttle.emergency && (SSshuttle.emergency.mode == SHUTTLE_ENDGAME)) - return TRUE - if(station_was_nuked) - return TRUE - var/list/continuous = CONFIG_GET(keyed_list/continuous) - var/list/midround_antag = CONFIG_GET(keyed_list/midround_antag) - if(!round_converted && (!continuous[config_tag] || (continuous[config_tag] && midround_antag[config_tag]))) //Non-continuous or continous with replacement antags - if(!continuous_sanity_checked) //make sure we have antags to be checking in the first place - for(var/mob/Player in GLOB.mob_list) - if(Player.mind) - if(Player.mind.special_role || LAZYLEN(Player.mind.antag_datums)) - continuous_sanity_checked = 1 - return 0 - if(!continuous_sanity_checked) - message_admins("The roundtype ([config_tag]) has no antagonists, continuous round has been defaulted to on and midround_antag has been defaulted to off.") - continuous[config_tag] = TRUE - midround_antag[config_tag] = FALSE - SSshuttle.clearHostileEnvironment(src) - return 0 - - - if(living_antag_player && living_antag_player.mind && isliving(living_antag_player) && living_antag_player.stat != DEAD && !isnewplayer(living_antag_player) &&!isbrain(living_antag_player) && (living_antag_player.mind.special_role || LAZYLEN(living_antag_player.mind.antag_datums))) - return 0 //A resource saver: once we find someone who has to die for all antags to be dead, we can just keep checking them, cycling over everyone only when we lose our mark. - - for(var/mob/Player in GLOB.alive_mob_list) - if(Player.mind && Player.stat != DEAD && !isnewplayer(Player) &&!isbrain(Player) && Player.client) - if(Player.mind.special_role || LAZYLEN(Player.mind.antag_datums)) //Someone's still antaging! - living_antag_player = Player - return 0 - - if(!are_special_antags_dead()) - return FALSE - - if(!continuous[config_tag] || force_ending) - return 1 - - else - round_converted = convert_roundtype() - if(!round_converted) - if(round_ends_with_antag_death) - return 1 - else - midround_antag[config_tag] = 0 - return 0 - - return 0 - - -/datum/game_mode/proc/check_win() //universal trigger to be called at mob death, nuke explosion, etc. To be called from everywhere. - return 0 - -/datum/game_mode/proc/send_intercept() - if(flipseclevel && !(config_tag == "extended"))//CIT CHANGE - lets the security level be flipped roundstart - priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", "commandreport") - return - var/intercepttext = "Central Command Status Summary
      " - intercepttext += "Central Command has intercepted and partially decoded a Syndicate transmission with vital information regarding their movements. The following report outlines the most \ - likely threats to appear in your sector." - var/list/report_weights = config.mode_false_report_weight.Copy() - report_weights[config_tag] = 0 //Prevent the current mode from being falsely selected. - var/list/reports = list() - var/Count = 0 //To compensate for missing correct report - if(prob(65)) // 65% chance the actual mode will appear on the list - reports += config.mode_reports[config_tag] - Count++ - for(var/i in Count to rand(3,5)) //Between three and five wrong entries on the list. - var/false_report_type = pickweightAllowZero(report_weights) - report_weights[false_report_type] = 0 //Make it so the same false report won't be selected twice - reports += config.mode_reports[false_report_type] - - reports = shuffle(reports) //Randomize the order, so the real one is at a random position. - - for(var/report in reports) - intercepttext += "
      " - intercepttext += report - - if(station_goals.len) - intercepttext += "
      Special Orders for [station_name()]:" - for(var/datum/station_goal/G in station_goals) - G.on_report() - intercepttext += G.get_report() - - print_command_report(intercepttext, "Central Command Status Summary", announce=FALSE) - priority_announce("A summary has been copied and printed to all communications consoles.", "Enemy communication intercepted. Security level elevated.", "intercept") - if(GLOB.security_level < SEC_LEVEL_BLUE) - set_security_level(SEC_LEVEL_BLUE) - - -// This is a frequency selection system. You may imagine it like a raffle where each player can have some number of tickets. The more tickets you have the more likely you are to -// "win". The default is 100 tickets. If no players use any extra tickets (earned with the antagonist rep system) calling this function should be equivalent to calling the normal -// pick() function. By default you may use up to 100 extra tickets per roll, meaning at maximum a player may double their chances compared to a player who has no extra tickets. -// -// The odds of being picked are simply (your_tickets / total_tickets). Suppose you have one player using fifty (50) extra tickets, and one who uses no extra: -// Player A: 150 tickets -// Player B: 100 tickets -// Total: 250 tickets -// -// The odds become: -// Player A: 150 / 250 = 0.6 = 60% -// Player B: 100 / 250 = 0.4 = 40% - -//Use return list if you want a list, with the arg being the number you want returned. -//WARNING: THIS PROC DOES NOT TAKE INTO ACCOUNT WHAT SSPersistence ALREADY HAS FOR "ADJUST ANTAG REP". If this is used more than once -//and the person rolls more than once, they will not get even more deduction! -//More efficient if you use return list instead of calling this multiple times -//fail_default_pick makes it use pick() instead of antag rep if it can't find anyone -//allow_zero_if_insufficient allows it to pick people with zero rep if there isn't enough antags -/datum/game_mode/proc/antag_pick(list/datum/mind/candidates, return_list = FALSE, fail_default_pick = TRUE, allow_zero_if_insufficient = TRUE) - if(!CONFIG_GET(flag/use_antag_rep)) // || candidates.len <= 1) - return pick(candidates) - - //whoever named the config entries is a bad person :( - - //Tickets you get for free - var/free_tickets = CONFIG_GET(number/default_antag_tickets) - //Max extra tickets you can use - var/additional_tickets = CONFIG_GET(number/max_tickets_per_roll) - - var/list/ckey_to_mind = list() //this is admittedly shitcode but I'm webediting - var/list/prev_tickets = SSpersistence.antag_rep //cache for hyper-speed in theory. how many tickets someone has stored - var/list/curr_tickets = list() //how many tickets someone has for *this* antag roll, so with the free tickets - var/list/datum/mind/insufficient = list() //who got cucked out of an antag roll due to not having *any* tickets - for(var/datum/mind/M in candidates) - var/mind_ckey = ckey(M.key) - var/can_spend = min(prev_tickets[mind_ckey], additional_tickets) //they can only spend up to config/max_tickets_per_roll - var/amount = can_spend + free_tickets //but they get config/default_antag_tickets for free - if(amount <= 0) //if they don't have any - insufficient += M //too bad! - continue - curr_tickets[mind_ckey] = amount - ckey_to_mind[mind_ckey] = M //make sure we can look them up after picking - - if(!return_list) //return a single guy - var/ckey - if(length(curr_tickets)) - ckey = pickweight(curr_tickets) - SSpersistence.antag_rep_change[ckey] = -(curr_tickets[ckey] - free_tickets) //deduct what they spent - var/mind = ckey_to_mind[ckey] || (allow_zero_if_insufficient? pick(insufficient) : null) //we want their mind - if(!mind) //no mind - var/warning = "WARNING: No antagonists were successfully picked by /datum/gamemode/proc/antag_pick()![fail_default_pick? " Defaulting to pick()!":""]" - message_admins(warning) - log_game(warning) - if(fail_default_pick) - mind = pick(candidates) - return mind - else //the far more efficient and proper use of this, to get a list - var/list/rolled = list() - var/list/spend_tickets = list() - for(var/i in 1 to return_list) - if(!length(curr_tickets)) //ah heck, we're out of candidates.. - break - var/ckey = pickweight(curr_tickets) //pick - rolled += ckey //add - spend_tickets[ckey] = curr_tickets[ckey] - free_tickets - curr_tickets -= ckey //don't roll them again - var/missing = return_list - length(rolled) - var/list/add - if((missing > 0) && allow_zero_if_insufficient) //need more.. - for(var/i in 1 to missing) - if(!length(insufficient)) - break //still not enough - var/datum/mind/M = pick_n_take(insufficient) - add += M - if(!length(rolled) && !length(add)) //if no one could normally roll AND no one can zero roll - var/warning = "WARNING: No antagonists were successfully picked by /datum/gamemode/proc/antag_pick()![fail_default_pick? " Defaulting to pick()!":""]" - message_admins(warning) - log_game(warning) - var/list/failed = list() - if(fail_default_pick) - var/list/C = candidates.Copy() - for(var/i in 1 to return_list) - if(!length(C)) - break - failed += pick_n_take(C) - return failed //Wew, no one qualified! - for(var/i in 1 to length(rolled)) - var/ckey = rolled[i] - SSpersistence.antag_rep_change[ckey] = -(spend_tickets[ckey]) //deduct what all of the folks who rolled spent - rolled[i] = ckey_to_mind[ckey] //whoever called us wants minds, not ckeys - if(add) - rolled += add - return rolled - -/datum/game_mode/proc/get_players_for_role(role) - var/list/players = list() - var/list/candidates = list() - var/list/drafted = list() - var/datum/mind/applicant = null - - // Ultimate randomizing code right here - for(var/mob/dead/new_player/player in GLOB.player_list) - if(player.client && player.ready == PLAYER_READY_TO_PLAY && player.check_preferences()) - players += player - - // Shuffling, the players list is now ping-independent!!! - // Goodbye antag dante - players = shuffle(players) - - for(var/mob/dead/new_player/player in players) - if(player.client && player.ready == PLAYER_READY_TO_PLAY) - if(role in player.client.prefs.be_special) - if(!jobban_isbanned(player, ROLE_SYNDICATE) && !QDELETED(player) && !jobban_isbanned(player, role) && !QDELETED(player)) //Nodrak/Carn: Antag Job-bans - if(age_check(player.client)) //Must be older than the minimum age - candidates += player.mind // Get a list of all the people who want to be the antagonist for this round - - if(restricted_jobs) - for(var/datum/mind/player in candidates) - for(var/job in restricted_jobs) // Remove people who want to be antagonist but have a job already that precludes it - if(player.assigned_role == job) - candidates -= player - - if(candidates.len < recommended_enemies) - for(var/mob/dead/new_player/player in players) - if(player.client && player.ready == PLAYER_READY_TO_PLAY) - if(!(role in player.client.prefs.be_special)) // We don't have enough people who want to be antagonist, make a separate list of people who don't want to be one - if(!jobban_isbanned(player, ROLE_SYNDICATE) && !QDELETED(player) && !jobban_isbanned(player, role) && !QDELETED(player) ) //Nodrak/Carn: Antag Job-bans - drafted += player.mind - - if(restricted_jobs) - for(var/datum/mind/player in drafted) // Remove people who can't be an antagonist - for(var/job in restricted_jobs) - if(player.assigned_role == job) - drafted -= player - - drafted = shuffle(drafted) // Will hopefully increase randomness, Donkie - - while(candidates.len < recommended_enemies) // Pick randomlly just the number of people we need and add them to our list of candidates - if(drafted.len > 0) - applicant = pick(drafted) - if(applicant) - candidates += applicant - drafted.Remove(applicant) - - else // Not enough scrubs, ABORT ABORT ABORT - break - - if(restricted_jobs) - for(var/datum/mind/player in drafted) // Remove people who can't be an antagonist - for(var/job in restricted_jobs) - if(player.assigned_role == job) - drafted -= player - - drafted = shuffle(drafted) // Will hopefully increase randomness, Donkie - - while(candidates.len < recommended_enemies) // Pick randomlly just the number of people we need and add them to our list of candidates - if(drafted.len > 0) - applicant = pick(drafted) - if(applicant) - candidates += applicant - drafted.Remove(applicant) - - else // Not enough scrubs, ABORT ABORT ABORT - break - - return candidates // Returns: The number of people who had the antagonist role set to yes, regardless of recomended_enemies, if that number is greater than recommended_enemies - // recommended_enemies if the number of people with that role set to yes is less than recomended_enemies, - // Less if there are not enough valid players in the game entirely to make recommended_enemies. - - - -/datum/game_mode/proc/num_players() - . = 0 - for(var/mob/dead/new_player/P in GLOB.player_list) - if(P.client && P.ready == PLAYER_READY_TO_PLAY) - . ++ - -////////////////////////// -//Reports player logouts// -////////////////////////// -/proc/display_roundstart_logout_report() - var/list/msg = list("Roundstart logout report\n\n") - for(var/i in GLOB.mob_living_list) - var/mob/living/L = i - var/mob/living/carbon/C = L - if (istype(C) && !C.last_mind) - continue // never had a client - - if(L.ckey && !GLOB.directory[L.ckey]) - msg += "[L.name] ([L.key]), the [L.job] (Disconnected)\n" - - - if(L.ckey && L.client) - var/failed = FALSE - if(L.client.inactivity >= (ROUNDSTART_LOGOUT_REPORT_TIME / 2)) //Connected, but inactive (alt+tabbed or something) - msg += "[L.name] ([L.key]), the [L.job] (Connected, Inactive)\n" - failed = TRUE //AFK client - if(!failed && L.stat) - if(L.suiciding) //Suicider - msg += "[L.name] ([L.key]), the [L.job] (Suicide)\n" - failed = TRUE //Disconnected client - if(!failed && L.stat == UNCONSCIOUS) - msg += "[L.name] ([L.key]), the [L.job] (Dying)\n" - failed = TRUE //Unconscious - if(!failed && L.stat == DEAD) - msg += "[L.name] ([L.key]), the [L.job] (Dead)\n" - failed = TRUE //Dead - - var/p_ckey = L.client.ckey -// WARNING("AR_DEBUG: [p_ckey]: failed - [failed], antag_rep_change: [SSpersistence.antag_rep_change[p_ckey]]") - - // people who died or left should not gain any reputation - // people who rolled antagonist still lose it - if(failed && SSpersistence.antag_rep_change[p_ckey] > 0) -// WARNING("AR_DEBUG: Zeroed [p_ckey]'s antag_rep_change") - SSpersistence.antag_rep_change[p_ckey] = 0 - - continue //Happy connected client - for(var/mob/dead/observer/D in GLOB.dead_mob_list) - if(D.mind && D.mind.current == L) - if(L.stat == DEAD) - if(L.suiciding) //Suicider - msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Suicide)\n" - continue //Disconnected client - else - msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Dead)\n" - continue //Dead mob, ghost abandoned - else - if(D.can_reenter_corpse) - continue //Adminghost, or cult/wizard ghost - else - msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Ghosted)\n" - continue //Ghosted while alive - - - for (var/C in GLOB.admins) - to_chat(C, msg.Join()) - -//If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1 -/datum/game_mode/proc/age_check(client/C) - if(get_remaining_days(C) == 0) - return 1 //Available in 0 days = available right now = player is old enough to play. - return 0 - - -/datum/game_mode/proc/get_remaining_days(client/C) - if(!C) - return 0 - if(!CONFIG_GET(flag/use_age_restriction_for_jobs)) - return 0 - if(!isnum(C.player_age)) - return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced - if(!isnum(enemy_minimum_age)) - return 0 - - return max(0, enemy_minimum_age - C.player_age) - -/datum/game_mode/proc/remove_antag_for_borging(datum/mind/newborgie) - SSticker.mode.remove_cultist(newborgie, 0, 0) - var/datum/antagonist/rev/rev = newborgie.has_antag_datum(/datum/antagonist/rev) - if(rev) - rev.remove_revolutionary(TRUE) - -/datum/game_mode/proc/generate_station_goals() - if(flipseclevel && !(config_tag == "extended")) //CIT CHANGE - allows the sec level to be flipped roundstart - for(var/T in subtypesof(/datum/station_goal)) - var/datum/station_goal/G = new T - station_goals += G - G.on_report() - return - var/list/possible = list() - for(var/T in subtypesof(/datum/station_goal)) - var/datum/station_goal/G = T - if(config_tag in initial(G.gamemode_blacklist)) - continue - possible += T - var/goal_weights = 0 - while(possible.len && goal_weights < STATION_GOAL_BUDGET) - var/datum/station_goal/picked = pick_n_take(possible) - goal_weights += initial(picked.weight) - station_goals += new picked - - -/datum/game_mode/proc/generate_report() //Generates a small text blurb for the gamemode in centcom report - return "Gamemode report for [name] not set. Contact a coder." - -//By default nuke just ends the round -/datum/game_mode/proc/OnNukeExplosion(off_station) - nuke_off_station = off_station - if(off_station < 2) - station_was_nuked = TRUE //Will end the round on next check. - -//Additional report section in roundend report -/datum/game_mode/proc/special_report() - return - -//Set result and news report here -/datum/game_mode/proc/set_round_result() - SSticker.mode_result = "undefined" - if(station_was_nuked) - SSticker.news_report = STATION_DESTROYED_NUKE - if(EMERGENCY_ESCAPED_OR_ENDGAMED) - SSticker.news_report = STATION_EVACUATED - if(SSshuttle.emergency.is_hijacked()) - SSticker.news_report = SHUTTLE_HIJACK - -/// Mode specific admin panel. -/datum/game_mode/proc/admin_panel() - return + + +/* + * GAMEMODES (by Rastaf0) + * + * In the new mode system all special roles are fully supported. + * You can have proper wizards/traitors/changelings/cultists during any mode. + * Only two things really depends on gamemode: + * 1. Starting roles, equipment and preparations + * 2. Conditions of finishing the round. + * + */ + + +/datum/game_mode + var/name = "invalid" + var/config_tag = null + var/votable = 1 + var/probability = 0 + var/false_report_weight = 0 //How often will this show up incorrectly in a centcom report? + var/station_was_nuked = 0 //see nuclearbomb.dm and malfunction.dm + var/nuke_off_station = 0 //Used for tracking where the nuke hit + var/round_ends_with_antag_death = 0 //flags the "one verse the station" antags as such + var/list/datum/mind/antag_candidates = list() // List of possible starting antags goes here + var/list/restricted_jobs = list() // Jobs it doesn't make sense to be. I.E chaplain or AI cultist + var/list/protected_jobs = list() // Jobs that can't be traitors because + var/list/required_jobs = list() // alternative required job groups eg list(list(cap=1),list(hos=1,sec=2)) translates to one captain OR one hos and two secmans + var/required_players = 0 + var/maximum_players = -1 // -1 is no maximum, positive numbers limit the selection of a mode on overstaffed stations + var/required_enemies = 0 + var/recommended_enemies = 0 + var/antag_flag = null //preferences flag such as BE_WIZARD that need to be turned on for players to be antag + var/mob/living/living_antag_player = null + var/datum/game_mode/replacementmode = null + var/round_converted = 0 //0: round not converted, 1: round going to convert, 2: round converted + var/reroll_friendly //During mode conversion only these are in the running + var/continuous_sanity_checked //Catches some cases where config options could be used to suggest that modes without antagonists should end when all antagonists die + var/enemy_minimum_age = 7 //How many days must players have been playing before they can play this antagonist + + var/announce_span = "warning" //The gamemode's name will be in this span during announcement. + var/announce_text = "This gamemode forgot to set a descriptive text! Uh oh!" //Used to describe a gamemode when it's announced. + + var/const/waittime_l = 600 + var/const/waittime_h = 1800 // started at 1800 + + var/list/datum/station_goal/station_goals = list() + + var/allow_persistence_save = TRUE + + var/gamemode_ready = FALSE //Is the gamemode all set up and ready to start checking for ending conditions. + var/setup_error //What stopepd setting up the mode. + var/flipseclevel = FALSE //CIT CHANGE - adds a 10% chance for the alert level to be the opposite of what the gamemode is supposed to have + +/datum/game_mode/proc/announce() //Shows the gamemode's name and a fast description. + to_chat(world, "The gamemode is: [name]!") + to_chat(world, "[announce_text]") + + +///Checks to see if the game can be setup and ran with the current number of players or whatnot. +/datum/game_mode/proc/can_start() + var/playerC = 0 + for(var/mob/dead/new_player/player in GLOB.player_list) + if((player.client)&&(player.ready == PLAYER_READY_TO_PLAY)) + playerC++ + if(!GLOB.Debug2) + if(playerC < required_players || (maximum_players >= 0 && playerC > maximum_players)) + return 0 + antag_candidates = get_players_for_role(antag_flag) + if(!GLOB.Debug2) + if(antag_candidates.len < required_enemies) + return 0 + return 1 + else + message_admins("DEBUG: GAME STARTING WITHOUT PLAYER NUMBER CHECKS, THIS WILL PROBABLY BREAK SHIT.") + return 1 + + +///Attempts to select players for special roles the mode might have. +/datum/game_mode/proc/pre_setup() + return 1 + +///Everyone should now be on the station and have their normal gear. This is the place to give the special roles extra things +/datum/game_mode/proc/post_setup(report) //Gamemodes can override the intercept report. Passing TRUE as the argument will force a report. + //finalize_monster_hunters() Disabled for now + if(!report) + report = !CONFIG_GET(flag/no_intercept_report) + addtimer(CALLBACK(GLOBAL_PROC, .proc/display_roundstart_logout_report), ROUNDSTART_LOGOUT_REPORT_TIME) + + if(prob(20)) //CIT CHANGE - adds a 20% chance for the security level to be the opposite of what it normally is + flipseclevel = TRUE + if(SSdbcore.Connect()) + var/sql + if(SSticker.mode) + sql += "game_mode = '[SSticker.mode]'" + if(GLOB.revdata.originmastercommit) + if(sql) + sql += ", " + sql += "commit_hash = '[GLOB.revdata.originmastercommit]'" + if(sql) + var/datum/DBQuery/query_round_game_mode = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET [sql] WHERE id = [GLOB.round_id]") + query_round_game_mode.Execute() + qdel(query_round_game_mode) + if(report) + addtimer(CALLBACK(src, .proc/send_intercept, 0), rand(waittime_l, waittime_h)) + generate_station_goals() + gamemode_ready = TRUE + return 1 + + +///Handles late-join antag assignments +/datum/game_mode/proc/make_antag_chance(mob/living/carbon/human/character) + if(replacementmode && round_converted == 2) + replacementmode.make_antag_chance(character) + return + + +///Allows rounds to basically be "rerolled" should the initial premise fall through. Also known as mulligan antags. +/datum/game_mode/proc/convert_roundtype() + set waitfor = FALSE + var/list/living_crew = list() + + for(var/mob/Player in GLOB.mob_list) + if(Player.mind && Player.stat != DEAD && !isnewplayer(Player) && !isbrain(Player) && Player.client) + living_crew += Player + var/malc = CONFIG_GET(number/midround_antag_life_check) + if(living_crew.len / GLOB.joined_player_list.len <= malc) //If a lot of the player base died, we start fresh + message_admins("Convert_roundtype failed due to too many dead people. Limit is [malc * 100]% living crew") + return null + + var/list/datum/game_mode/runnable_modes = config.get_runnable_midround_modes(living_crew.len) + var/list/datum/game_mode/usable_modes = list() + for(var/datum/game_mode/G in runnable_modes) + if(G.reroll_friendly && living_crew.len >= G.required_players) + usable_modes += G + else + qdel(G) + + if(!usable_modes) + message_admins("Convert_roundtype failed due to no valid modes to convert to. Please report this error to the Coders.") + return null + + replacementmode = pickweight(usable_modes) + + switch(SSshuttle.emergency.mode) //Rounds on the verge of ending don't get new antags, they just run out + if(SHUTTLE_STRANDED, SHUTTLE_ESCAPE) + return 1 + if(SHUTTLE_CALL) + if(SSshuttle.emergency.timeLeft(1) < initial(SSshuttle.emergencyCallTime)*0.5) + return 1 + + var/matc = CONFIG_GET(number/midround_antag_time_check) + if(world.time >= (matc * 600)) + message_admins("Convert_roundtype failed due to round length. Limit is [matc] minutes.") + return null + + var/list/antag_candidates = list() + + for(var/mob/living/carbon/human/H in living_crew) + if(H.client && H.client.prefs.allow_midround_antag) + antag_candidates += H + + if(!antag_candidates) + message_admins("Convert_roundtype failed due to no antag candidates.") + return null + + antag_candidates = shuffle(antag_candidates) + + if(CONFIG_GET(flag/protect_roles_from_antagonist)) + replacementmode.restricted_jobs += replacementmode.protected_jobs + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) + replacementmode.restricted_jobs += "Assistant" + + message_admins("The roundtype will be converted. If you have other plans for the station or feel the station is too messed up to inhabit stop the creation of antags or end the round now.") + log_game("Roundtype converted to [replacementmode.name]") + + . = 1 + + sleep(rand(600,1800)) + if(!SSticker.IsRoundInProgress()) + message_admins("Roundtype conversion cancelled, the game appears to have finished!") + round_converted = 0 + return + //somewhere between 1 and 3 minutes from now + if(!CONFIG_GET(keyed_list/midround_antag)[SSticker.mode.config_tag]) + round_converted = 0 + return 1 + for(var/mob/living/carbon/human/H in antag_candidates) + if(H.client) + replacementmode.make_antag_chance(H) + replacementmode.gamemode_ready = TRUE //Awful but we're not doing standard setup here. + round_converted = 2 + message_admins("-- IMPORTANT: The roundtype has been converted to [replacementmode.name], antagonists may have been created! --") + + +///Called by the gameSSticker +/datum/game_mode/process() + return 0 + +//For things that do not die easily +/datum/game_mode/proc/are_special_antags_dead() + return TRUE + + +/datum/game_mode/proc/check_finished(force_ending) //to be called by SSticker + if(!SSticker.setup_done || !gamemode_ready) + return FALSE + if(replacementmode && round_converted == 2) + return replacementmode.check_finished() + if(SSshuttle.emergency && (SSshuttle.emergency.mode == SHUTTLE_ENDGAME)) + return TRUE + if(station_was_nuked) + return TRUE + var/list/continuous = CONFIG_GET(keyed_list/continuous) + var/list/midround_antag = CONFIG_GET(keyed_list/midround_antag) + if(!round_converted && (!continuous[config_tag] || (continuous[config_tag] && midround_antag[config_tag]))) //Non-continuous or continous with replacement antags + if(!continuous_sanity_checked) //make sure we have antags to be checking in the first place + for(var/mob/Player in GLOB.mob_list) + if(Player.mind) + if(Player.mind.special_role || LAZYLEN(Player.mind.antag_datums)) + continuous_sanity_checked = 1 + return 0 + if(!continuous_sanity_checked) + message_admins("The roundtype ([config_tag]) has no antagonists, continuous round has been defaulted to on and midround_antag has been defaulted to off.") + continuous[config_tag] = TRUE + midround_antag[config_tag] = FALSE + SSshuttle.clearHostileEnvironment(src) + return 0 + + + if(living_antag_player && living_antag_player.mind && isliving(living_antag_player) && living_antag_player.stat != DEAD && !isnewplayer(living_antag_player) &&!isbrain(living_antag_player) && (living_antag_player.mind.special_role || LAZYLEN(living_antag_player.mind.antag_datums))) + return 0 //A resource saver: once we find someone who has to die for all antags to be dead, we can just keep checking them, cycling over everyone only when we lose our mark. + + for(var/mob/Player in GLOB.alive_mob_list) + if(Player.mind && Player.stat != DEAD && !isnewplayer(Player) &&!isbrain(Player) && Player.client) + if(Player.mind.special_role || LAZYLEN(Player.mind.antag_datums)) //Someone's still antaging! + living_antag_player = Player + return 0 + + if(!are_special_antags_dead()) + return FALSE + + if(!continuous[config_tag] || force_ending) + return 1 + + else + round_converted = convert_roundtype() + if(!round_converted) + if(round_ends_with_antag_death) + return 1 + else + midround_antag[config_tag] = 0 + return 0 + + return 0 + + +/datum/game_mode/proc/check_win() //universal trigger to be called at mob death, nuke explosion, etc. To be called from everywhere. + return 0 + +/datum/game_mode/proc/send_intercept() + if(flipseclevel && !(config_tag == "extended"))//CIT CHANGE - lets the security level be flipped roundstart + priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", "commandreport") + return + var/intercepttext = "Central Command Status Summary
      " + intercepttext += "Central Command has intercepted and partially decoded a Syndicate transmission with vital information regarding their movements. The following report outlines the most \ + likely threats to appear in your sector." + var/list/report_weights = config.mode_false_report_weight.Copy() + report_weights[config_tag] = 0 //Prevent the current mode from being falsely selected. + var/list/reports = list() + var/Count = 0 //To compensate for missing correct report + if(prob(65)) // 65% chance the actual mode will appear on the list + reports += config.mode_reports[config_tag] + Count++ + for(var/i in Count to rand(3,5)) //Between three and five wrong entries on the list. + var/false_report_type = pickweightAllowZero(report_weights) + report_weights[false_report_type] = 0 //Make it so the same false report won't be selected twice + reports += config.mode_reports[false_report_type] + + reports = shuffle(reports) //Randomize the order, so the real one is at a random position. + + for(var/report in reports) + intercepttext += "
      " + intercepttext += report + + if(station_goals.len) + intercepttext += "
      Special Orders for [station_name()]:" + for(var/datum/station_goal/G in station_goals) + G.on_report() + intercepttext += G.get_report() + + print_command_report(intercepttext, "Central Command Status Summary", announce=FALSE) + priority_announce("A summary has been copied and printed to all communications consoles.", "Enemy communication intercepted. Security level elevated.", "intercept") + if(GLOB.security_level < SEC_LEVEL_BLUE) + set_security_level(SEC_LEVEL_BLUE) + + +// This is a frequency selection system. You may imagine it like a raffle where each player can have some number of tickets. The more tickets you have the more likely you are to +// "win". The default is 100 tickets. If no players use any extra tickets (earned with the antagonist rep system) calling this function should be equivalent to calling the normal +// pick() function. By default you may use up to 100 extra tickets per roll, meaning at maximum a player may double their chances compared to a player who has no extra tickets. +// +// The odds of being picked are simply (your_tickets / total_tickets). Suppose you have one player using fifty (50) extra tickets, and one who uses no extra: +// Player A: 150 tickets +// Player B: 100 tickets +// Total: 250 tickets +// +// The odds become: +// Player A: 150 / 250 = 0.6 = 60% +// Player B: 100 / 250 = 0.4 = 40% + +//Use return list if you want a list, with the arg being the number you want returned. +//WARNING: THIS PROC DOES NOT TAKE INTO ACCOUNT WHAT SSPersistence ALREADY HAS FOR "ADJUST ANTAG REP". If this is used more than once +//and the person rolls more than once, they will not get even more deduction! +//More efficient if you use return list instead of calling this multiple times +//fail_default_pick makes it use pick() instead of antag rep if it can't find anyone +//allow_zero_if_insufficient allows it to pick people with zero rep if there isn't enough antags +/datum/game_mode/proc/antag_pick(list/datum/mind/candidates, return_list = FALSE, fail_default_pick = TRUE, allow_zero_if_insufficient = TRUE) + if(!CONFIG_GET(flag/use_antag_rep)) // || candidates.len <= 1) + return pick(candidates) + + //whoever named the config entries is a bad person :( + + //Tickets you get for free + var/free_tickets = CONFIG_GET(number/default_antag_tickets) + //Max extra tickets you can use + var/additional_tickets = CONFIG_GET(number/max_tickets_per_roll) + + var/list/ckey_to_mind = list() //this is admittedly shitcode but I'm webediting + var/list/prev_tickets = SSpersistence.antag_rep //cache for hyper-speed in theory. how many tickets someone has stored + var/list/curr_tickets = list() //how many tickets someone has for *this* antag roll, so with the free tickets + var/list/datum/mind/insufficient = list() //who got cucked out of an antag roll due to not having *any* tickets + for(var/datum/mind/M in candidates) + var/mind_ckey = ckey(M.key) + var/can_spend = min(prev_tickets[mind_ckey], additional_tickets) //they can only spend up to config/max_tickets_per_roll + var/amount = can_spend + free_tickets //but they get config/default_antag_tickets for free + if(amount <= 0) //if they don't have any + insufficient += M //too bad! + continue + curr_tickets[mind_ckey] = amount + ckey_to_mind[mind_ckey] = M //make sure we can look them up after picking + + if(!return_list) //return a single guy + var/ckey + if(length(curr_tickets)) + ckey = pickweight(curr_tickets) + SSpersistence.antag_rep_change[ckey] = -(curr_tickets[ckey] - free_tickets) //deduct what they spent + var/mind = ckey_to_mind[ckey] || (allow_zero_if_insufficient? pick(insufficient) : null) //we want their mind + if(!mind) //no mind + var/warning = "WARNING: No antagonists were successfully picked by /datum/gamemode/proc/antag_pick()![fail_default_pick? " Defaulting to pick()!":""]" + message_admins(warning) + log_game(warning) + if(fail_default_pick) + mind = pick(candidates) + return mind + else //the far more efficient and proper use of this, to get a list + var/list/rolled = list() + var/list/spend_tickets = list() + for(var/i in 1 to return_list) + if(!length(curr_tickets)) //ah heck, we're out of candidates.. + break + var/ckey = pickweight(curr_tickets) //pick + rolled += ckey //add + spend_tickets[ckey] = curr_tickets[ckey] - free_tickets + curr_tickets -= ckey //don't roll them again + var/missing = return_list - length(rolled) + var/list/add + if((missing > 0) && allow_zero_if_insufficient) //need more.. + for(var/i in 1 to missing) + if(!length(insufficient)) + break //still not enough + var/datum/mind/M = pick_n_take(insufficient) + add += M + if(!length(rolled) && !length(add)) //if no one could normally roll AND no one can zero roll + var/warning = "WARNING: No antagonists were successfully picked by /datum/gamemode/proc/antag_pick()![fail_default_pick? " Defaulting to pick()!":""]" + message_admins(warning) + log_game(warning) + var/list/failed = list() + if(fail_default_pick) + var/list/C = candidates.Copy() + for(var/i in 1 to return_list) + if(!length(C)) + break + failed += pick_n_take(C) + return failed //Wew, no one qualified! + for(var/i in 1 to length(rolled)) + var/ckey = rolled[i] + SSpersistence.antag_rep_change[ckey] = -(spend_tickets[ckey]) //deduct what all of the folks who rolled spent + rolled[i] = ckey_to_mind[ckey] //whoever called us wants minds, not ckeys + if(add) + rolled += add + return rolled + +/datum/game_mode/proc/get_players_for_role(role) + var/list/players = list() + var/list/candidates = list() + var/list/drafted = list() + var/datum/mind/applicant = null + + // Ultimate randomizing code right here + for(var/mob/dead/new_player/player in GLOB.player_list) + if(player.client && player.ready == PLAYER_READY_TO_PLAY && player.check_preferences()) + players += player + + // Shuffling, the players list is now ping-independent!!! + // Goodbye antag dante + players = shuffle(players) + + for(var/mob/dead/new_player/player in players) + if(player.client && player.ready == PLAYER_READY_TO_PLAY) + if(role in player.client.prefs.be_special) + if(!jobban_isbanned(player, ROLE_SYNDICATE) && !QDELETED(player) && !jobban_isbanned(player, role) && !QDELETED(player)) //Nodrak/Carn: Antag Job-bans + if(age_check(player.client)) //Must be older than the minimum age + candidates += player.mind // Get a list of all the people who want to be the antagonist for this round + + if(restricted_jobs) + for(var/datum/mind/player in candidates) + for(var/job in restricted_jobs) // Remove people who want to be antagonist but have a job already that precludes it + if(player.assigned_role == job) + candidates -= player + + if(candidates.len < recommended_enemies) + for(var/mob/dead/new_player/player in players) + if(player.client && player.ready == PLAYER_READY_TO_PLAY) + if(!(role in player.client.prefs.be_special)) // We don't have enough people who want to be antagonist, make a separate list of people who don't want to be one + if(!jobban_isbanned(player, ROLE_SYNDICATE) && !QDELETED(player) && !jobban_isbanned(player, role) && !QDELETED(player) ) //Nodrak/Carn: Antag Job-bans + drafted += player.mind + + if(restricted_jobs) + for(var/datum/mind/player in drafted) // Remove people who can't be an antagonist + for(var/job in restricted_jobs) + if(player.assigned_role == job) + drafted -= player + + drafted = shuffle(drafted) // Will hopefully increase randomness, Donkie + + while(candidates.len < recommended_enemies) // Pick randomlly just the number of people we need and add them to our list of candidates + if(drafted.len > 0) + applicant = pick(drafted) + if(applicant) + candidates += applicant + drafted.Remove(applicant) + + else // Not enough scrubs, ABORT ABORT ABORT + break + + if(restricted_jobs) + for(var/datum/mind/player in drafted) // Remove people who can't be an antagonist + for(var/job in restricted_jobs) + if(player.assigned_role == job) + drafted -= player + + drafted = shuffle(drafted) // Will hopefully increase randomness, Donkie + + while(candidates.len < recommended_enemies) // Pick randomlly just the number of people we need and add them to our list of candidates + if(drafted.len > 0) + applicant = pick(drafted) + if(applicant) + candidates += applicant + drafted.Remove(applicant) + + else // Not enough scrubs, ABORT ABORT ABORT + break + + return candidates // Returns: The number of people who had the antagonist role set to yes, regardless of recomended_enemies, if that number is greater than recommended_enemies + // recommended_enemies if the number of people with that role set to yes is less than recomended_enemies, + // Less if there are not enough valid players in the game entirely to make recommended_enemies. + + + +/datum/game_mode/proc/num_players() + . = 0 + for(var/mob/dead/new_player/P in GLOB.player_list) + if(P.client && P.ready == PLAYER_READY_TO_PLAY) + . ++ + +////////////////////////// +//Reports player logouts// +////////////////////////// +/proc/display_roundstart_logout_report() + var/list/msg = list("Roundstart logout report\n\n") + for(var/i in GLOB.mob_living_list) + var/mob/living/L = i + var/mob/living/carbon/C = L + if (istype(C) && !C.last_mind) + continue // never had a client + + if(L.ckey && !GLOB.directory[L.ckey]) + msg += "[L.name] ([L.key]), the [L.job] (Disconnected)\n" + + + if(L.ckey && L.client) + var/failed = FALSE + if(L.client.inactivity >= (ROUNDSTART_LOGOUT_REPORT_TIME / 2)) //Connected, but inactive (alt+tabbed or something) + msg += "[L.name] ([L.key]), the [L.job] (Connected, Inactive)\n" + failed = TRUE //AFK client + if(!failed && L.stat) + if(L.suiciding) //Suicider + msg += "[L.name] ([L.key]), the [L.job] (Suicide)\n" + failed = TRUE //Disconnected client + if(!failed && L.stat == UNCONSCIOUS) + msg += "[L.name] ([L.key]), the [L.job] (Dying)\n" + failed = TRUE //Unconscious + if(!failed && L.stat == DEAD) + msg += "[L.name] ([L.key]), the [L.job] (Dead)\n" + failed = TRUE //Dead + + var/p_ckey = L.client.ckey +// WARNING("AR_DEBUG: [p_ckey]: failed - [failed], antag_rep_change: [SSpersistence.antag_rep_change[p_ckey]]") + + // people who died or left should not gain any reputation + // people who rolled antagonist still lose it + if(failed && SSpersistence.antag_rep_change[p_ckey] > 0) +// WARNING("AR_DEBUG: Zeroed [p_ckey]'s antag_rep_change") + SSpersistence.antag_rep_change[p_ckey] = 0 + + continue //Happy connected client + for(var/mob/dead/observer/D in GLOB.dead_mob_list) + if(D.mind && D.mind.current == L) + if(L.stat == DEAD) + if(L.suiciding) //Suicider + msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Suicide)\n" + continue //Disconnected client + else + msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Dead)\n" + continue //Dead mob, ghost abandoned + else + if(D.can_reenter_corpse) + continue //Adminghost, or cult/wizard ghost + else + msg += "[L.name] ([ckey(D.mind.key)]), the [L.job] (Ghosted)\n" + continue //Ghosted while alive + + + for (var/C in GLOB.admins) + to_chat(C, msg.Join()) + +//If the configuration option is set to require players to be logged as old enough to play certain jobs, then this proc checks that they are, otherwise it just returns 1 +/datum/game_mode/proc/age_check(client/C) + if(get_remaining_days(C) == 0) + return 1 //Available in 0 days = available right now = player is old enough to play. + return 0 + + +/datum/game_mode/proc/get_remaining_days(client/C) + if(!C) + return 0 + if(!CONFIG_GET(flag/use_age_restriction_for_jobs)) + return 0 + if(!isnum(C.player_age)) + return 0 //This is only a number if the db connection is established, otherwise it is text: "Requires database", meaning these restrictions cannot be enforced + if(!isnum(enemy_minimum_age)) + return 0 + + return max(0, enemy_minimum_age - C.player_age) + +/datum/game_mode/proc/remove_antag_for_borging(datum/mind/newborgie) + SSticker.mode.remove_cultist(newborgie, 0, 0) + var/datum/antagonist/rev/rev = newborgie.has_antag_datum(/datum/antagonist/rev) + if(rev) + rev.remove_revolutionary(TRUE) + +/datum/game_mode/proc/generate_station_goals() + if(flipseclevel && !(config_tag == "extended")) //CIT CHANGE - allows the sec level to be flipped roundstart + for(var/T in subtypesof(/datum/station_goal)) + var/datum/station_goal/G = new T + station_goals += G + G.on_report() + return + var/list/possible = list() + for(var/T in subtypesof(/datum/station_goal)) + var/datum/station_goal/G = T + if(config_tag in initial(G.gamemode_blacklist)) + continue + possible += T + var/goal_weights = 0 + while(possible.len && goal_weights < STATION_GOAL_BUDGET) + var/datum/station_goal/picked = pick_n_take(possible) + goal_weights += initial(picked.weight) + station_goals += new picked + + +/datum/game_mode/proc/generate_report() //Generates a small text blurb for the gamemode in centcom report + return "Gamemode report for [name] not set. Contact a coder." + +//By default nuke just ends the round +/datum/game_mode/proc/OnNukeExplosion(off_station) + nuke_off_station = off_station + if(off_station < 2) + station_was_nuked = TRUE //Will end the round on next check. + +//Additional report section in roundend report +/datum/game_mode/proc/special_report() + return + +//Set result and news report here +/datum/game_mode/proc/set_round_result() + SSticker.mode_result = "undefined" + if(station_was_nuked) + SSticker.news_report = STATION_DESTROYED_NUKE + if(EMERGENCY_ESCAPED_OR_ENDGAMED) + SSticker.news_report = STATION_EVACUATED + if(SSshuttle.emergency.is_hijacked()) + SSticker.news_report = SHUTTLE_HIJACK + +/// Mode specific admin panel. +/datum/game_mode/proc/admin_panel() + return diff --git a/code/game/gamemodes/meteor/meteor.dm b/code/game/gamemodes/meteor/meteor.dm index 90e2b85f11..7857eb8253 100644 --- a/code/game/gamemodes/meteor/meteor.dm +++ b/code/game/gamemodes/meteor/meteor.dm @@ -1,59 +1,59 @@ -/datum/game_mode/meteor - name = "meteor" - config_tag = "meteor" - false_report_weight = 1 - var/meteordelay = 2000 - var/nometeors = 0 - var/rampupdelta = 5 - required_players = 0 - - announce_span = "danger" - announce_text = "A major meteor shower is bombarding the station! The crew needs to evacuate or survive the onslaught." - - -/datum/game_mode/meteor/process() - if(nometeors || meteordelay > world.time - SSticker.round_start_time) - return - - var/list/wavetype = GLOB.meteors_normal - var/meteorminutes = (world.time - SSticker.round_start_time - meteordelay) / 10 / 60 - - - if (prob(meteorminutes)) - wavetype = GLOB.meteors_threatening - - if (prob(meteorminutes/2)) - wavetype = GLOB.meteors_catastrophic - - var/ramp_up_final = CLAMP(round(meteorminutes/rampupdelta), 1, 10) - - spawn_meteors(ramp_up_final, wavetype) - - -/datum/game_mode/meteor/special_report() - var/survivors = 0 - var/list/survivor_list = list() - - for(var/mob/living/player in GLOB.player_list) - if(player.stat != DEAD) - ++survivors - - if(player.onCentCom()) - survivor_list += "[player.real_name] escaped to the safety of CentCom." - else if(player.onSyndieBase()) - survivor_list += "[player.real_name] escaped to the (relative) safety of Syndicate Space." - else - survivor_list += "[player.real_name] survived but is stranded without any hope of rescue." - - if(survivors) - return "
      The following survived the meteor storm:
      [survivor_list.Join("
      ")]
      " - else - return "
      Nobody survived the meteor storm!
      " - -/datum/game_mode/meteor/set_round_result() - ..() - SSticker.mode_result = "end - evacuation" - -/datum/game_mode/meteor/generate_report() - return "[pick("Asteroids have", "Meteors have", "Large rocks have", "Stellar minerals have", "Space hail has", "Debris has")] been detected near your station, and a collision is possible, \ - though unlikely. Be prepared for largescale impacts and destruction. Please note that the debris will prevent the escape shuttle from arriving quickly." +/datum/game_mode/meteor + name = "meteor" + config_tag = "meteor" + false_report_weight = 1 + var/meteordelay = 2000 + var/nometeors = 0 + var/rampupdelta = 5 + required_players = 0 + + announce_span = "danger" + announce_text = "A major meteor shower is bombarding the station! The crew needs to evacuate or survive the onslaught." + + +/datum/game_mode/meteor/process() + if(nometeors || meteordelay > world.time - SSticker.round_start_time) + return + + var/list/wavetype = GLOB.meteors_normal + var/meteorminutes = (world.time - SSticker.round_start_time - meteordelay) / 10 / 60 + + + if (prob(meteorminutes)) + wavetype = GLOB.meteors_threatening + + if (prob(meteorminutes/2)) + wavetype = GLOB.meteors_catastrophic + + var/ramp_up_final = CLAMP(round(meteorminutes/rampupdelta), 1, 10) + + spawn_meteors(ramp_up_final, wavetype) + + +/datum/game_mode/meteor/special_report() + var/survivors = 0 + var/list/survivor_list = list() + + for(var/mob/living/player in GLOB.player_list) + if(player.stat != DEAD) + ++survivors + + if(player.onCentCom()) + survivor_list += "[player.real_name] escaped to the safety of CentCom." + else if(player.onSyndieBase()) + survivor_list += "[player.real_name] escaped to the (relative) safety of Syndicate Space." + else + survivor_list += "[player.real_name] survived but is stranded without any hope of rescue." + + if(survivors) + return "
      The following survived the meteor storm:
      [survivor_list.Join("
      ")]
      " + else + return "
      Nobody survived the meteor storm!
      " + +/datum/game_mode/meteor/set_round_result() + ..() + SSticker.mode_result = "end - evacuation" + +/datum/game_mode/meteor/generate_report() + return "[pick("Asteroids have", "Meteors have", "Large rocks have", "Stellar minerals have", "Space hail has", "Debris has")] been detected near your station, and a collision is possible, \ + though unlikely. Be prepared for largescale impacts and destruction. Please note that the debris will prevent the escape shuttle from arriving quickly." diff --git a/code/game/gamemodes/objective_items.dm b/code/game/gamemodes/objective_items.dm index 176f62ef2d..d84c104a2f 100644 --- a/code/game/gamemodes/objective_items.dm +++ b/code/game/gamemodes/objective_items.dm @@ -1,265 +1,265 @@ -//Contains the target item datums for Steal objectives. - -/datum/objective_item - var/name = "A silly bike horn! Honk!" - var/targetitem = /obj/item/bikehorn //typepath of the objective item - var/difficulty = 9001 //vaguely how hard it is to do this objective - var/list/excludefromjob = list() //If you don't want a job to get a certain objective (no captain stealing his own medal, etcetc) - var/list/altitems = list() //Items which can serve as an alternative to the objective (darn you blueprints) - var/list/special_equipment = list() - -/datum/objective_item/proc/check_special_completion() //for objectives with special checks (is that slime extract unused? does that intellicard have an ai in it? etcetc) - return 1 - -/datum/objective_item/proc/TargetExists() - return TRUE - -/datum/objective_item/steal/New() - ..() - if(TargetExists()) - GLOB.possible_items += src - else - qdel(src) - -/datum/objective_item/steal/Destroy() - GLOB.possible_items -= src - return ..() - -/datum/objective_item/steal/caplaser - name = "the captain's antique laser gun." - targetitem = /obj/item/gun/energy/laser/captain - difficulty = 5 - excludefromjob = list("Captain") - -/datum/objective_item/steal/hoslaser - name = "the head of security's personal laser gun." - targetitem = /obj/item/gun/energy/e_gun/hos - difficulty = 10 - excludefromjob = list("Head Of Security") - -/datum/objective_item/steal/handtele - name = "a hand teleporter." - targetitem = /obj/item/hand_tele - difficulty = 5 - excludefromjob = list("Captain", "Research Director") - -/datum/objective_item/steal/jetpack - name = "the Captain's jetpack." - targetitem = /obj/item/tank/jetpack/oxygen/captain - difficulty = 5 - excludefromjob = list("Captain") - -/datum/objective_item/steal/magboots - name = "the chief engineer's advanced magnetic boots." - targetitem = /obj/item/clothing/shoes/magboots/advance - difficulty = 5 - excludefromjob = list("Chief Engineer", "Station Engineer", "Atmospheric Technician") - -/datum/objective_item/steal/capmedal - name = "the medal of captaincy." - targetitem = /obj/item/clothing/accessory/medal/gold/captain - difficulty = 5 - excludefromjob = list("Captain") - -/datum/objective_item/steal/hypo - name = "the Chief Medical Officer's MKII hypospray." - targetitem = /obj/item/hypospray/mkii/CMO //CITADEL EDIT, changing theft objective for the Hypo MK II - difficulty = 5 - excludefromjob = list("Chief Medical Officer", "Medical Doctor", "Chemist", "Virologist", "Geneticist") - -/datum/objective_item/steal/nukedisc - name = "the nuclear authentication disk." - targetitem = /obj/item/disk/nuclear - difficulty = 5 - excludefromjob = list("Captain") - -/datum/objective_item/steal/nukedisc/check_special_completion(obj/item/disk/nuclear/N) - return !N.fake - -/datum/objective_item/steal/reflector - name = "a reflector vest." - targetitem = /obj/item/clothing/suit/armor/laserproof - difficulty = 3 - excludefromjob = list("Head of Security", "Warden") - -/datum/objective_item/steal/reactive - name = "a reactive teleport armor." - targetitem = /obj/item/clothing/suit/armor/reactive - difficulty = 5 - excludefromjob = list("Research Director","Scientist", "Roboticist") - -/datum/objective_item/steal/documents - name = "any set of secret documents of any organization." - targetitem = /obj/item/documents //Any set of secret documents. Doesn't have to be NT's - difficulty = 5 - -/datum/objective_item/steal/nuke_core - name = "the heavily radioactive plutonium core from the onboard self-destruct. Take care to wear the proper safety equipment when extracting the core!" - targetitem = /obj/item/nuke_core - difficulty = 15 - -/datum/objective_item/steal/nuke_core/New() - special_equipment += /obj/item/storage/box/syndie_kit/nuke - ..() - -/datum/objective_item/steal/supermatter - name = "a sliver of a supermatter crystal. Be sure to use the proper safety equipment when extracting the sliver!" - targetitem = /obj/item/nuke_core/supermatter_sliver - difficulty = 15 - -/datum/objective_item/steal/supermatter/New() - special_equipment += /obj/item/storage/box/syndie_kit/supermatter - ..() - -/datum/objective_item/steal/supermatter/TargetExists() - return GLOB.main_supermatter_engine != null - -//Items with special checks! -/datum/objective_item/steal/plasma - name = "28 moles of plasma (full tank)." - targetitem = /obj/item/tank - difficulty = 3 - excludefromjob = list("Chief Engineer","Research Director","Station Engineer","Scientist","Atmospheric Technician") - -/datum/objective_item/steal/plasma/check_special_completion(obj/item/tank/T) - var/target_amount = text2num(name) - var/found_amount = 0 - found_amount += T.air_contents.gases[/datum/gas/plasma] - return found_amount>=target_amount - - -/datum/objective_item/steal/functionalai - name = "a functional AI." - targetitem = /obj/item/aicard - difficulty = 20 //beyond the impossible - -/datum/objective_item/steal/functionalai/check_special_completion(obj/item/aicard/C) - for(var/mob/living/silicon/ai/A in C) - if(isAI(A) && A.stat != DEAD) //See if any AI's are alive inside that card. - return 1 - return 0 - -/datum/objective_item/steal/blueprints - name = "the station blueprints." - targetitem = /obj/item/areaeditor/blueprints - difficulty = 10 - excludefromjob = list("Chief Engineer", "Station Engineer", "Atmospheric Technician") - altitems = list(/obj/item/photo) - -/datum/objective_item/steal/blueprints/check_special_completion(obj/item/I) - if(istype(I, /obj/item/areaeditor/blueprints)) - return TRUE - if(istype(I, /obj/item/photo)) - var/obj/item/photo/P = I - if(P.picture.has_blueprints) //if the blueprints are in frame - return TRUE - return FALSE - -/datum/objective_item/steal/slime - name = "an unused sample of slime extract." - targetitem = /obj/item/slime_extract - difficulty = 3 - excludefromjob = list("Research Director","Scientist", "Roboticist") - -/datum/objective_item/steal/slime/check_special_completion(obj/item/slime_extract/E) - if(E.Uses > 0) - return 1 - return 0 - -//Unique Objectives -/datum/objective_item/unique/docs_red - name = "the \"Red\" secret documents." - targetitem = /obj/item/documents/syndicate/red - difficulty = 10 - -/datum/objective_item/unique/docs_blue - name = "the \"Blue\" secret documents." - targetitem = /obj/item/documents/syndicate/blue - difficulty = 10 - -/datum/objective_item/special/New() - ..() - if(TargetExists()) - GLOB.possible_items_special += src - else - qdel(src) - -/datum/objective_item/special/Destroy() - GLOB.possible_items_special -= src - return ..() - -//Old ninja objectives. -/datum/objective_item/special/pinpointer/nuke - name = "the captain's pinpointer." - targetitem = /obj/item/pinpointer - difficulty = 10 - -/datum/objective_item/special/aegun - name = "an advanced energy gun." - targetitem = /obj/item/gun/energy/e_gun/nuclear - difficulty = 10 - -/datum/objective_item/special/ddrill - name = "a diamond drill." - targetitem = /obj/item/pickaxe/drill/diamonddrill - difficulty = 10 - -/datum/objective_item/special/boh - name = "a bag of holding." - targetitem = /obj/item/storage/backpack/holding - difficulty = 10 - -/datum/objective_item/special/hypercell - name = "a hyper-capacity power cell." - targetitem = /obj/item/stock_parts/cell/hyper - difficulty = 5 - -/datum/objective_item/special/laserpointer - name = "a laser pointer." - targetitem = /obj/item/laser_pointer - difficulty = 5 - -/datum/objective_item/special/corgimeat - name = "a piece of corgi meat." - targetitem = /obj/item/reagent_containers/food/snacks/meat/slab/corgi - difficulty = 5 - -/datum/objective_item/stack/New() - ..() - if(TargetExists()) - GLOB.possible_items_special += src - else - qdel(src) - -/datum/objective_item/stack/Destroy() - GLOB.possible_items_special -= src - return ..() - -//Stack objectives get their own subtype -/datum/objective_item/stack - name = "5 cardboard." - targetitem = /obj/item/stack/sheet/cardboard - difficulty = 9001 - -/datum/objective_item/stack/check_special_completion(obj/item/stack/S) - var/target_amount = text2num(name) - var/found_amount = 0 - - if(istype(S, targetitem)) - found_amount = S.amount - return found_amount>=target_amount - -/datum/objective_item/stack/diamond - name = "10 diamonds." - targetitem = /obj/item/stack/sheet/mineral/diamond - difficulty = 10 - -/datum/objective_item/stack/gold - name = "50 gold bars." - targetitem = /obj/item/stack/sheet/mineral/gold - difficulty = 15 - -/datum/objective_item/stack/uranium - name = "25 refined uranium bars." - targetitem = /obj/item/stack/sheet/mineral/uranium - difficulty = 10 +//Contains the target item datums for Steal objectives. + +/datum/objective_item + var/name = "A silly bike horn! Honk!" + var/targetitem = /obj/item/bikehorn //typepath of the objective item + var/difficulty = 9001 //vaguely how hard it is to do this objective + var/list/excludefromjob = list() //If you don't want a job to get a certain objective (no captain stealing his own medal, etcetc) + var/list/altitems = list() //Items which can serve as an alternative to the objective (darn you blueprints) + var/list/special_equipment = list() + +/datum/objective_item/proc/check_special_completion() //for objectives with special checks (is that slime extract unused? does that intellicard have an ai in it? etcetc) + return 1 + +/datum/objective_item/proc/TargetExists() + return TRUE + +/datum/objective_item/steal/New() + ..() + if(TargetExists()) + GLOB.possible_items += src + else + qdel(src) + +/datum/objective_item/steal/Destroy() + GLOB.possible_items -= src + return ..() + +/datum/objective_item/steal/caplaser + name = "the captain's antique laser gun." + targetitem = /obj/item/gun/energy/laser/captain + difficulty = 5 + excludefromjob = list("Captain") + +/datum/objective_item/steal/hoslaser + name = "the head of security's personal laser gun." + targetitem = /obj/item/gun/energy/e_gun/hos + difficulty = 10 + excludefromjob = list("Head Of Security") + +/datum/objective_item/steal/handtele + name = "a hand teleporter." + targetitem = /obj/item/hand_tele + difficulty = 5 + excludefromjob = list("Captain", "Research Director") + +/datum/objective_item/steal/jetpack + name = "the Captain's jetpack." + targetitem = /obj/item/tank/jetpack/oxygen/captain + difficulty = 5 + excludefromjob = list("Captain") + +/datum/objective_item/steal/magboots + name = "the chief engineer's advanced magnetic boots." + targetitem = /obj/item/clothing/shoes/magboots/advance + difficulty = 5 + excludefromjob = list("Chief Engineer", "Station Engineer", "Atmospheric Technician") + +/datum/objective_item/steal/capmedal + name = "the medal of captaincy." + targetitem = /obj/item/clothing/accessory/medal/gold/captain + difficulty = 5 + excludefromjob = list("Captain") + +/datum/objective_item/steal/hypo + name = "the Chief Medical Officer's MKII hypospray." + targetitem = /obj/item/hypospray/mkii/CMO //CITADEL EDIT, changing theft objective for the Hypo MK II + difficulty = 5 + excludefromjob = list("Chief Medical Officer", "Medical Doctor", "Chemist", "Virologist", "Geneticist") + +/datum/objective_item/steal/nukedisc + name = "the nuclear authentication disk." + targetitem = /obj/item/disk/nuclear + difficulty = 5 + excludefromjob = list("Captain") + +/datum/objective_item/steal/nukedisc/check_special_completion(obj/item/disk/nuclear/N) + return !N.fake + +/datum/objective_item/steal/reflector + name = "a reflector vest." + targetitem = /obj/item/clothing/suit/armor/laserproof + difficulty = 3 + excludefromjob = list("Head of Security", "Warden") + +/datum/objective_item/steal/reactive + name = "a reactive teleport armor." + targetitem = /obj/item/clothing/suit/armor/reactive + difficulty = 5 + excludefromjob = list("Research Director","Scientist", "Roboticist") + +/datum/objective_item/steal/documents + name = "any set of secret documents of any organization." + targetitem = /obj/item/documents //Any set of secret documents. Doesn't have to be NT's + difficulty = 5 + +/datum/objective_item/steal/nuke_core + name = "the heavily radioactive plutonium core from the onboard self-destruct. Take care to wear the proper safety equipment when extracting the core!" + targetitem = /obj/item/nuke_core + difficulty = 15 + +/datum/objective_item/steal/nuke_core/New() + special_equipment += /obj/item/storage/box/syndie_kit/nuke + ..() + +/datum/objective_item/steal/supermatter + name = "a sliver of a supermatter crystal. Be sure to use the proper safety equipment when extracting the sliver!" + targetitem = /obj/item/nuke_core/supermatter_sliver + difficulty = 15 + +/datum/objective_item/steal/supermatter/New() + special_equipment += /obj/item/storage/box/syndie_kit/supermatter + ..() + +/datum/objective_item/steal/supermatter/TargetExists() + return GLOB.main_supermatter_engine != null + +//Items with special checks! +/datum/objective_item/steal/plasma + name = "28 moles of plasma (full tank)." + targetitem = /obj/item/tank + difficulty = 3 + excludefromjob = list("Chief Engineer","Research Director","Station Engineer","Scientist","Atmospheric Technician") + +/datum/objective_item/steal/plasma/check_special_completion(obj/item/tank/T) + var/target_amount = text2num(name) + var/found_amount = 0 + found_amount += T.air_contents.gases[/datum/gas/plasma] + return found_amount>=target_amount + + +/datum/objective_item/steal/functionalai + name = "a functional AI." + targetitem = /obj/item/aicard + difficulty = 20 //beyond the impossible + +/datum/objective_item/steal/functionalai/check_special_completion(obj/item/aicard/C) + for(var/mob/living/silicon/ai/A in C) + if(isAI(A) && A.stat != DEAD) //See if any AI's are alive inside that card. + return 1 + return 0 + +/datum/objective_item/steal/blueprints + name = "the station blueprints." + targetitem = /obj/item/areaeditor/blueprints + difficulty = 10 + excludefromjob = list("Chief Engineer", "Station Engineer", "Atmospheric Technician") + altitems = list(/obj/item/photo) + +/datum/objective_item/steal/blueprints/check_special_completion(obj/item/I) + if(istype(I, /obj/item/areaeditor/blueprints)) + return TRUE + if(istype(I, /obj/item/photo)) + var/obj/item/photo/P = I + if(P.picture.has_blueprints) //if the blueprints are in frame + return TRUE + return FALSE + +/datum/objective_item/steal/slime + name = "an unused sample of slime extract." + targetitem = /obj/item/slime_extract + difficulty = 3 + excludefromjob = list("Research Director","Scientist", "Roboticist") + +/datum/objective_item/steal/slime/check_special_completion(obj/item/slime_extract/E) + if(E.Uses > 0) + return 1 + return 0 + +//Unique Objectives +/datum/objective_item/unique/docs_red + name = "the \"Red\" secret documents." + targetitem = /obj/item/documents/syndicate/red + difficulty = 10 + +/datum/objective_item/unique/docs_blue + name = "the \"Blue\" secret documents." + targetitem = /obj/item/documents/syndicate/blue + difficulty = 10 + +/datum/objective_item/special/New() + ..() + if(TargetExists()) + GLOB.possible_items_special += src + else + qdel(src) + +/datum/objective_item/special/Destroy() + GLOB.possible_items_special -= src + return ..() + +//Old ninja objectives. +/datum/objective_item/special/pinpointer/nuke + name = "the captain's pinpointer." + targetitem = /obj/item/pinpointer + difficulty = 10 + +/datum/objective_item/special/aegun + name = "an advanced energy gun." + targetitem = /obj/item/gun/energy/e_gun/nuclear + difficulty = 10 + +/datum/objective_item/special/ddrill + name = "a diamond drill." + targetitem = /obj/item/pickaxe/drill/diamonddrill + difficulty = 10 + +/datum/objective_item/special/boh + name = "a bag of holding." + targetitem = /obj/item/storage/backpack/holding + difficulty = 10 + +/datum/objective_item/special/hypercell + name = "a hyper-capacity power cell." + targetitem = /obj/item/stock_parts/cell/hyper + difficulty = 5 + +/datum/objective_item/special/laserpointer + name = "a laser pointer." + targetitem = /obj/item/laser_pointer + difficulty = 5 + +/datum/objective_item/special/corgimeat + name = "a piece of corgi meat." + targetitem = /obj/item/reagent_containers/food/snacks/meat/slab/corgi + difficulty = 5 + +/datum/objective_item/stack/New() + ..() + if(TargetExists()) + GLOB.possible_items_special += src + else + qdel(src) + +/datum/objective_item/stack/Destroy() + GLOB.possible_items_special -= src + return ..() + +//Stack objectives get their own subtype +/datum/objective_item/stack + name = "5 cardboard." + targetitem = /obj/item/stack/sheet/cardboard + difficulty = 9001 + +/datum/objective_item/stack/check_special_completion(obj/item/stack/S) + var/target_amount = text2num(name) + var/found_amount = 0 + + if(istype(S, targetitem)) + found_amount = S.amount + return found_amount>=target_amount + +/datum/objective_item/stack/diamond + name = "10 diamonds." + targetitem = /obj/item/stack/sheet/mineral/diamond + difficulty = 10 + +/datum/objective_item/stack/gold + name = "50 gold bars." + targetitem = /obj/item/stack/sheet/mineral/gold + difficulty = 15 + +/datum/objective_item/stack/uranium + name = "25 refined uranium bars." + targetitem = /obj/item/stack/sheet/mineral/uranium + difficulty = 10 diff --git a/code/game/gamemodes/sandbox/airlock_maker.dm b/code/game/gamemodes/sandbox/airlock_maker.dm index 6b988fd077..ddb622ab08 100644 --- a/code/game/gamemodes/sandbox/airlock_maker.dm +++ b/code/game/gamemodes/sandbox/airlock_maker.dm @@ -1,141 +1,141 @@ -/* - This is for the sandbox for now, - maybe useful later for an actual thing? - -Sayu -*/ - -/obj/structure/door_assembly - var/datum/airlock_maker/maker = null - -/obj/structure/door_assembly/attack_hand() - . = ..() - if(.) - return - if(maker) - maker.interact() - -/datum/airlock_maker - var/obj/structure/door_assembly/linked = null - - var/list/access_used = null - var/require_all = 1 - - var/paintjob = "none" - var/glassdoor = 0 - - var/doorname = "airlock" - -/datum/airlock_maker/New(var/atom/target_loc) - linked = new(target_loc) - linked.maker = src - linked.anchored = FALSE - access_used = list() - - interact() - -/datum/airlock_maker/proc/linkpretty(href,desc,active) - if(!desc) - var/static/list/defaults = list("No","Yes") - desc = defaults[active+1] - if(active) - return "[desc]" - return "[desc]" - -/datum/airlock_maker/proc/interact() - var/list/leftcolumn = list() - var/list/rightcolumn = list() - leftcolumn += "Required Access" - for(var/access in get_all_accesses()) - leftcolumn += linkpretty("access=[access]",get_access_desc(access),access in access_used) - leftcolumn += "Require all listed accesses: [linkpretty("reqall",null,require_all)]" - - rightcolumn += "Paintjob" - for(var/option in list("none","engineering","atmos","security","command","medical","research","mining","maintenance","external","highsecurity")) - rightcolumn += linkpretty("paint=[option]",option,option == paintjob) - rightcolumn += "Glass door: " + linkpretty("glass",null,glassdoor) + "

      " - var/length = max(leftcolumn.len,rightcolumn.len) - - var/dat = "You may move the model airlock around. A new airlock will be built in its space when you click done, below.

      " - dat += "Door name: \"[doorname]\"" - dat += "" - for(var/i=1; i<=length; i++) - dat += "" - - dat += "
      " - if(i<=leftcolumn.len) - dat += leftcolumn[i] - dat += "" - if(i<=rightcolumn.len) - dat += rightcolumn[i] - dat += "

      Finalize Airlock Construction | Cancel and Destroy Airlock" - usr << browse(dat,"window=airlockmaker") - -/datum/airlock_maker/Topic(var/href,var/list/href_list) - if(!usr) - return - if(!src || !linked || !linked.loc) - usr << browse(null,"window=airlockmaker") - return - - if("rename" in href_list) - var/newname = stripped_input(usr,"New airlock name:","Name the airlock",doorname) - if(newname) - doorname = newname - if("access" in href_list) - var/value = text2num(href_list["access"]) - access_used ^= value - if("reqall" in href_list) - require_all = !require_all - if("paint" in href_list) - paintjob = href_list["paint"] - if("glass" in href_list) - glassdoor = !glassdoor - - if("cancel" in href_list) - usr << browse(null,"window=airlockmaker") - qdel(linked) - qdel(src) - return - - if("done" in href_list) - usr << browse(null,"window=airlockmaker") - var/turf/t_loc = linked.loc - qdel(linked) - if(!istype(t_loc)) - return - - var/target_type = "/obj/machinery/door/airlock" - if(glassdoor) - if(paintjob != "none") - if(paintjob in list("external","highsecurity","maintenance")) // no glass version - target_type += "/[paintjob]" - else - target_type += "/glass_[paintjob]" - else - target_type += "/glass" - else if(paintjob != "none") - target_type += "/[paintjob]" - var/final = target_type - target_type = text2path(final) - if(!target_type) - to_chat(usr, "Didn't work, contact Sayu with this: [final]") - usr << browse(null,"window=airlockmaker") - return - - var/obj/machinery/door/D = new target_type(t_loc) - - D.name = doorname - - if(access_used.len == 0) - D.req_access = null - D.req_one_access = null - else if(require_all) - D.req_access = access_used.Copy() - D.req_one_access = null - else - D.req_access = null - D.req_one_access = access_used.Copy() - - return - - interact() +/* + This is for the sandbox for now, + maybe useful later for an actual thing? + -Sayu +*/ + +/obj/structure/door_assembly + var/datum/airlock_maker/maker = null + +/obj/structure/door_assembly/attack_hand() + . = ..() + if(.) + return + if(maker) + maker.interact() + +/datum/airlock_maker + var/obj/structure/door_assembly/linked = null + + var/list/access_used = null + var/require_all = 1 + + var/paintjob = "none" + var/glassdoor = 0 + + var/doorname = "airlock" + +/datum/airlock_maker/New(var/atom/target_loc) + linked = new(target_loc) + linked.maker = src + linked.anchored = FALSE + access_used = list() + + interact() + +/datum/airlock_maker/proc/linkpretty(href,desc,active) + if(!desc) + var/static/list/defaults = list("No","Yes") + desc = defaults[active+1] + if(active) + return "[desc]" + return "[desc]" + +/datum/airlock_maker/proc/interact() + var/list/leftcolumn = list() + var/list/rightcolumn = list() + leftcolumn += "Required Access" + for(var/access in get_all_accesses()) + leftcolumn += linkpretty("access=[access]",get_access_desc(access),access in access_used) + leftcolumn += "Require all listed accesses: [linkpretty("reqall",null,require_all)]" + + rightcolumn += "Paintjob" + for(var/option in list("none","engineering","atmos","security","command","medical","research","mining","maintenance","external","highsecurity")) + rightcolumn += linkpretty("paint=[option]",option,option == paintjob) + rightcolumn += "Glass door: " + linkpretty("glass",null,glassdoor) + "

      " + var/length = max(leftcolumn.len,rightcolumn.len) + + var/dat = "You may move the model airlock around. A new airlock will be built in its space when you click done, below.

      " + dat += "Door name: \"[doorname]\"" + dat += "" + for(var/i=1; i<=length; i++) + dat += "" + + dat += "
      " + if(i<=leftcolumn.len) + dat += leftcolumn[i] + dat += "" + if(i<=rightcolumn.len) + dat += rightcolumn[i] + dat += "

      Finalize Airlock Construction | Cancel and Destroy Airlock" + usr << browse(dat,"window=airlockmaker") + +/datum/airlock_maker/Topic(var/href,var/list/href_list) + if(!usr) + return + if(!src || !linked || !linked.loc) + usr << browse(null,"window=airlockmaker") + return + + if("rename" in href_list) + var/newname = stripped_input(usr,"New airlock name:","Name the airlock",doorname) + if(newname) + doorname = newname + if("access" in href_list) + var/value = text2num(href_list["access"]) + access_used ^= value + if("reqall" in href_list) + require_all = !require_all + if("paint" in href_list) + paintjob = href_list["paint"] + if("glass" in href_list) + glassdoor = !glassdoor + + if("cancel" in href_list) + usr << browse(null,"window=airlockmaker") + qdel(linked) + qdel(src) + return + + if("done" in href_list) + usr << browse(null,"window=airlockmaker") + var/turf/t_loc = linked.loc + qdel(linked) + if(!istype(t_loc)) + return + + var/target_type = "/obj/machinery/door/airlock" + if(glassdoor) + if(paintjob != "none") + if(paintjob in list("external","highsecurity","maintenance")) // no glass version + target_type += "/[paintjob]" + else + target_type += "/glass_[paintjob]" + else + target_type += "/glass" + else if(paintjob != "none") + target_type += "/[paintjob]" + var/final = target_type + target_type = text2path(final) + if(!target_type) + to_chat(usr, "Didn't work, contact Sayu with this: [final]") + usr << browse(null,"window=airlockmaker") + return + + var/obj/machinery/door/D = new target_type(t_loc) + + D.name = doorname + + if(access_used.len == 0) + D.req_access = null + D.req_one_access = null + else if(require_all) + D.req_access = access_used.Copy() + D.req_one_access = null + else + D.req_access = null + D.req_one_access = access_used.Copy() + + return + + interact() diff --git a/code/game/gamemodes/sandbox/h_sandbox.dm b/code/game/gamemodes/sandbox/h_sandbox.dm index d54dda5353..e1fbb636c8 100644 --- a/code/game/gamemodes/sandbox/h_sandbox.dm +++ b/code/game/gamemodes/sandbox/h_sandbox.dm @@ -1,303 +1,303 @@ - - -GLOBAL_VAR_INIT(hsboxspawn, TRUE) - -/mob - var/datum/hSB/sandbox = null -/mob/proc/CanBuild() - sandbox = new/datum/hSB - sandbox.owner = src.ckey - if(src.client.holder) - sandbox.admin = 1 - verbs += new/mob/proc/sandbox_panel -/mob/proc/sandbox_panel() - set name = "Sandbox Panel" - if(sandbox) - sandbox.update() - -/datum/hSB - var/owner = null - var/admin = 0 - - var/static/clothinfo = null - var/static/reaginfo = null - var/static/objinfo = null - var/canisterinfo = null - var/hsbinfo = null - //items that shouldn't spawn on the floor because they would bug or act weird - var/static/list/spawn_forbidden = list( - /obj/item/tk_grab, /obj/item/implant, // not implanter, the actual thing that is inside you - /obj/item/assembly, /obj/item/onetankbomb, /obj/item/pda/ai, - /obj/item/smallDelivery, /obj/item/projectile, - /obj/item/borg/sight, /obj/item/borg/stun, /obj/item/robot_module) - -/datum/hSB/proc/update() - var/static/list/hrefs = list( - "Space Gear", - "Suit Up (Space Travel Gear)" = "hsbsuit", - "Spawn Gas Mask" = "hsbspawn&path=[/obj/item/clothing/mask/gas]", - "Spawn Emergency Air Tank" = "hsbspawn&path=[/obj/item/tank/internals/emergency_oxygen/double]", - - "Standard Tools", - "Spawn Flashlight" = "hsbspawn&path=[/obj/item/flashlight]", - "Spawn Toolbox" = "hsbspawn&path=[/obj/item/storage/toolbox/mechanical]", - "Spawn Light Replacer" = "hsbspawn&path=[/obj/item/lightreplacer]", - "Spawn Medical Kit" = "hsbspawn&path=[/obj/item/storage/firstaid/regular]", - "Spawn All-Access ID" = "hsbaaid", - - "Building Supplies", - "Spawn 50 Wood" = "hsbwood", - "Spawn 50 Metal" = "hsbmetal", - "Spawn 50 Plasteel" = "hsbplasteel", - "Spawn 50 Reinforced Glass" = "hsbrglass", - "Spawn 50 Glass" = "hsbglass", - "Spawn Full Cable Coil" = "hsbspawn&path=[/obj/item/stack/cable_coil]", - "Spawn Hyper Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/hyper]", - "Spawn Inf. Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/infinite]", - "Spawn Rapid Construction Device" = "hsbrcd", - "Spawn RCD Ammo" = "hsb_safespawn&path=[/obj/item/rcd_ammo]", - "Spawn Airlock" = "hsbairlock", - - "Miscellaneous", - "Spawn Air Scrubber" = "hsbscrubber", - "Spawn Welding Fuel Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/fueltank]", - "Spawn Water Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/watertank]", - - "Bots", - "Spawn Cleanbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/cleanbot]", - "Spawn Floorbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/floorbot]", - "Spawn Medbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/medbot]", - - "Canisters", - "Spawn O2 Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/oxygen]", - "Spawn Air Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/air]") - - - if(!hsbinfo) - hsbinfo = "
      Sandbox Panel

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

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

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

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

      " - var/list/all_items = subtypesof(/obj/item/) - typesof(/obj/item/clothing) - typesof(/obj/item/reagent_containers) - for(var/typekey in spawn_forbidden) - all_items -= typesof(typekey) - - for(var/O in reverseRange(all_items)) - objinfo += "[O]
      " - - usr << browse(objinfo,"window=sandbox") - - // - // Safespawn checks to see if spawning is disabled. - // - if("hsb_safespawn") - if(!GLOB.hsboxspawn) - usr << browse(null,"window=sandbox") - return - - var/typepath = text2path(href_list["path"]) - if(!typepath) - to_chat(usr, "Bad path: \"[href_list["path"]]\"") - return - new typepath(usr.loc) - - if(CONFIG_GET(flag/sandbox_autoclose)) - usr << browse(null,"window=sandbox") - // - // For everything else in the href list - // - if("hsbspawn") - var/typepath = text2path(href_list["path"]) - if(!typepath) - to_chat(usr, "Bad path: \"[href_list["path"]]\"") - return - new typepath(usr.loc) - - if(CONFIG_GET(flag/sandbox_autoclose)) - usr << browse(null,"window=sandbox") + + +GLOBAL_VAR_INIT(hsboxspawn, TRUE) + +/mob + var/datum/hSB/sandbox = null +/mob/proc/CanBuild() + sandbox = new/datum/hSB + sandbox.owner = src.ckey + if(src.client.holder) + sandbox.admin = 1 + verbs += new/mob/proc/sandbox_panel +/mob/proc/sandbox_panel() + set name = "Sandbox Panel" + if(sandbox) + sandbox.update() + +/datum/hSB + var/owner = null + var/admin = 0 + + var/static/clothinfo = null + var/static/reaginfo = null + var/static/objinfo = null + var/canisterinfo = null + var/hsbinfo = null + //items that shouldn't spawn on the floor because they would bug or act weird + var/static/list/spawn_forbidden = list( + /obj/item/tk_grab, /obj/item/implant, // not implanter, the actual thing that is inside you + /obj/item/assembly, /obj/item/onetankbomb, /obj/item/pda/ai, + /obj/item/smallDelivery, /obj/item/projectile, + /obj/item/borg/sight, /obj/item/borg/stun, /obj/item/robot_module) + +/datum/hSB/proc/update() + var/static/list/hrefs = list( + "Space Gear", + "Suit Up (Space Travel Gear)" = "hsbsuit", + "Spawn Gas Mask" = "hsbspawn&path=[/obj/item/clothing/mask/gas]", + "Spawn Emergency Air Tank" = "hsbspawn&path=[/obj/item/tank/internals/emergency_oxygen/double]", + + "Standard Tools", + "Spawn Flashlight" = "hsbspawn&path=[/obj/item/flashlight]", + "Spawn Toolbox" = "hsbspawn&path=[/obj/item/storage/toolbox/mechanical]", + "Spawn Light Replacer" = "hsbspawn&path=[/obj/item/lightreplacer]", + "Spawn Medical Kit" = "hsbspawn&path=[/obj/item/storage/firstaid/regular]", + "Spawn All-Access ID" = "hsbaaid", + + "Building Supplies", + "Spawn 50 Wood" = "hsbwood", + "Spawn 50 Metal" = "hsbmetal", + "Spawn 50 Plasteel" = "hsbplasteel", + "Spawn 50 Reinforced Glass" = "hsbrglass", + "Spawn 50 Glass" = "hsbglass", + "Spawn Full Cable Coil" = "hsbspawn&path=[/obj/item/stack/cable_coil]", + "Spawn Hyper Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/hyper]", + "Spawn Inf. Capacity Power Cell" = "hsbspawn&path=[/obj/item/stock_parts/cell/infinite]", + "Spawn Rapid Construction Device" = "hsbrcd", + "Spawn RCD Ammo" = "hsb_safespawn&path=[/obj/item/rcd_ammo]", + "Spawn Airlock" = "hsbairlock", + + "Miscellaneous", + "Spawn Air Scrubber" = "hsbscrubber", + "Spawn Welding Fuel Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/fueltank]", + "Spawn Water Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/watertank]", + + "Bots", + "Spawn Cleanbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/cleanbot]", + "Spawn Floorbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/floorbot]", + "Spawn Medbot" = "hsbspawn&path=[/mob/living/simple_animal/bot/medbot]", + + "Canisters", + "Spawn O2 Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/oxygen]", + "Spawn Air Canister" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/canister/air]") + + + if(!hsbinfo) + hsbinfo = "
      Sandbox Panel

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

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

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

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

      " + var/list/all_items = subtypesof(/obj/item/) - typesof(/obj/item/clothing) - typesof(/obj/item/reagent_containers) + for(var/typekey in spawn_forbidden) + all_items -= typesof(typekey) + + for(var/O in reverseRange(all_items)) + objinfo += "[O]
      " + + usr << browse(objinfo,"window=sandbox") + + // + // Safespawn checks to see if spawning is disabled. + // + if("hsb_safespawn") + if(!GLOB.hsboxspawn) + usr << browse(null,"window=sandbox") + return + + var/typepath = text2path(href_list["path"]) + if(!typepath) + to_chat(usr, "Bad path: \"[href_list["path"]]\"") + return + new typepath(usr.loc) + + if(CONFIG_GET(flag/sandbox_autoclose)) + usr << browse(null,"window=sandbox") + // + // For everything else in the href list + // + if("hsbspawn") + var/typepath = text2path(href_list["path"]) + if(!typepath) + to_chat(usr, "Bad path: \"[href_list["path"]]\"") + return + new typepath(usr.loc) + + if(CONFIG_GET(flag/sandbox_autoclose)) + usr << browse(null,"window=sandbox") diff --git a/code/game/gamemodes/sandbox/sandbox.dm b/code/game/gamemodes/sandbox/sandbox.dm index 21169b8236..9c38bd83e8 100644 --- a/code/game/gamemodes/sandbox/sandbox.dm +++ b/code/game/gamemodes/sandbox/sandbox.dm @@ -1,21 +1,21 @@ -/datum/game_mode/sandbox - name = "sandbox" - config_tag = "sandbox" - required_players = 0 - - announce_span = "info" - announce_text = "Build your own station... or just shoot each other!" - - allow_persistence_save = FALSE - -/datum/game_mode/sandbox/pre_setup() - for(var/mob/M in GLOB.player_list) - M.CanBuild() - return 1 - -/datum/game_mode/sandbox/post_setup() - ..() - SSshuttle.registerHostileEnvironment(src) - -/datum/game_mode/sandbox/generate_report() - return "Sensors indicate that crewmembers have been all given psychic powers from which they can manifest various objects.

      This can only end poorly." +/datum/game_mode/sandbox + name = "sandbox" + config_tag = "sandbox" + required_players = 0 + + announce_span = "info" + announce_text = "Build your own station... or just shoot each other!" + + allow_persistence_save = FALSE + +/datum/game_mode/sandbox/pre_setup() + for(var/mob/M in GLOB.player_list) + M.CanBuild() + return 1 + +/datum/game_mode/sandbox/post_setup() + ..() + SSshuttle.registerHostileEnvironment(src) + +/datum/game_mode/sandbox/generate_report() + return "Sensors indicate that crewmembers have been all given psychic powers from which they can manifest various objects.

      This can only end poorly." diff --git a/code/game/gamemodes/traitor/double_agents.dm b/code/game/gamemodes/traitor/double_agents.dm index 3811fa9562..fc669d4855 100644 --- a/code/game/gamemodes/traitor/double_agents.dm +++ b/code/game/gamemodes/traitor/double_agents.dm @@ -1,82 +1,82 @@ -/datum/game_mode - var/list/target_list = list() - var/list/late_joining_list = list() - -/datum/game_mode/traitor/internal_affairs - name = "Internal Affairs" - config_tag = "internal_affairs" - false_report_weight = 10 - required_players = 25 - required_enemies = 5 - recommended_enemies = 8 - reroll_friendly = 0 - traitor_name = "Nanotrasen Internal Affairs Agent" - antag_flag = ROLE_INTERNAL_AFFAIRS - - traitors_possible = 10 //hard limit on traitors if scaling is turned off - num_modifier = 4 // Four additional traitors - antag_datum = /datum/antagonist/traitor/internal_affairs - - announce_text = "There are Nanotrasen Internal Affairs Agents trying to kill each other!\n\ - IAA: Eliminate your targets and protect yourself!\n\ - Crew: Stop the IAA agents before they can cause too much mayhem." - - - -/datum/game_mode/traitor/internal_affairs/post_setup() - var/i = 0 - for(var/datum/mind/traitor in pre_traitors) - i++ - if(i + 1 > pre_traitors.len) - i = 0 - target_list[traitor] = pre_traitors[i+1] - ..() - - -/datum/game_mode/traitor/internal_affairs/add_latejoin_traitor(datum/mind/character) - - check_potential_agents() - - // As soon as we get 3 or 4 extra latejoin traitors, make them traitors and kill each other. - if(late_joining_list.len >= rand(3, 4)) - // True randomness - shuffle_inplace(late_joining_list) - // Reset the target_list, it'll be used again in force_traitor_objectives - target_list = list() - - // Basically setting the target_list for who is killing who - var/i = 0 - for(var/datum/mind/traitor in late_joining_list) - i++ - if(i + 1 > late_joining_list.len) - i = 0 - target_list[traitor] = late_joining_list[i + 1] - traitor.special_role = traitor_name - - // Now, give them their targets - for(var/datum/mind/traitor in target_list) - ..(traitor) - - late_joining_list = list() - else - late_joining_list += character - return - -/datum/game_mode/traitor/internal_affairs/proc/check_potential_agents() - - for(var/M in late_joining_list) - if(istype(M, /datum/mind)) - var/datum/mind/agent_mind = M - if(ishuman(agent_mind.current)) - var/mob/living/carbon/human/H = agent_mind.current - if(H.stat != DEAD) - if(H.client) - continue // It all checks out. - - // If any check fails, remove them from our list - late_joining_list -= M - - -/datum/game_mode/traitor/internal_affairs/generate_report() - return "Nanotrasen denies any accusations of placing internal affairs agents onboard your station to eliminate inconvenient employees. Any further accusations against CentCom for such \ - actions will be met with a conversation with an official internal affairs agent." +/datum/game_mode + var/list/target_list = list() + var/list/late_joining_list = list() + +/datum/game_mode/traitor/internal_affairs + name = "Internal Affairs" + config_tag = "internal_affairs" + false_report_weight = 10 + required_players = 25 + required_enemies = 5 + recommended_enemies = 8 + reroll_friendly = 0 + traitor_name = "Nanotrasen Internal Affairs Agent" + antag_flag = ROLE_INTERNAL_AFFAIRS + + traitors_possible = 10 //hard limit on traitors if scaling is turned off + num_modifier = 4 // Four additional traitors + antag_datum = /datum/antagonist/traitor/internal_affairs + + announce_text = "There are Nanotrasen Internal Affairs Agents trying to kill each other!\n\ + IAA: Eliminate your targets and protect yourself!\n\ + Crew: Stop the IAA agents before they can cause too much mayhem." + + + +/datum/game_mode/traitor/internal_affairs/post_setup() + var/i = 0 + for(var/datum/mind/traitor in pre_traitors) + i++ + if(i + 1 > pre_traitors.len) + i = 0 + target_list[traitor] = pre_traitors[i+1] + ..() + + +/datum/game_mode/traitor/internal_affairs/add_latejoin_traitor(datum/mind/character) + + check_potential_agents() + + // As soon as we get 3 or 4 extra latejoin traitors, make them traitors and kill each other. + if(late_joining_list.len >= rand(3, 4)) + // True randomness + shuffle_inplace(late_joining_list) + // Reset the target_list, it'll be used again in force_traitor_objectives + target_list = list() + + // Basically setting the target_list for who is killing who + var/i = 0 + for(var/datum/mind/traitor in late_joining_list) + i++ + if(i + 1 > late_joining_list.len) + i = 0 + target_list[traitor] = late_joining_list[i + 1] + traitor.special_role = traitor_name + + // Now, give them their targets + for(var/datum/mind/traitor in target_list) + ..(traitor) + + late_joining_list = list() + else + late_joining_list += character + return + +/datum/game_mode/traitor/internal_affairs/proc/check_potential_agents() + + for(var/M in late_joining_list) + if(istype(M, /datum/mind)) + var/datum/mind/agent_mind = M + if(ishuman(agent_mind.current)) + var/mob/living/carbon/human/H = agent_mind.current + if(H.stat != DEAD) + if(H.client) + continue // It all checks out. + + // If any check fails, remove them from our list + late_joining_list -= M + + +/datum/game_mode/traitor/internal_affairs/generate_report() + return "Nanotrasen denies any accusations of placing internal affairs agents onboard your station to eliminate inconvenient employees. Any further accusations against CentCom for such \ + actions will be met with a conversation with an official internal affairs agent." diff --git a/code/game/gamemodes/traitor/traitor.dm b/code/game/gamemodes/traitor/traitor.dm index 4a6e72cf67..8b1b18660a 100644 --- a/code/game/gamemodes/traitor/traitor.dm +++ b/code/game/gamemodes/traitor/traitor.dm @@ -1,99 +1,99 @@ -/datum/game_mode - var/traitor_name = "traitor" - var/list/datum/mind/traitors = list() - - var/datum/mind/exchange_red - var/datum/mind/exchange_blue - -/datum/game_mode/traitor - name = "traitor" - config_tag = "traitor" - antag_flag = ROLE_TRAITOR - false_report_weight = 20 //Reports of traitors are pretty common. - restricted_jobs = list("Cyborg")//They are part of the AI if he is traitor so are they, they use to get double chances - protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") //citadel change - adds HoP, CE, CMO, and RD to ling role blacklist - required_players = 0 - required_enemies = 1 - recommended_enemies = 4 - reroll_friendly = 1 - enemy_minimum_age = 0 - - announce_span = "danger" - announce_text = "There are Syndicate agents on the station!\n\ - Traitors: Accomplish your objectives.\n\ - Crew: Do not let the traitors succeed!" - - var/list/datum/mind/pre_traitors = list() - var/traitors_possible = 4 //hard limit on traitors if scaling is turned off - var/num_modifier = 0 // Used for gamemodes, that are a child of traitor, that need more than the usual. - var/antag_datum = /datum/antagonist/traitor //what type of antag to create - var/traitors_required = TRUE //Will allow no traitors - - -/datum/game_mode/traitor/pre_setup() - - if(CONFIG_GET(flag/protect_roles_from_antagonist)) - restricted_jobs += protected_jobs - - if(CONFIG_GET(flag/protect_assistant_from_antagonist)) - restricted_jobs += "Assistant" - - var/num_traitors = 1 - - var/tsc = CONFIG_GET(number/traitor_scaling_coeff) - if(tsc) - num_traitors = max(1, min(round(num_players() / (tsc * 2)) + 2 + num_modifier, round(num_players() / tsc) + num_modifier)) - else - num_traitors = max(1, min(num_players(), traitors_possible)) - - for(var/j = 0, j < num_traitors, j++) - if (!antag_candidates.len) - break - var/datum/mind/traitor = antag_pick(antag_candidates) - pre_traitors += traitor - traitor.special_role = traitor_name - traitor.restricted_roles = restricted_jobs - log_game("[key_name(traitor)] has been selected as a [traitor_name]") - antag_candidates.Remove(traitor) - - var/enough_tators = !traitors_required || pre_traitors.len > 0 - - if(!enough_tators) - setup_error = "Not enough traitor candidates" - return FALSE - else - return TRUE - - -/datum/game_mode/traitor/post_setup() - for(var/datum/mind/traitor in pre_traitors) - var/datum/antagonist/traitor/new_antag = new antag_datum() - addtimer(CALLBACK(traitor, /datum/mind.proc/add_antag_datum, new_antag), rand(10,100)) - if(!exchange_blue) - exchange_blue = -1 //Block latejoiners from getting exchange objectives - ..() - - //We're not actually ready until all traitors are assigned. - gamemode_ready = FALSE - addtimer(VARSET_CALLBACK(src, gamemode_ready, TRUE), 101) - return TRUE - -/datum/game_mode/traitor/make_antag_chance(mob/living/carbon/human/character) //Assigns traitor to latejoiners - var/tsc = CONFIG_GET(number/traitor_scaling_coeff) - var/traitorcap = min(round(GLOB.joined_player_list.len / (tsc * 2)) + 2 + num_modifier, round(GLOB.joined_player_list.len / tsc) + num_modifier) - if((SSticker.mode.traitors.len + pre_traitors.len) >= traitorcap) //Upper cap for number of latejoin antagonists - return - if((SSticker.mode.traitors.len + pre_traitors.len) <= (traitorcap - 2) || prob(100 / (tsc * 2))) - if(antag_flag in character.client.prefs.be_special) - if(!jobban_isbanned(character, ROLE_TRAITOR) && !QDELETED(character) && !jobban_isbanned(character, ROLE_SYNDICATE) && !QDELETED(character)) - if(age_check(character.client)) - if(!(character.job in restricted_jobs)) - add_latejoin_traitor(character.mind) - -/datum/game_mode/traitor/proc/add_latejoin_traitor(datum/mind/character) - var/datum/antagonist/traitor/new_antag = new antag_datum() - character.add_antag_datum(new_antag) - -/datum/game_mode/traitor/generate_report() - return "Although more specific threats are commonplace, you should always remain vigilant for Syndicate agents aboard your station. Syndicate communications have implied that many \ - Nanotrasen employees are Syndicate agents with hidden memories that may be activated at a moment's notice, so it's possible that these agents might not even know their positions." +/datum/game_mode + var/traitor_name = "traitor" + var/list/datum/mind/traitors = list() + + var/datum/mind/exchange_red + var/datum/mind/exchange_blue + +/datum/game_mode/traitor + name = "traitor" + config_tag = "traitor" + antag_flag = ROLE_TRAITOR + false_report_weight = 20 //Reports of traitors are pretty common. + restricted_jobs = list("Cyborg")//They are part of the AI if he is traitor so are they, they use to get double chances + protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster") //citadel change - adds HoP, CE, CMO, and RD to ling role blacklist + required_players = 0 + required_enemies = 1 + recommended_enemies = 4 + reroll_friendly = 1 + enemy_minimum_age = 0 + + announce_span = "danger" + announce_text = "There are Syndicate agents on the station!\n\ + Traitors: Accomplish your objectives.\n\ + Crew: Do not let the traitors succeed!" + + var/list/datum/mind/pre_traitors = list() + var/traitors_possible = 4 //hard limit on traitors if scaling is turned off + var/num_modifier = 0 // Used for gamemodes, that are a child of traitor, that need more than the usual. + var/antag_datum = /datum/antagonist/traitor //what type of antag to create + var/traitors_required = TRUE //Will allow no traitors + + +/datum/game_mode/traitor/pre_setup() + + if(CONFIG_GET(flag/protect_roles_from_antagonist)) + restricted_jobs += protected_jobs + + if(CONFIG_GET(flag/protect_assistant_from_antagonist)) + restricted_jobs += "Assistant" + + var/num_traitors = 1 + + var/tsc = CONFIG_GET(number/traitor_scaling_coeff) + if(tsc) + num_traitors = max(1, min(round(num_players() / (tsc * 2)) + 2 + num_modifier, round(num_players() / tsc) + num_modifier)) + else + num_traitors = max(1, min(num_players(), traitors_possible)) + + for(var/j = 0, j < num_traitors, j++) + if (!antag_candidates.len) + break + var/datum/mind/traitor = antag_pick(antag_candidates) + pre_traitors += traitor + traitor.special_role = traitor_name + traitor.restricted_roles = restricted_jobs + log_game("[key_name(traitor)] has been selected as a [traitor_name]") + antag_candidates.Remove(traitor) + + var/enough_tators = !traitors_required || pre_traitors.len > 0 + + if(!enough_tators) + setup_error = "Not enough traitor candidates" + return FALSE + else + return TRUE + + +/datum/game_mode/traitor/post_setup() + for(var/datum/mind/traitor in pre_traitors) + var/datum/antagonist/traitor/new_antag = new antag_datum() + addtimer(CALLBACK(traitor, /datum/mind.proc/add_antag_datum, new_antag), rand(10,100)) + if(!exchange_blue) + exchange_blue = -1 //Block latejoiners from getting exchange objectives + ..() + + //We're not actually ready until all traitors are assigned. + gamemode_ready = FALSE + addtimer(VARSET_CALLBACK(src, gamemode_ready, TRUE), 101) + return TRUE + +/datum/game_mode/traitor/make_antag_chance(mob/living/carbon/human/character) //Assigns traitor to latejoiners + var/tsc = CONFIG_GET(number/traitor_scaling_coeff) + var/traitorcap = min(round(GLOB.joined_player_list.len / (tsc * 2)) + 2 + num_modifier, round(GLOB.joined_player_list.len / tsc) + num_modifier) + if((SSticker.mode.traitors.len + pre_traitors.len) >= traitorcap) //Upper cap for number of latejoin antagonists + return + if((SSticker.mode.traitors.len + pre_traitors.len) <= (traitorcap - 2) || prob(100 / (tsc * 2))) + if(antag_flag in character.client.prefs.be_special) + if(!jobban_isbanned(character, ROLE_TRAITOR) && !QDELETED(character) && !jobban_isbanned(character, ROLE_SYNDICATE) && !QDELETED(character)) + if(age_check(character.client)) + if(!(character.job in restricted_jobs)) + add_latejoin_traitor(character.mind) + +/datum/game_mode/traitor/proc/add_latejoin_traitor(datum/mind/character) + var/datum/antagonist/traitor/new_antag = new antag_datum() + character.add_antag_datum(new_antag) + +/datum/game_mode/traitor/generate_report() + return "Although more specific threats are commonplace, you should always remain vigilant for Syndicate agents aboard your station. Syndicate communications have implied that many \ + Nanotrasen employees are Syndicate agents with hidden memories that may be activated at a moment's notice, so it's possible that these agents might not even know their positions." diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm index 9ea2694354..2f3645a248 100644 --- a/code/game/gamemodes/wizard/wizard.dm +++ b/code/game/gamemodes/wizard/wizard.dm @@ -1,73 +1,73 @@ -/datum/game_mode - var/list/datum/mind/wizards = list() - var/list/datum/mind/apprentices = list() - -/datum/game_mode/wizard - name = "wizard" - config_tag = "wizard" - antag_flag = ROLE_WIZARD - false_report_weight = 10 - required_players = 20 - required_enemies = 1 - recommended_enemies = 1 - enemy_minimum_age = 7 - round_ends_with_antag_death = 1 - announce_span = "danger" - announce_text = "There is a space wizard attacking the station!\n\ - Wizard: Accomplish your objectives and cause mayhem on the station.\n\ - Crew: Eliminate the wizard before they can succeed!" - var/finished = 0 - -/datum/game_mode/wizard/pre_setup() - var/datum/mind/wizard = antag_pick(antag_candidates) - wizards += wizard - wizard.assigned_role = ROLE_WIZARD - wizard.special_role = ROLE_WIZARD - log_game("[key_name(wizard)] has been selected as a Wizard") //TODO: Move these to base antag datum - if(GLOB.wizardstart.len == 0) - setup_error = "No wizard starting location found" - return FALSE - for(var/datum/mind/wiz in wizards) - wiz.current.forceMove(pick(GLOB.wizardstart)) - return TRUE - - -/datum/game_mode/wizard/post_setup() - for(var/datum/mind/wizard in wizards) - wizard.add_antag_datum(/datum/antagonist/wizard) - return ..() - -/datum/game_mode/wizard/generate_report() - return "A dangerous Wizards' Federation individual by the name of [pick(GLOB.wizard_first)] [pick(GLOB.wizard_second)] has recently escaped confinement from an unlisted prison facility. This \ - man is a dangerous mutant with the ability to alter himself and the world around him by what he and his leaders believe to be magic. If this man attempts an attack on your station, \ - his execution is highly encouraged, as is the preservation of his body for later study." - - -/datum/game_mode/wizard/are_special_antags_dead() - for(var/datum/mind/wizard in wizards) - if(isliving(wizard.current) && wizard.current.stat!=DEAD) - return FALSE - - for(var/obj/item/phylactery/P in GLOB.poi_list) //TODO : IsProperlyDead() - if(P.mind && P.mind.has_antag_datum(/datum/antagonist/wizard)) - return FALSE - - if(SSevents.wizardmode) //If summon events was active, turn it off - SSevents.toggleWizardmode() - SSevents.resetFrequency() - - return TRUE - -/datum/game_mode/wizard/set_round_result() - ..() - if(finished) - SSticker.mode_result = "loss - wizard killed" - SSticker.news_report = WIZARD_KILLED - -/datum/game_mode/wizard/special_report() - if(finished) - return "The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!" - -//returns whether the mob is a wizard (or apprentice) -/proc/iswizard(mob/living/M) - return M.mind && M.mind.has_antag_datum(/datum/antagonist/wizard,TRUE) +/datum/game_mode + var/list/datum/mind/wizards = list() + var/list/datum/mind/apprentices = list() + +/datum/game_mode/wizard + name = "wizard" + config_tag = "wizard" + antag_flag = ROLE_WIZARD + false_report_weight = 10 + required_players = 20 + required_enemies = 1 + recommended_enemies = 1 + enemy_minimum_age = 7 + round_ends_with_antag_death = 1 + announce_span = "danger" + announce_text = "There is a space wizard attacking the station!\n\ + Wizard: Accomplish your objectives and cause mayhem on the station.\n\ + Crew: Eliminate the wizard before they can succeed!" + var/finished = 0 + +/datum/game_mode/wizard/pre_setup() + var/datum/mind/wizard = antag_pick(antag_candidates) + wizards += wizard + wizard.assigned_role = ROLE_WIZARD + wizard.special_role = ROLE_WIZARD + log_game("[key_name(wizard)] has been selected as a Wizard") //TODO: Move these to base antag datum + if(GLOB.wizardstart.len == 0) + setup_error = "No wizard starting location found" + return FALSE + for(var/datum/mind/wiz in wizards) + wiz.current.forceMove(pick(GLOB.wizardstart)) + return TRUE + + +/datum/game_mode/wizard/post_setup() + for(var/datum/mind/wizard in wizards) + wizard.add_antag_datum(/datum/antagonist/wizard) + return ..() + +/datum/game_mode/wizard/generate_report() + return "A dangerous Wizards' Federation individual by the name of [pick(GLOB.wizard_first)] [pick(GLOB.wizard_second)] has recently escaped confinement from an unlisted prison facility. This \ + man is a dangerous mutant with the ability to alter himself and the world around him by what he and his leaders believe to be magic. If this man attempts an attack on your station, \ + his execution is highly encouraged, as is the preservation of his body for later study." + + +/datum/game_mode/wizard/are_special_antags_dead() + for(var/datum/mind/wizard in wizards) + if(isliving(wizard.current) && wizard.current.stat!=DEAD) + return FALSE + + for(var/obj/item/phylactery/P in GLOB.poi_list) //TODO : IsProperlyDead() + if(P.mind && P.mind.has_antag_datum(/datum/antagonist/wizard)) + return FALSE + + if(SSevents.wizardmode) //If summon events was active, turn it off + SSevents.toggleWizardmode() + SSevents.resetFrequency() + + return TRUE + +/datum/game_mode/wizard/set_round_result() + ..() + if(finished) + SSticker.mode_result = "loss - wizard killed" + SSticker.news_report = WIZARD_KILLED + +/datum/game_mode/wizard/special_report() + if(finished) + return "The wizard[(wizards.len>1)?"s":""] has been killed by the crew! The Space Wizards Federation has been taught a lesson they will not soon forget!" + +//returns whether the mob is a wizard (or apprentice) +/proc/iswizard(mob/living/M) + return M.mind && M.mind.has_antag_datum(/datum/antagonist/wizard,TRUE) diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/Beacon.dm index c98795c90b..84eda82ef5 100644 --- a/code/game/machinery/Beacon.dm +++ b/code/game/machinery/Beacon.dm @@ -1,48 +1,48 @@ -/obj/machinery/bluespace_beacon - - icon = 'icons/obj/objects.dmi' - icon_state = "floor_beaconf" - name = "bluespace gigabeacon" - desc = "A device that draws power from bluespace and creates a permanent tracking beacon." - level = 1 // underfloor - layer = LOW_OBJ_LAYER - use_power = IDLE_POWER_USE - idle_power_usage = 0 - var/obj/item/beacon/Beacon - -/obj/machinery/bluespace_beacon/Initialize() - . = ..() - var/turf/T = loc - Beacon = new(T) - Beacon.invisibility = INVISIBILITY_MAXIMUM - - hide(T.intact) - -/obj/machinery/bluespace_beacon/Destroy() - QDEL_NULL(Beacon) - return ..() - -// update the invisibility and icon -/obj/machinery/bluespace_beacon/hide(intact) - invisibility = intact ? INVISIBILITY_MAXIMUM : 0 - update_icon() - -// update the icon_state -/obj/machinery/bluespace_beacon/update_icon() - var/state="floor_beacon" - - if(invisibility) - icon_state = "[state]f" - - else - icon_state = "[state]" - -/obj/machinery/bluespace_beacon/process() - if(!Beacon) - var/turf/T = loc - Beacon = new(T) - Beacon.invisibility = INVISIBILITY_MAXIMUM - else if (Beacon.loc != loc) - Beacon.forceMove(loc) - - update_icon() +/obj/machinery/bluespace_beacon + + icon = 'icons/obj/objects.dmi' + icon_state = "floor_beaconf" + name = "bluespace gigabeacon" + desc = "A device that draws power from bluespace and creates a permanent tracking beacon." + level = 1 // underfloor + layer = LOW_OBJ_LAYER + use_power = IDLE_POWER_USE + idle_power_usage = 0 + var/obj/item/beacon/Beacon + +/obj/machinery/bluespace_beacon/Initialize() + . = ..() + var/turf/T = loc + Beacon = new(T) + Beacon.invisibility = INVISIBILITY_MAXIMUM + + hide(T.intact) + +/obj/machinery/bluespace_beacon/Destroy() + QDEL_NULL(Beacon) + return ..() + +// update the invisibility and icon +/obj/machinery/bluespace_beacon/hide(intact) + invisibility = intact ? INVISIBILITY_MAXIMUM : 0 + update_icon() + +// update the icon_state +/obj/machinery/bluespace_beacon/update_icon() + var/state="floor_beacon" + + if(invisibility) + icon_state = "[state]f" + + else + icon_state = "[state]" + +/obj/machinery/bluespace_beacon/process() + if(!Beacon) + var/turf/T = loc + Beacon = new(T) + Beacon.invisibility = INVISIBILITY_MAXIMUM + else if (Beacon.loc != loc) + Beacon.forceMove(loc) + + update_icon() diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm index 45a3b59661..20efee9420 100644 --- a/code/game/machinery/PDApainter.dm +++ b/code/game/machinery/PDApainter.dm @@ -1,143 +1,143 @@ -/obj/machinery/pdapainter - name = "\improper PDA painter" - desc = "A PDA painting machine. To use, simply insert your PDA and choose the desired preset paint scheme." - icon = 'icons/obj/pda.dmi' - icon_state = "pdapainter" - density = TRUE - max_integrity = 200 - var/obj/item/pda/storedpda = null - var/list/colorlist = list() - - -/obj/machinery/pdapainter/update_icon() - cut_overlays() - - if(stat & BROKEN) - icon_state = "[initial(icon_state)]-broken" - return - - if(storedpda) - add_overlay("[initial(icon_state)]-closed") - - if(powered()) - icon_state = initial(icon_state) - else - icon_state = "[initial(icon_state)]-off" - - return - -/obj/machinery/pdapainter/Initialize() - . = ..() - var/list/blocked = list( - /obj/item/pda/ai/pai, - /obj/item/pda/ai, - /obj/item/pda/heads, - /obj/item/pda/clear, - /obj/item/pda/syndicate, - /obj/item/pda/chameleon, - /obj/item/pda/chameleon/broken, - /obj/item/pda/lieutenant) - - for(var/A in typesof(/obj/item/pda) - blocked) - var/obj/item/pda/P = A - var/PDA_name = initial(P.name) - colorlist += PDA_name - colorlist[PDA_name] = list(initial(P.icon_state), initial(P.desc), initial(P.overlays_offsets), initial(P.overlays_icons)) - -/obj/machinery/pdapainter/Destroy() - QDEL_NULL(storedpda) - return ..() - -/obj/machinery/pdapainter/on_deconstruction() - if(storedpda) - storedpda.forceMove(loc) - storedpda = null - -/obj/machinery/pdapainter/contents_explosion(severity, target) - if(storedpda) - storedpda.ex_act(severity, target) - -/obj/machinery/pdapainter/handle_atom_del(atom/A) - if(A == storedpda) - storedpda = null - update_icon() - -/obj/machinery/pdapainter/attackby(obj/item/O, mob/user, params) - if(default_unfasten_wrench(user, O)) - power_change() - return - - else if(istype(O, /obj/item/pda)) - if(storedpda) - to_chat(user, "There is already a PDA inside!") - return - else if(!user.transferItemToLoc(O, src)) - return - storedpda = O - O.add_fingerprint(user) - update_icon() - - else if(istype(O, /obj/item/weldingtool) && user.a_intent != INTENT_HARM) - if(stat & BROKEN) - if(!O.tool_start_check(user, amount=0)) - return - user.visible_message("[user] is repairing [src].", \ - "You begin repairing [src]...", \ - "You hear welding.") - if(O.use_tool(src, user, 40, volume=50)) - if(!(stat & BROKEN)) - return - to_chat(user, "You repair [src].") - stat &= ~BROKEN - obj_integrity = max_integrity - update_icon() - else - to_chat(user, "[src] does not need repairs.") - else - return ..() - -/obj/machinery/pdapainter/deconstruct(disassembled = TRUE) - if(!(flags_1 & NODECONSTRUCT_1)) - if(!(stat & BROKEN)) - stat |= BROKEN - update_icon() - -/obj/machinery/pdapainter/attack_hand(mob/user) - . = ..() - if(.) - return - - if(!storedpda) - to_chat(user, "[src] is empty.") - return - var/choice = input(user, "Select the new skin!", "PDA Painting") as null|anything in colorlist - if(!choice || !storedpda || !in_range(src, user)) - return - var/list/P = colorlist[choice] - storedpda.icon_state = P[1] - storedpda.desc = P[2] - storedpda.overlays_offsets = P[3] - storedpda.overlays_icons = P[4] - storedpda.set_new_overlays() - storedpda.update_icon() - ejectpda() - -/obj/machinery/pdapainter/verb/ejectpda() - set name = "Eject PDA" - set category = "Object" - set src in oview(1) - - if(usr.stat || usr.restrained()) - return - - if(storedpda) - storedpda.forceMove(drop_location()) - storedpda = null - update_icon() - else - to_chat(usr, "[src] is empty.") - - -/obj/machinery/pdapainter/power_change() - ..() - update_icon() +/obj/machinery/pdapainter + name = "\improper PDA painter" + desc = "A PDA painting machine. To use, simply insert your PDA and choose the desired preset paint scheme." + icon = 'icons/obj/pda.dmi' + icon_state = "pdapainter" + density = TRUE + max_integrity = 200 + var/obj/item/pda/storedpda = null + var/list/colorlist = list() + + +/obj/machinery/pdapainter/update_icon() + cut_overlays() + + if(stat & BROKEN) + icon_state = "[initial(icon_state)]-broken" + return + + if(storedpda) + add_overlay("[initial(icon_state)]-closed") + + if(powered()) + icon_state = initial(icon_state) + else + icon_state = "[initial(icon_state)]-off" + + return + +/obj/machinery/pdapainter/Initialize() + . = ..() + var/list/blocked = list( + /obj/item/pda/ai/pai, + /obj/item/pda/ai, + /obj/item/pda/heads, + /obj/item/pda/clear, + /obj/item/pda/syndicate, + /obj/item/pda/chameleon, + /obj/item/pda/chameleon/broken, + /obj/item/pda/lieutenant) + + for(var/A in typesof(/obj/item/pda) - blocked) + var/obj/item/pda/P = A + var/PDA_name = initial(P.name) + colorlist += PDA_name + colorlist[PDA_name] = list(initial(P.icon_state), initial(P.desc), initial(P.overlays_offsets), initial(P.overlays_icons)) + +/obj/machinery/pdapainter/Destroy() + QDEL_NULL(storedpda) + return ..() + +/obj/machinery/pdapainter/on_deconstruction() + if(storedpda) + storedpda.forceMove(loc) + storedpda = null + +/obj/machinery/pdapainter/contents_explosion(severity, target) + if(storedpda) + storedpda.ex_act(severity, target) + +/obj/machinery/pdapainter/handle_atom_del(atom/A) + if(A == storedpda) + storedpda = null + update_icon() + +/obj/machinery/pdapainter/attackby(obj/item/O, mob/user, params) + if(default_unfasten_wrench(user, O)) + power_change() + return + + else if(istype(O, /obj/item/pda)) + if(storedpda) + to_chat(user, "There is already a PDA inside!") + return + else if(!user.transferItemToLoc(O, src)) + return + storedpda = O + O.add_fingerprint(user) + update_icon() + + else if(istype(O, /obj/item/weldingtool) && user.a_intent != INTENT_HARM) + if(stat & BROKEN) + if(!O.tool_start_check(user, amount=0)) + return + user.visible_message("[user] is repairing [src].", \ + "You begin repairing [src]...", \ + "You hear welding.") + if(O.use_tool(src, user, 40, volume=50)) + if(!(stat & BROKEN)) + return + to_chat(user, "You repair [src].") + stat &= ~BROKEN + obj_integrity = max_integrity + update_icon() + else + to_chat(user, "[src] does not need repairs.") + else + return ..() + +/obj/machinery/pdapainter/deconstruct(disassembled = TRUE) + if(!(flags_1 & NODECONSTRUCT_1)) + if(!(stat & BROKEN)) + stat |= BROKEN + update_icon() + +/obj/machinery/pdapainter/attack_hand(mob/user) + . = ..() + if(.) + return + + if(!storedpda) + to_chat(user, "[src] is empty.") + return + var/choice = input(user, "Select the new skin!", "PDA Painting") as null|anything in colorlist + if(!choice || !storedpda || !in_range(src, user)) + return + var/list/P = colorlist[choice] + storedpda.icon_state = P[1] + storedpda.desc = P[2] + storedpda.overlays_offsets = P[3] + storedpda.overlays_icons = P[4] + storedpda.set_new_overlays() + storedpda.update_icon() + ejectpda() + +/obj/machinery/pdapainter/verb/ejectpda() + set name = "Eject PDA" + set category = "Object" + set src in oview(1) + + if(usr.stat || usr.restrained()) + return + + if(storedpda) + storedpda.forceMove(drop_location()) + storedpda = null + update_icon() + else + to_chat(usr, "[src] is empty.") + + +/obj/machinery/pdapainter/power_change() + ..() + update_icon() diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 88b0e804b7..b6dc09eb59 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -1,412 +1,412 @@ -/obj/machinery/sleep_console - name = "sleeper console" - icon = 'icons/obj/machines/sleeper.dmi' - icon_state = "console" - density = FALSE - -/obj/machinery/sleeper - name = "sleeper" - desc = "An enclosed machine used to stabilize and heal patients." - icon = 'icons/obj/machines/sleeper.dmi' - icon_state = "sleeper" - density = FALSE - state_open = TRUE - circuit = /obj/item/circuitboard/machine/sleeper - req_access = list(ACCESS_CMO) //Used for reagent deletion and addition of non medicines - var/efficiency = 1 - var/min_health = 30 - var/list/available_chems - var/controls_inside = FALSE - var/list/possible_chems = list( - list(/datum/reagent/medicine/epinephrine, /datum/reagent/medicine/morphine, /datum/reagent/medicine/salbutamol, /datum/reagent/medicine/bicaridine, /datum/reagent/medicine/kelotane), - list(/datum/reagent/medicine/oculine,/datum/reagent/medicine/inacusiate), - list(/datum/reagent/medicine/antitoxin, /datum/reagent/medicine/mutadone, /datum/reagent/medicine/mannitol, /datum/reagent/medicine/pen_acid), - list(/datum/reagent/medicine/omnizine) - ) - var/list/chem_buttons //Used when emagged to scramble which chem is used, eg: antitoxin -> morphine - var/scrambled_chems = FALSE //Are chem buttons scrambled? used as a warning - var/enter_message = "You feel cool air surround you. You go numb as your senses turn inward." - -/obj/machinery/sleeper/Initialize() - . = ..() - create_reagents(500, NO_REACT) - occupant_typecache = GLOB.typecache_living - update_icon() - reset_chem_buttons() - RefreshParts() - add_inital_chems() - -/obj/machinery/sleeper/on_deconstruction() - var/obj/item/reagent_containers/sleeper_buffer/buffer = new (loc) - buffer.volume = reagents.maximum_volume - buffer.reagents.maximum_volume = reagents.maximum_volume - reagents.trans_to(buffer.reagents, reagents.total_volume) - -/obj/machinery/sleeper/proc/add_inital_chems() - for(var/i in available_chems) - var/datum/reagent/R = reagents.has_reagent(i) - if(!R) - reagents.add_reagent(i, (20)) - continue - if(R.volume < 20) - reagents.add_reagent(i, (20 - R.volume)) - -/obj/machinery/sleeper/RefreshParts() - var/E - for(var/obj/item/stock_parts/matter_bin/B in component_parts) - E += B.rating - var/I - for(var/obj/item/stock_parts/manipulator/M in component_parts) - I += M.rating - - efficiency = initial(efficiency)* E - min_health = initial(min_health) - (10*(E-1)) // CIT CHANGE - changes min health equation to be min_health - (matterbin rating * 10) - available_chems = list() - for(var/i in 1 to I) - available_chems |= possible_chems[i] - reset_chem_buttons() - - //Total container size 500 - 2000u - if(reagents) - reagents.maximum_volume = (500*E) - - -/obj/machinery/sleeper/update_icon() - icon_state = initial(icon_state) - if(state_open) - icon_state += "-open" - -/obj/machinery/sleeper/container_resist(mob/living/user) - visible_message("[occupant] emerges from [src]!", - "You climb out of [src]!") - open_machine() - -/obj/machinery/sleeper/Exited(atom/movable/user) - if (!state_open && user == occupant) - container_resist(user) - -/obj/machinery/sleeper/relaymove(mob/user) - if (!state_open) - container_resist(user) - -/obj/machinery/sleeper/open_machine() - if(!state_open && !panel_open) - ..() - -/obj/machinery/sleeper/close_machine(mob/user) - if((isnull(user) || istype(user)) && state_open && !panel_open) - ..(user) - var/mob/living/mob_occupant = occupant - if(mob_occupant && mob_occupant.stat != DEAD) - to_chat(occupant, "[enter_message]") - -/obj/machinery/sleeper/emp_act(severity) - . = ..() - if (. & EMP_PROTECT_SELF) - return - if(is_operational() && occupant) - var/datum/reagent/R = pick(reagents.reagent_list) - inject_chem(R.type, occupant) - open_machine() - //Is this too much? - if(severity == EMP_HEAVY) - var/chem = pick(available_chems) - available_chems -= chem - available_chems += get_random_reagent_id() - reset_chem_buttons() - -/obj/machinery/sleeper/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/reagent_containers/sleeper_buffer)) - var/obj/item/reagent_containers/sleeper_buffer/SB = I - if((SB.reagents.total_volume + reagents.total_volume) < reagents.maximum_volume) - SB.reagents.trans_to(reagents, SB.reagents.total_volume) - visible_message("[user] places the [SB] into the [src].") - qdel(SB) - return - else - SB.reagents.trans_to(reagents, SB.reagents.total_volume) - visible_message("[user] adds as much as they can to the [src] from the [SB].") - return - if(istype(I, /obj/item/reagent_containers)) - var/obj/item/reagent_containers/RC = I - if(RC.reagents.total_volume == 0) - to_chat(user, "The [I] is empty!") - for(var/datum/reagent/R in RC.reagents.reagent_list) - if((obj_flags & EMAGGED) || (allowed(usr))) - break - if(!istype(R, /datum/reagent/medicine)) - visible_message("The [src] gives out a hearty boop and rejects the [I]. The Sleeper's screen flashes with a pompous \"Medicines only, please.\"") - return - RC.reagents.trans_to(reagents, 1000) - visible_message("[user] adds as much as they can to the [src] from the [I].") - return - - -/obj/machinery/sleeper/MouseDrop_T(mob/target, mob/user) - if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser()) - return - close_machine(target) - -/obj/machinery/sleeper/screwdriver_act(mob/living/user, obj/item/I) - . = TRUE - if(..()) - return - if(occupant) - to_chat(user, "[src] is currently occupied!") - return - if(state_open) - to_chat(user, "[src] must be closed to [panel_open ? "close" : "open"] its maintenance hatch!") - return - if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), I)) - return - return FALSE - -/obj/machinery/sleeper/wrench_act(mob/living/user, obj/item/I) - . = ..() - if(default_change_direction_wrench(user, I)) - return TRUE - -/obj/machinery/sleeper/crowbar_act(mob/living/user, obj/item/I) - . = ..() - if(default_pry_open(I)) - return TRUE - if(default_deconstruction_crowbar(I)) - return TRUE - -/obj/machinery/sleeper/default_pry_open(obj/item/I) //wew - . = !(state_open || panel_open || (flags_1 & NODECONSTRUCT_1)) && I.tool_behaviour == TOOL_CROWBAR - if(.) - I.play_tool_sound(src, 50) - visible_message("[usr] pries open [src].", "You pry open [src].") - open_machine() - -/obj/machinery/sleeper/AltClick(mob/user) - . = ..() - if(!user.canUseTopic(src, !issilicon(user))) - return - if(state_open) - close_machine() - else - open_machine() - return TRUE - -/obj/machinery/sleeper/examine(mob/user) - . = ..() - . += "Alt-click [src] to [state_open ? "close" : "open"] it." - -/obj/machinery/sleeper/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) - - if(controls_inside && state == GLOB.notcontained_state) - state = GLOB.default_state // If it has a set of controls on the inside, make it actually controllable by the mob in it. - - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "sleeper", name, 550, 700, master_ui, state) - ui.open() - -/obj/machinery/sleeper/ui_data() - var/list/data = list() - data["occupied"] = occupant ? 1 : 0 - data["open"] = state_open - data["efficiency"] = efficiency - data["current_vol"] = reagents.total_volume - data["tot_capacity"] = reagents.maximum_volume - - data["chems"] = list() - for(var/chem in available_chems) - var/datum/reagent/R = reagents.has_reagent(chem) - R = GLOB.chemical_reagents_list[chem] - data["synthchems"] += list(list("name" = R.name, "id" = R.type, "synth_allowed" = synth_allowed(chem))) - for(var/datum/reagent/R in reagents.reagent_list) - data["chems"] += list(list("name" = R.name, "id" = R.type, "vol" = R.volume, "purity" = R.purity, "allowed" = chem_allowed(R.type))) - - data["occupant"] = list() - var/mob/living/mob_occupant = occupant - if(mob_occupant) - data["occupant"]["name"] = mob_occupant.name - switch(mob_occupant.stat) - if(CONSCIOUS) - data["occupant"]["stat"] = "Conscious" - data["occupant"]["statstate"] = "good" - if(SOFT_CRIT) - data["occupant"]["stat"] = "Conscious" - data["occupant"]["statstate"] = "average" - if(UNCONSCIOUS) - data["occupant"]["stat"] = "Unconscious" - data["occupant"]["statstate"] = "average" - if(DEAD) - data["occupant"]["stat"] = "Dead" - data["occupant"]["statstate"] = "bad" - data["occupant"]["health"] = mob_occupant.health - data["occupant"]["maxHealth"] = mob_occupant.maxHealth - data["occupant"]["minHealth"] = HEALTH_THRESHOLD_DEAD - data["occupant"]["bruteLoss"] = mob_occupant.getBruteLoss() - data["occupant"]["oxyLoss"] = mob_occupant.getOxyLoss() - data["occupant"]["toxLoss"] = mob_occupant.getToxLoss() - data["occupant"]["fireLoss"] = mob_occupant.getFireLoss() - data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss() - data["occupant"]["brainLoss"] = mob_occupant.getOrganLoss(ORGAN_SLOT_BRAIN) - data["occupant"]["reagents"] = list() - if(mob_occupant.reagents && mob_occupant.reagents.reagent_list.len) - for(var/datum/reagent/R in mob_occupant.reagents.reagent_list) - data["occupant"]["reagents"] += list(list("name" = R.name, "volume" = R.volume)) - data["occupant"]["failing_organs"] = list() - var/mob/living/carbon/C = mob_occupant - if(C) - for(var/obj/item/organ/Or in C.getFailingOrgans()) - if(istype(Or, /obj/item/organ/brain)) - continue - data["occupant"]["failing_organs"] += list(list("name" = Or.name)) - - if(mob_occupant.has_dna()) // Blood-stuff is mostly a copy-paste from the healthscanner. - var/blood_id = C.get_blood_id() - if(blood_id) - data["occupant"]["blood"] = list() // We can start populating this list. - var/blood_type = C.dna.blood_type - if(blood_id != "blood") // special blood substance - var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id] - if(R) - blood_type = R.name - else - blood_type = blood_id - data["occupant"]["blood"]["maxBloodVolume"] = (BLOOD_VOLUME_NORMAL*C.blood_ratio) - data["occupant"]["blood"]["currentBloodVolume"] = C.blood_volume - data["occupant"]["blood"]["dangerBloodVolume"] = BLOOD_VOLUME_SAFE - data["occupant"]["blood"]["bloodType"] = blood_type - return data - -/obj/machinery/sleeper/ui_act(action, params) - if(..()) - return - var/mob/living/mob_occupant = occupant - - switch(action) - if("door") - if(state_open) - close_machine() - else - open_machine() - . = TRUE - if("inject") - var/chem = text2path(params["chem"]) - var/amount = text2num(params["volume"]) - if(!is_operational() || !mob_occupant || isnull(chem)) - return - if(mob_occupant.health < min_health && chem != /datum/reagent/medicine/epinephrine) - return - if(inject_chem(chem, usr, amount)) - . = TRUE - if(scrambled_chems && prob(5)) - to_chat(usr, "Chemical system re-route detected, results may not be as expected!") - if("synth") - var/chem = text2path(params["chem"]) - if(!is_operational()) - return - reagents.add_reagent(chem_buttons[chem], 10) //other_purity = 0.75 for when the mechanics are in - if("purge") - var/chem = text2path(params["chem"]) - if(allowed(usr)) - if(!is_operational()) - return - reagents.remove_reagent(chem, 10) - return - if(chem in available_chems) - if(!is_operational()) - return - /*var/datum/reagent/R = reagents.has_reagent(chem) //For when purity effects are in - if(R.purity < 0.8)*/ - reagents.remove_reagent(chem, 10) - else - visible_message("Access Denied.") - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - - -/obj/machinery/sleeper/emag_act(mob/user) - . = ..() - obj_flags |= EMAGGED - scramble_chem_buttons() - to_chat(user, "You scramble the sleeper's user interface!") - return TRUE - -//trans to -/obj/machinery/sleeper/proc/inject_chem(chem, mob/user, volume = 10) - if(chem_allowed(chem)) - reagents.trans_id_to(occupant, chem, volume)//emag effect kicks in here so that the "intended" chem is used for all checks, for extra FUUU - if(user) - log_combat(user, occupant, "injected [chem] into", addition = "via [src]") - return TRUE - -/obj/machinery/sleeper/proc/chem_allowed(chem) - var/mob/living/mob_occupant = occupant - if(!mob_occupant || !mob_occupant.reagents) - return - var/amount = mob_occupant.reagents.get_reagent_amount(chem) + 10 <= 20 * efficiency - var/occ_health = mob_occupant.health > min_health || chem == /datum/reagent/medicine/epinephrine - return amount && occ_health - -/obj/machinery/sleeper/proc/synth_allowed(chem) - var/datum/reagent/R = reagents.has_reagent(chem) - if(!R) - return TRUE - if(R.volume < 50) - return TRUE - return FALSE - -/obj/machinery/sleeper/proc/reset_chem_buttons() - scrambled_chems = FALSE - LAZYINITLIST(chem_buttons) - for(var/chem in available_chems) - chem_buttons[chem] = chem - -/obj/machinery/sleeper/proc/scramble_chem_buttons() - scrambled_chems = TRUE - var/list/av_chem = available_chems.Copy() - for(var/chem in av_chem) - chem_buttons[chem] = pick_n_take(av_chem) //no dupes, allow for random buttons to still be correct - - -/obj/machinery/sleeper/syndie - icon_state = "sleeper_s" - controls_inside = TRUE - -/obj/machinery/sleeper/syndie/Initialize() - . = ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/sleeper/syndie(null) - component_parts += new /obj/item/stock_parts/matter_bin/super(null) - component_parts += new /obj/item/stock_parts/manipulator/pico(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stack/cable_coil(null) - RefreshParts() - -/obj/machinery/sleeper/syndie/fullupgrade/Initialize() - . = ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/sleeper/syndie(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/manipulator/femto(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stack/cable_coil(null) - RefreshParts() - -/obj/machinery/sleeper/clockwork - name = "soothing sleeper" - desc = "A large cryogenics unit built from brass. Its surface is pleasantly cool the touch." - icon_state = "sleeper_clockwork" - enter_message = "You hear the gentle hum and click of machinery, and are lulled into a sense of peace." - possible_chems = list(list("epinephrine", "salbutamol", "bicaridine", "kelotane", "oculine", "inacusiate", "mannitol")) - -/obj/machinery/sleeper/clockwork/process() - if(occupant && isliving(occupant)) - var/mob/living/L = occupant - if(GLOB.clockwork_vitality) //If there's Vitality, the sleeper has passive healing - GLOB.clockwork_vitality = max(0, GLOB.clockwork_vitality - 1) - L.adjustBruteLoss(-1) - L.adjustFireLoss(-1) - L.adjustOxyLoss(-5) - -/obj/machinery/sleeper/old - icon_state = "oldpod" +/obj/machinery/sleep_console + name = "sleeper console" + icon = 'icons/obj/machines/sleeper.dmi' + icon_state = "console" + density = FALSE + +/obj/machinery/sleeper + name = "sleeper" + desc = "An enclosed machine used to stabilize and heal patients." + icon = 'icons/obj/machines/sleeper.dmi' + icon_state = "sleeper" + density = FALSE + state_open = TRUE + circuit = /obj/item/circuitboard/machine/sleeper + req_access = list(ACCESS_CMO) //Used for reagent deletion and addition of non medicines + var/efficiency = 1 + var/min_health = 30 + var/list/available_chems + var/controls_inside = FALSE + var/list/possible_chems = list( + list(/datum/reagent/medicine/epinephrine, /datum/reagent/medicine/morphine, /datum/reagent/medicine/salbutamol, /datum/reagent/medicine/bicaridine, /datum/reagent/medicine/kelotane), + list(/datum/reagent/medicine/oculine,/datum/reagent/medicine/inacusiate), + list(/datum/reagent/medicine/antitoxin, /datum/reagent/medicine/mutadone, /datum/reagent/medicine/mannitol, /datum/reagent/medicine/pen_acid), + list(/datum/reagent/medicine/omnizine) + ) + var/list/chem_buttons //Used when emagged to scramble which chem is used, eg: antitoxin -> morphine + var/scrambled_chems = FALSE //Are chem buttons scrambled? used as a warning + var/enter_message = "You feel cool air surround you. You go numb as your senses turn inward." + +/obj/machinery/sleeper/Initialize() + . = ..() + create_reagents(500, NO_REACT) + occupant_typecache = GLOB.typecache_living + update_icon() + reset_chem_buttons() + RefreshParts() + add_inital_chems() + +/obj/machinery/sleeper/on_deconstruction() + var/obj/item/reagent_containers/sleeper_buffer/buffer = new (loc) + buffer.volume = reagents.maximum_volume + buffer.reagents.maximum_volume = reagents.maximum_volume + reagents.trans_to(buffer.reagents, reagents.total_volume) + +/obj/machinery/sleeper/proc/add_inital_chems() + for(var/i in available_chems) + var/datum/reagent/R = reagents.has_reagent(i) + if(!R) + reagents.add_reagent(i, (20)) + continue + if(R.volume < 20) + reagents.add_reagent(i, (20 - R.volume)) + +/obj/machinery/sleeper/RefreshParts() + var/E + for(var/obj/item/stock_parts/matter_bin/B in component_parts) + E += B.rating + var/I + for(var/obj/item/stock_parts/manipulator/M in component_parts) + I += M.rating + + efficiency = initial(efficiency)* E + min_health = initial(min_health) - (10*(E-1)) // CIT CHANGE - changes min health equation to be min_health - (matterbin rating * 10) + available_chems = list() + for(var/i in 1 to I) + available_chems |= possible_chems[i] + reset_chem_buttons() + + //Total container size 500 - 2000u + if(reagents) + reagents.maximum_volume = (500*E) + + +/obj/machinery/sleeper/update_icon() + icon_state = initial(icon_state) + if(state_open) + icon_state += "-open" + +/obj/machinery/sleeper/container_resist(mob/living/user) + visible_message("[occupant] emerges from [src]!", + "You climb out of [src]!") + open_machine() + +/obj/machinery/sleeper/Exited(atom/movable/user) + if (!state_open && user == occupant) + container_resist(user) + +/obj/machinery/sleeper/relaymove(mob/user) + if (!state_open) + container_resist(user) + +/obj/machinery/sleeper/open_machine() + if(!state_open && !panel_open) + ..() + +/obj/machinery/sleeper/close_machine(mob/user) + if((isnull(user) || istype(user)) && state_open && !panel_open) + ..(user) + var/mob/living/mob_occupant = occupant + if(mob_occupant && mob_occupant.stat != DEAD) + to_chat(occupant, "[enter_message]") + +/obj/machinery/sleeper/emp_act(severity) + . = ..() + if (. & EMP_PROTECT_SELF) + return + if(is_operational() && occupant) + var/datum/reagent/R = pick(reagents.reagent_list) + inject_chem(R.type, occupant) + open_machine() + //Is this too much? + if(severity == EMP_HEAVY) + var/chem = pick(available_chems) + available_chems -= chem + available_chems += get_random_reagent_id() + reset_chem_buttons() + +/obj/machinery/sleeper/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/reagent_containers/sleeper_buffer)) + var/obj/item/reagent_containers/sleeper_buffer/SB = I + if((SB.reagents.total_volume + reagents.total_volume) < reagents.maximum_volume) + SB.reagents.trans_to(reagents, SB.reagents.total_volume) + visible_message("[user] places the [SB] into the [src].") + qdel(SB) + return + else + SB.reagents.trans_to(reagents, SB.reagents.total_volume) + visible_message("[user] adds as much as they can to the [src] from the [SB].") + return + if(istype(I, /obj/item/reagent_containers)) + var/obj/item/reagent_containers/RC = I + if(RC.reagents.total_volume == 0) + to_chat(user, "The [I] is empty!") + for(var/datum/reagent/R in RC.reagents.reagent_list) + if((obj_flags & EMAGGED) || (allowed(usr))) + break + if(!istype(R, /datum/reagent/medicine)) + visible_message("The [src] gives out a hearty boop and rejects the [I]. The Sleeper's screen flashes with a pompous \"Medicines only, please.\"") + return + RC.reagents.trans_to(reagents, 1000) + visible_message("[user] adds as much as they can to the [src] from the [I].") + return + + +/obj/machinery/sleeper/MouseDrop_T(mob/target, mob/user) + if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser()) + return + close_machine(target) + +/obj/machinery/sleeper/screwdriver_act(mob/living/user, obj/item/I) + . = TRUE + if(..()) + return + if(occupant) + to_chat(user, "[src] is currently occupied!") + return + if(state_open) + to_chat(user, "[src] must be closed to [panel_open ? "close" : "open"] its maintenance hatch!") + return + if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), I)) + return + return FALSE + +/obj/machinery/sleeper/wrench_act(mob/living/user, obj/item/I) + . = ..() + if(default_change_direction_wrench(user, I)) + return TRUE + +/obj/machinery/sleeper/crowbar_act(mob/living/user, obj/item/I) + . = ..() + if(default_pry_open(I)) + return TRUE + if(default_deconstruction_crowbar(I)) + return TRUE + +/obj/machinery/sleeper/default_pry_open(obj/item/I) //wew + . = !(state_open || panel_open || (flags_1 & NODECONSTRUCT_1)) && I.tool_behaviour == TOOL_CROWBAR + if(.) + I.play_tool_sound(src, 50) + visible_message("[usr] pries open [src].", "You pry open [src].") + open_machine() + +/obj/machinery/sleeper/AltClick(mob/user) + . = ..() + if(!user.canUseTopic(src, !issilicon(user))) + return + if(state_open) + close_machine() + else + open_machine() + return TRUE + +/obj/machinery/sleeper/examine(mob/user) + . = ..() + . += "Alt-click [src] to [state_open ? "close" : "open"] it." + +/obj/machinery/sleeper/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) + + if(controls_inside && state == GLOB.notcontained_state) + state = GLOB.default_state // If it has a set of controls on the inside, make it actually controllable by the mob in it. + + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "sleeper", name, 550, 700, master_ui, state) + ui.open() + +/obj/machinery/sleeper/ui_data() + var/list/data = list() + data["occupied"] = occupant ? 1 : 0 + data["open"] = state_open + data["efficiency"] = efficiency + data["current_vol"] = reagents.total_volume + data["tot_capacity"] = reagents.maximum_volume + + data["chems"] = list() + for(var/chem in available_chems) + var/datum/reagent/R = reagents.has_reagent(chem) + R = GLOB.chemical_reagents_list[chem] + data["synthchems"] += list(list("name" = R.name, "id" = R.type, "synth_allowed" = synth_allowed(chem))) + for(var/datum/reagent/R in reagents.reagent_list) + data["chems"] += list(list("name" = R.name, "id" = R.type, "vol" = R.volume, "purity" = R.purity, "allowed" = chem_allowed(R.type))) + + data["occupant"] = list() + var/mob/living/mob_occupant = occupant + if(mob_occupant) + data["occupant"]["name"] = mob_occupant.name + switch(mob_occupant.stat) + if(CONSCIOUS) + data["occupant"]["stat"] = "Conscious" + data["occupant"]["statstate"] = "good" + if(SOFT_CRIT) + data["occupant"]["stat"] = "Conscious" + data["occupant"]["statstate"] = "average" + if(UNCONSCIOUS) + data["occupant"]["stat"] = "Unconscious" + data["occupant"]["statstate"] = "average" + if(DEAD) + data["occupant"]["stat"] = "Dead" + data["occupant"]["statstate"] = "bad" + data["occupant"]["health"] = mob_occupant.health + data["occupant"]["maxHealth"] = mob_occupant.maxHealth + data["occupant"]["minHealth"] = HEALTH_THRESHOLD_DEAD + data["occupant"]["bruteLoss"] = mob_occupant.getBruteLoss() + data["occupant"]["oxyLoss"] = mob_occupant.getOxyLoss() + data["occupant"]["toxLoss"] = mob_occupant.getToxLoss() + data["occupant"]["fireLoss"] = mob_occupant.getFireLoss() + data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss() + data["occupant"]["brainLoss"] = mob_occupant.getOrganLoss(ORGAN_SLOT_BRAIN) + data["occupant"]["reagents"] = list() + if(mob_occupant.reagents && mob_occupant.reagents.reagent_list.len) + for(var/datum/reagent/R in mob_occupant.reagents.reagent_list) + data["occupant"]["reagents"] += list(list("name" = R.name, "volume" = R.volume)) + data["occupant"]["failing_organs"] = list() + var/mob/living/carbon/C = mob_occupant + if(C) + for(var/obj/item/organ/Or in C.getFailingOrgans()) + if(istype(Or, /obj/item/organ/brain)) + continue + data["occupant"]["failing_organs"] += list(list("name" = Or.name)) + + if(mob_occupant.has_dna()) // Blood-stuff is mostly a copy-paste from the healthscanner. + var/blood_id = C.get_blood_id() + if(blood_id) + data["occupant"]["blood"] = list() // We can start populating this list. + var/blood_type = C.dna.blood_type + if(blood_id != "blood") // special blood substance + var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id] + if(R) + blood_type = R.name + else + blood_type = blood_id + data["occupant"]["blood"]["maxBloodVolume"] = (BLOOD_VOLUME_NORMAL*C.blood_ratio) + data["occupant"]["blood"]["currentBloodVolume"] = C.blood_volume + data["occupant"]["blood"]["dangerBloodVolume"] = BLOOD_VOLUME_SAFE + data["occupant"]["blood"]["bloodType"] = blood_type + return data + +/obj/machinery/sleeper/ui_act(action, params) + if(..()) + return + var/mob/living/mob_occupant = occupant + + switch(action) + if("door") + if(state_open) + close_machine() + else + open_machine() + . = TRUE + if("inject") + var/chem = text2path(params["chem"]) + var/amount = text2num(params["volume"]) + if(!is_operational() || !mob_occupant || isnull(chem)) + return + if(mob_occupant.health < min_health && chem != /datum/reagent/medicine/epinephrine) + return + if(inject_chem(chem, usr, amount)) + . = TRUE + if(scrambled_chems && prob(5)) + to_chat(usr, "Chemical system re-route detected, results may not be as expected!") + if("synth") + var/chem = text2path(params["chem"]) + if(!is_operational()) + return + reagents.add_reagent(chem_buttons[chem], 10) //other_purity = 0.75 for when the mechanics are in + if("purge") + var/chem = text2path(params["chem"]) + if(allowed(usr)) + if(!is_operational()) + return + reagents.remove_reagent(chem, 10) + return + if(chem in available_chems) + if(!is_operational()) + return + /*var/datum/reagent/R = reagents.has_reagent(chem) //For when purity effects are in + if(R.purity < 0.8)*/ + reagents.remove_reagent(chem, 10) + else + visible_message("Access Denied.") + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + + +/obj/machinery/sleeper/emag_act(mob/user) + . = ..() + obj_flags |= EMAGGED + scramble_chem_buttons() + to_chat(user, "You scramble the sleeper's user interface!") + return TRUE + +//trans to +/obj/machinery/sleeper/proc/inject_chem(chem, mob/user, volume = 10) + if(chem_allowed(chem)) + reagents.trans_id_to(occupant, chem, volume)//emag effect kicks in here so that the "intended" chem is used for all checks, for extra FUUU + if(user) + log_combat(user, occupant, "injected [chem] into", addition = "via [src]") + return TRUE + +/obj/machinery/sleeper/proc/chem_allowed(chem) + var/mob/living/mob_occupant = occupant + if(!mob_occupant || !mob_occupant.reagents) + return + var/amount = mob_occupant.reagents.get_reagent_amount(chem) + 10 <= 20 * efficiency + var/occ_health = mob_occupant.health > min_health || chem == /datum/reagent/medicine/epinephrine + return amount && occ_health + +/obj/machinery/sleeper/proc/synth_allowed(chem) + var/datum/reagent/R = reagents.has_reagent(chem) + if(!R) + return TRUE + if(R.volume < 50) + return TRUE + return FALSE + +/obj/machinery/sleeper/proc/reset_chem_buttons() + scrambled_chems = FALSE + LAZYINITLIST(chem_buttons) + for(var/chem in available_chems) + chem_buttons[chem] = chem + +/obj/machinery/sleeper/proc/scramble_chem_buttons() + scrambled_chems = TRUE + var/list/av_chem = available_chems.Copy() + for(var/chem in av_chem) + chem_buttons[chem] = pick_n_take(av_chem) //no dupes, allow for random buttons to still be correct + + +/obj/machinery/sleeper/syndie + icon_state = "sleeper_s" + controls_inside = TRUE + +/obj/machinery/sleeper/syndie/Initialize() + . = ..() + component_parts = list() + component_parts += new /obj/item/circuitboard/machine/sleeper/syndie(null) + component_parts += new /obj/item/stock_parts/matter_bin/super(null) + component_parts += new /obj/item/stock_parts/manipulator/pico(null) + component_parts += new /obj/item/stack/sheet/glass(null) + component_parts += new /obj/item/stack/sheet/glass(null) + component_parts += new /obj/item/stack/cable_coil(null) + RefreshParts() + +/obj/machinery/sleeper/syndie/fullupgrade/Initialize() + . = ..() + component_parts = list() + component_parts += new /obj/item/circuitboard/machine/sleeper/syndie(null) + component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) + component_parts += new /obj/item/stock_parts/manipulator/femto(null) + component_parts += new /obj/item/stack/sheet/glass(null) + component_parts += new /obj/item/stack/sheet/glass(null) + component_parts += new /obj/item/stack/cable_coil(null) + RefreshParts() + +/obj/machinery/sleeper/clockwork + name = "soothing sleeper" + desc = "A large cryogenics unit built from brass. Its surface is pleasantly cool the touch." + icon_state = "sleeper_clockwork" + enter_message = "You hear the gentle hum and click of machinery, and are lulled into a sense of peace." + possible_chems = list(list("epinephrine", "salbutamol", "bicaridine", "kelotane", "oculine", "inacusiate", "mannitol")) + +/obj/machinery/sleeper/clockwork/process() + if(occupant && isliving(occupant)) + var/mob/living/L = occupant + if(GLOB.clockwork_vitality) //If there's Vitality, the sleeper has passive healing + GLOB.clockwork_vitality = max(0, GLOB.clockwork_vitality - 1) + L.adjustBruteLoss(-1) + L.adjustFireLoss(-1) + L.adjustOxyLoss(-5) + +/obj/machinery/sleeper/old + icon_state = "oldpod" diff --git a/code/game/machinery/ai_slipper.dm b/code/game/machinery/ai_slipper.dm index 1703ce57d1..4935c9d4d3 100644 --- a/code/game/machinery/ai_slipper.dm +++ b/code/game/machinery/ai_slipper.dm @@ -1,48 +1,48 @@ -/obj/machinery/ai_slipper - name = "foam dispenser" - desc = "A remotely-activatable dispenser for crowd-controlling foam." - icon = 'icons/obj/device.dmi' - icon_state = "ai-slipper0" - layer = PROJECTILE_HIT_THRESHHOLD_LAYER - plane = FLOOR_PLANE - max_integrity = 200 - armor = list("melee" = 50, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) - - var/uses = 20 - var/cooldown = 0 - var/cooldown_time = 100 - req_access = list(ACCESS_AI_UPLOAD) - -/obj/machinery/ai_slipper/examine(mob/user) - . = ..() - . += "It has [uses] uses of foam remaining." - -/obj/machinery/ai_slipper/power_change() - if(stat & BROKEN) - return - else - if(powered()) - stat &= ~NOPOWER - else - stat |= NOPOWER - if((stat & (NOPOWER|BROKEN)) || cooldown_time > world.time || !uses) - icon_state = "ai-slipper0" - else - icon_state = "ai-slipper1" - -/obj/machinery/ai_slipper/interact(mob/user) - if(!allowed(user)) - to_chat(user, "Access denied.") - return - if(!uses) - to_chat(user, "[src] is out of foam and cannot be activated.") - return - if(cooldown_time > world.time) - to_chat(user, "[src] cannot be activated for [DisplayTimeText(world.time - cooldown_time)].") - return - new /obj/effect/particle_effect/foam(loc) - uses-- - to_chat(user, "You activate [src]. It now has [uses] uses of foam remaining.") - cooldown = world.time + cooldown_time - power_change() - addtimer(CALLBACK(src, .proc/power_change), cooldown_time) +/obj/machinery/ai_slipper + name = "foam dispenser" + desc = "A remotely-activatable dispenser for crowd-controlling foam." + icon = 'icons/obj/device.dmi' + icon_state = "ai-slipper0" + layer = PROJECTILE_HIT_THRESHHOLD_LAYER + plane = FLOOR_PLANE + max_integrity = 200 + armor = list("melee" = 50, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 30) + + var/uses = 20 + var/cooldown = 0 + var/cooldown_time = 100 + req_access = list(ACCESS_AI_UPLOAD) + +/obj/machinery/ai_slipper/examine(mob/user) + . = ..() + . += "It has [uses] uses of foam remaining." + +/obj/machinery/ai_slipper/power_change() + if(stat & BROKEN) + return + else + if(powered()) + stat &= ~NOPOWER + else + stat |= NOPOWER + if((stat & (NOPOWER|BROKEN)) || cooldown_time > world.time || !uses) + icon_state = "ai-slipper0" + else + icon_state = "ai-slipper1" + +/obj/machinery/ai_slipper/interact(mob/user) + if(!allowed(user)) + to_chat(user, "Access denied.") + return + if(!uses) + to_chat(user, "[src] is out of foam and cannot be activated.") + return + if(cooldown_time > world.time) + to_chat(user, "[src] cannot be activated for [DisplayTimeText(world.time - cooldown_time)].") + return + new /obj/effect/particle_effect/foam(loc) + uses-- + to_chat(user, "You activate [src]. It now has [uses] uses of foam remaining.") + cooldown = world.time + cooldown_time + power_change() + addtimer(CALLBACK(src, .proc/power_change), cooldown_time) diff --git a/code/game/machinery/airlock_control.dm b/code/game/machinery/airlock_control.dm index 14dc7d05c2..69dbdcd50c 100644 --- a/code/game/machinery/airlock_control.dm +++ b/code/game/machinery/airlock_control.dm @@ -1,164 +1,164 @@ -#define AIRLOCK_CONTROL_RANGE 5 - -// This code allows for airlocks to be controlled externally by setting an id_tag and comm frequency (disables ID access) -/obj/machinery/door/airlock - var/id_tag - var/frequency - var/datum/radio_frequency/radio_connection - - -/obj/machinery/door/airlock/receive_signal(datum/signal/signal) - if(!signal) - return - - if(id_tag != signal.data["tag"] || !signal.data["command"]) - return - - switch(signal.data["command"]) - if("open") - open(1) - - if("close") - close(1) - - if("unlock") - locked = FALSE - update_icon() - - if("lock") - locked = TRUE - update_icon() - - if("secure_open") - locked = FALSE - update_icon() - - sleep(2) - open(1) - - locked = TRUE - update_icon() - - if("secure_close") - locked = FALSE - close(1) - - locked = TRUE - sleep(2) - update_icon() - - send_status() - - -/obj/machinery/door/airlock/proc/send_status() - if(radio_connection) - var/datum/signal/signal = new(list( - "tag" = id_tag, - "timestamp" = world.time, - "door_status" = density ? "closed" : "open", - "lock_status" = locked ? "locked" : "unlocked" - )) - radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK) - - -/obj/machinery/door/airlock/open(surpress_send) - . = ..() - if(!surpress_send) - send_status() - - -/obj/machinery/door/airlock/close(surpress_send) - . = ..() - if(!surpress_send) - send_status() - - -/obj/machinery/door/airlock/proc/set_frequency(new_frequency) - SSradio.remove_object(src, frequency) - if(new_frequency) - frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency, RADIO_AIRLOCK) - -/obj/machinery/door/airlock/Destroy() - if(frequency) - SSradio.remove_object(src,frequency) - return ..() - -/obj/machinery/airlock_sensor - icon = 'icons/obj/airlock_machines.dmi' - icon_state = "airlock_sensor_off" - name = "airlock sensor" - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - - power_channel = ENVIRON - - var/id_tag - var/master_tag - var/frequency = FREQ_AIRLOCK_CONTROL - - var/datum/radio_frequency/radio_connection - - var/on = TRUE - var/alert = FALSE - -/obj/machinery/airlock_sensor/incinerator_toxmix - id_tag = INCINERATOR_TOXMIX_AIRLOCK_SENSOR - master_tag = INCINERATOR_TOXMIX_AIRLOCK_CONTROLLER - -/obj/machinery/airlock_sensor/incinerator_atmos - id_tag = INCINERATOR_ATMOS_AIRLOCK_SENSOR - master_tag = INCINERATOR_ATMOS_AIRLOCK_CONTROLLER - -/obj/machinery/airlock_sensor/incinerator_syndicatelava - id_tag = INCINERATOR_SYNDICATELAVA_AIRLOCK_SENSOR - master_tag = INCINERATOR_SYNDICATELAVA_AIRLOCK_CONTROLLER - -/obj/machinery/airlock_sensor/update_icon() - if(on) - if(alert) - icon_state = "airlock_sensor_alert" - else - icon_state = "airlock_sensor_standby" - else - icon_state = "airlock_sensor_off" - -/obj/machinery/airlock_sensor/attack_hand(mob/user) - . = ..() - if(.) - return - var/datum/signal/signal = new(list( - "tag" = master_tag, - "command" = "cycle" - )) - - radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK) - flick("airlock_sensor_cycle", src) - -/obj/machinery/airlock_sensor/process() - if(on) - var/datum/gas_mixture/air_sample = return_air() - var/pressure = round(air_sample.return_pressure(),0.1) - alert = (pressure < ONE_ATMOSPHERE*0.8) - - var/datum/signal/signal = new(list( - "tag" = id_tag, - "timestamp" = world.time, - "pressure" = num2text(pressure) - )) - - radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK) - - update_icon() - -/obj/machinery/airlock_sensor/proc/set_frequency(new_frequency) - SSradio.remove_object(src, frequency) - frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency, RADIO_AIRLOCK) - -/obj/machinery/airlock_sensor/Initialize() - . = ..() - set_frequency(frequency) - -/obj/machinery/airlock_sensor/Destroy() - SSradio.remove_object(src,frequency) +#define AIRLOCK_CONTROL_RANGE 5 + +// This code allows for airlocks to be controlled externally by setting an id_tag and comm frequency (disables ID access) +/obj/machinery/door/airlock + var/id_tag + var/frequency + var/datum/radio_frequency/radio_connection + + +/obj/machinery/door/airlock/receive_signal(datum/signal/signal) + if(!signal) + return + + if(id_tag != signal.data["tag"] || !signal.data["command"]) + return + + switch(signal.data["command"]) + if("open") + open(1) + + if("close") + close(1) + + if("unlock") + locked = FALSE + update_icon() + + if("lock") + locked = TRUE + update_icon() + + if("secure_open") + locked = FALSE + update_icon() + + sleep(2) + open(1) + + locked = TRUE + update_icon() + + if("secure_close") + locked = FALSE + close(1) + + locked = TRUE + sleep(2) + update_icon() + + send_status() + + +/obj/machinery/door/airlock/proc/send_status() + if(radio_connection) + var/datum/signal/signal = new(list( + "tag" = id_tag, + "timestamp" = world.time, + "door_status" = density ? "closed" : "open", + "lock_status" = locked ? "locked" : "unlocked" + )) + radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK) + + +/obj/machinery/door/airlock/open(surpress_send) + . = ..() + if(!surpress_send) + send_status() + + +/obj/machinery/door/airlock/close(surpress_send) + . = ..() + if(!surpress_send) + send_status() + + +/obj/machinery/door/airlock/proc/set_frequency(new_frequency) + SSradio.remove_object(src, frequency) + if(new_frequency) + frequency = new_frequency + radio_connection = SSradio.add_object(src, frequency, RADIO_AIRLOCK) + +/obj/machinery/door/airlock/Destroy() + if(frequency) + SSradio.remove_object(src,frequency) + return ..() + +/obj/machinery/airlock_sensor + icon = 'icons/obj/airlock_machines.dmi' + icon_state = "airlock_sensor_off" + name = "airlock sensor" + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + + power_channel = ENVIRON + + var/id_tag + var/master_tag + var/frequency = FREQ_AIRLOCK_CONTROL + + var/datum/radio_frequency/radio_connection + + var/on = TRUE + var/alert = FALSE + +/obj/machinery/airlock_sensor/incinerator_toxmix + id_tag = INCINERATOR_TOXMIX_AIRLOCK_SENSOR + master_tag = INCINERATOR_TOXMIX_AIRLOCK_CONTROLLER + +/obj/machinery/airlock_sensor/incinerator_atmos + id_tag = INCINERATOR_ATMOS_AIRLOCK_SENSOR + master_tag = INCINERATOR_ATMOS_AIRLOCK_CONTROLLER + +/obj/machinery/airlock_sensor/incinerator_syndicatelava + id_tag = INCINERATOR_SYNDICATELAVA_AIRLOCK_SENSOR + master_tag = INCINERATOR_SYNDICATELAVA_AIRLOCK_CONTROLLER + +/obj/machinery/airlock_sensor/update_icon() + if(on) + if(alert) + icon_state = "airlock_sensor_alert" + else + icon_state = "airlock_sensor_standby" + else + icon_state = "airlock_sensor_off" + +/obj/machinery/airlock_sensor/attack_hand(mob/user) + . = ..() + if(.) + return + var/datum/signal/signal = new(list( + "tag" = master_tag, + "command" = "cycle" + )) + + radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK) + flick("airlock_sensor_cycle", src) + +/obj/machinery/airlock_sensor/process() + if(on) + var/datum/gas_mixture/air_sample = return_air() + var/pressure = round(air_sample.return_pressure(),0.1) + alert = (pressure < ONE_ATMOSPHERE*0.8) + + var/datum/signal/signal = new(list( + "tag" = id_tag, + "timestamp" = world.time, + "pressure" = num2text(pressure) + )) + + radio_connection.post_signal(src, signal, range = AIRLOCK_CONTROL_RANGE, filter = RADIO_AIRLOCK) + + update_icon() + +/obj/machinery/airlock_sensor/proc/set_frequency(new_frequency) + SSradio.remove_object(src, frequency) + frequency = new_frequency + radio_connection = SSradio.add_object(src, frequency, RADIO_AIRLOCK) + +/obj/machinery/airlock_sensor/Initialize() + . = ..() + set_frequency(frequency) + +/obj/machinery/airlock_sensor/Destroy() + SSradio.remove_object(src,frequency) return ..() \ No newline at end of file diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index bdb90c4c97..016f226399 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -1,383 +1,383 @@ -#define AUTOLATHE_MAIN_MENU 1 -#define AUTOLATHE_CATEGORY_MENU 2 -#define AUTOLATHE_SEARCH_MENU 3 - -/obj/machinery/autolathe - name = "autolathe" - desc = "It produces items using metal and glass." - icon_state = "autolathe" - density = TRUE - use_power = IDLE_POWER_USE - idle_power_usage = 10 - active_power_usage = 100 - circuit = /obj/item/circuitboard/machine/autolathe - layer = BELOW_OBJ_LAYER - - var/operating = FALSE - var/list/L = list() - var/list/LL = list() - var/hacked = FALSE - var/disabled = 0 - var/shocked = FALSE - var/hack_wire - var/disable_wire - var/shock_wire - - var/busy = FALSE - var/prod_coeff = 1 - - var/datum/design/being_built - var/datum/techweb/stored_research - var/list/datum/design/matching_designs - var/selected_category - var/screen = 1 - - var/list/categories = list( - "Tools", - "Electronics", - "Construction", - "T-Comm", - "Security", - "Machinery", - "Medical", - "Misc", - "Dinnerware", - "Imported" - ) - -/obj/machinery/autolathe/Initialize() - AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS), 0, TRUE, null, null, CALLBACK(src, .proc/AfterMaterialInsert)) - . = ..() - - wires = new /datum/wires/autolathe(src) - stored_research = new /datum/techweb/specialized/autounlocking/autolathe - matching_designs = list() - -/obj/machinery/autolathe/Destroy() - QDEL_NULL(wires) - return ..() - -/obj/machinery/autolathe/ui_interact(mob/user) - . = ..() - if(!is_operational()) - return - - if(shocked && !(stat & NOPOWER)) - shock(user,50) - - var/dat - - switch(screen) - if(AUTOLATHE_MAIN_MENU) - dat = main_win(user) - if(AUTOLATHE_CATEGORY_MENU) - dat = category_win(user,selected_category) - if(AUTOLATHE_SEARCH_MENU) - dat = search_win(user) - - var/datum/browser/popup = new(user, "autolathe", name, 400, 500) - popup.set_content(dat) - popup.open() - -/obj/machinery/autolathe/on_deconstruction() - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - materials.retrieve_all() - -/obj/machinery/autolathe/attackby(obj/item/O, mob/user, params) - if (busy) - to_chat(user, "The autolathe is busy. Please wait for completion of previous operation.") - return TRUE - - if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", O)) - updateUsrDialog() - return TRUE - - if(default_deconstruction_crowbar(O)) - return TRUE - - if(panel_open && is_wire_tool(O)) - wires.interact(user) - return TRUE - - if(user.a_intent == INTENT_HARM) //so we can hit the machine - return ..() - - if(stat) - return TRUE - - if(istype(O, /obj/item/disk/design_disk)) - user.visible_message("[user] begins to load \the [O] in \the [src]...", - "You begin to load a design from \the [O]...", - "You hear the chatter of a floppy drive.") - busy = TRUE - var/obj/item/disk/design_disk/D = O - if(do_after(user, 14.4, target = src)) - for(var/B in D.blueprints) - if(B) - stored_research.add_design(B) - busy = FALSE - return TRUE - - return ..() - -/obj/machinery/autolathe/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted) - if(ispath(type_inserted, /obj/item/stack/ore/bluespace_crystal)) - use_power(MINERAL_MATERIAL_AMOUNT / 10) - else - switch(id_inserted) - if (MAT_METAL) - flick("autolathe_o",src)//plays metal insertion animation - if (MAT_GLASS) - flick("autolathe_r",src)//plays glass insertion animation - use_power(min(1000, amount_inserted / 100)) - updateUsrDialog() - -/obj/machinery/autolathe/Topic(href, href_list) - if(..()) - return - if (!busy) - if(href_list["menu"]) - screen = text2num(href_list["menu"]) - updateUsrDialog() - - if(href_list["category"]) - selected_category = href_list["category"] - updateUsrDialog() - - if(href_list["make"]) - - ///////////////// - //href protection - being_built = stored_research.isDesignResearchedID(href_list["make"]) - if(!being_built) - return - - var/multiplier = text2num(href_list["multiplier"]) - var/is_stack = ispath(being_built.build_path, /obj/item/stack) - multiplier = CLAMP(multiplier,1,50) - - ///////////////// - - var/coeff = (is_stack ? 1 : prod_coeff) //stacks are unaffected by production coefficient - var/metal_cost = being_built.materials[MAT_METAL] - var/glass_cost = being_built.materials[MAT_GLASS] - - var/power = max(2000, (metal_cost+glass_cost)*multiplier/5) - - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - if((materials.amount(MAT_METAL) >= metal_cost*multiplier*coeff) && (materials.amount(MAT_GLASS) >= glass_cost*multiplier*coeff)) - busy = TRUE - use_power(power) - icon_state = "autolathe_n" - var/time = is_stack ? 32 : 32*coeff*multiplier - addtimer(CALLBACK(src, .proc/make_item, power, metal_cost, glass_cost, multiplier, coeff, is_stack), time) - - if(href_list["search"]) - matching_designs.Cut() - - for(var/v in stored_research.researched_designs) - var/datum/design/D = SSresearch.techweb_design_by_id(v) - if(findtext(D.name,href_list["to_search"])) - matching_designs.Add(D) - updateUsrDialog() - else - to_chat(usr, "The autolathe is busy. Please wait for completion of previous operation.") - - updateUsrDialog() - - return - -/obj/machinery/autolathe/proc/make_item(power, metal_cost, glass_cost, multiplier, coeff, is_stack) - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - var/atom/A = drop_location() - use_power(power) - var/list/materials_used = list(MAT_METAL=metal_cost*coeff*multiplier, MAT_GLASS=glass_cost*coeff*multiplier) - materials.use_amount(materials_used) - - if(is_stack) - var/obj/item/stack/N = new being_built.build_path(A, multiplier) - N.update_icon() - N.autolathe_crafted(src) - else - for(var/i=1, i<=multiplier, i++) - var/obj/item/new_item = new being_built.build_path(A) - new_item.materials = new_item.materials.Copy() - for(var/mat in materials_used) - new_item.materials[mat] = materials_used[mat] / multiplier - new_item.autolathe_crafted(src) - icon_state = "autolathe" - busy = FALSE - updateDialog() - -/obj/machinery/autolathe/RefreshParts() - var/T = 0 - for(var/obj/item/stock_parts/matter_bin/MB in component_parts) - T += MB.rating*75000 - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - materials.max_amount = T - T=1.2 - for(var/obj/item/stock_parts/manipulator/M in component_parts) - T -= M.rating*0.2 - prod_coeff = min(1,max(0,T)) // Coeff going 1 -> 0,8 -> 0,6 -> 0,4 - -/obj/machinery/autolathe/proc/main_win(mob/user) - var/dat = "

      Autolathe Menu:


      " - dat += materials_printout() - - dat += "
      \ - \ - \ - \ - \ - \ -

      " - - var/line_length = 1 - dat += "" - - for(var/C in categories) - if(line_length > 2) - dat += "" - line_length = 1 - - dat += "" - line_length++ - - dat += "
      [C]
      " - return dat - -/obj/machinery/autolathe/proc/category_win(mob/user,selected_category) - var/dat = "Return to main menu" - dat += "

      Browsing [selected_category]:


      " - dat += materials_printout() - - for(var/v in stored_research.researched_designs) - var/datum/design/D = SSresearch.techweb_design_by_id(v) - if(!(selected_category in D.category)) - continue - - if(disabled || !can_build(D)) - dat += "[D.name]" - else - dat += "[D.name]" - - if(ispath(D.build_path, /obj/item/stack)) - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - var/max_multiplier = min(D.maxstack, D.materials[MAT_METAL] ?round(materials.amount(MAT_METAL)/D.materials[MAT_METAL]):INFINITY,D.materials[MAT_GLASS]?round(materials.amount(MAT_GLASS)/D.materials[MAT_GLASS]):INFINITY) - if (max_multiplier>10 && !disabled) - dat += " x10" - if (max_multiplier>25 && !disabled) - dat += " x25" - if(max_multiplier > 0 && !disabled) - dat += " x[max_multiplier]" - else - if(!disabled && can_build(D, 5)) - dat += " x5" - if(!disabled && can_build(D, 10)) - dat += " x10" - - dat += "[get_design_cost(D)]
      " - - dat += "
      " - return dat - -/obj/machinery/autolathe/proc/search_win(mob/user) - var/dat = "Return to main menu" - dat += "

      Search results:


      " - dat += materials_printout() - - for(var/v in matching_designs) - var/datum/design/D = v - if(disabled || !can_build(D)) - dat += "[D.name]" - else - dat += "[D.name]" - - if(ispath(D.build_path, /obj/item/stack)) - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - var/max_multiplier = min(D.maxstack, D.materials[MAT_METAL] ?round(materials.amount(MAT_METAL)/D.materials[MAT_METAL]):INFINITY,D.materials[MAT_GLASS]?round(materials.amount(MAT_GLASS)/D.materials[MAT_GLASS]):INFINITY) - if (max_multiplier>10 && !disabled) - dat += " x10" - if (max_multiplier>25 && !disabled) - dat += " x25" - if(max_multiplier > 0 && !disabled) - dat += " x[max_multiplier]" - - dat += "[get_design_cost(D)]
      " - - dat += "
      " - return dat - -/obj/machinery/autolathe/proc/materials_printout() - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - var/dat = "Total amount: [materials.total_amount] / [materials.max_amount] cm3
      " - for(var/mat_id in materials.materials) - var/datum/material/M = materials.materials[mat_id] - dat += "[M.name] amount: [M.amount] cm3
      " - return dat - -/obj/machinery/autolathe/proc/can_build(datum/design/D, amount = 1) - if(D.make_reagents.len) - return FALSE - - var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff) - - var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) - if(D.materials[MAT_METAL] && (materials.amount(MAT_METAL) < (D.materials[MAT_METAL] * coeff * amount))) - return FALSE - if(D.materials[MAT_GLASS] && (materials.amount(MAT_GLASS) < (D.materials[MAT_GLASS] * coeff * amount))) - return FALSE - return TRUE - -/obj/machinery/autolathe/proc/get_design_cost(datum/design/D) - var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff) - var/dat - if(D.materials[MAT_METAL]) - dat += "[D.materials[MAT_METAL] * coeff] metal " - if(D.materials[MAT_GLASS]) - dat += "[D.materials[MAT_GLASS] * coeff] glass" - return dat - -/obj/machinery/autolathe/proc/reset(wire) - switch(wire) - if(WIRE_HACK) - if(!wires.is_cut(wire)) - adjust_hacked(FALSE) - if(WIRE_SHOCK) - if(!wires.is_cut(wire)) - shocked = FALSE - if(WIRE_DISABLE) - if(!wires.is_cut(wire)) - disabled = FALSE - -/obj/machinery/autolathe/proc/shock(mob/user, prb) - if(stat & (BROKEN|NOPOWER)) // unpowered, no shock - return FALSE - if(!prob(prb)) - return FALSE - 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, get_area(src), src, 0.7, TRUE)) - return TRUE - else - return FALSE - -/obj/machinery/autolathe/proc/adjust_hacked(state) - hacked = state - for(var/id in SSresearch.techweb_designs) - var/datum/design/D = SSresearch.techweb_design_by_id(id) - if((D.build_type & AUTOLATHE) && ("hacked" in D.category)) - if(hacked) - stored_research.add_design(D) - else - stored_research.remove_design(D) - -/obj/machinery/autolathe/hacked/Initialize() - . = ..() - adjust_hacked(TRUE) - -//Called when the object is constructed by an autolathe -//Has a reference to the autolathe so you can do !!FUN!! things with hacked lathes -/obj/item/proc/autolathe_crafted(obj/machinery/autolathe/A) +#define AUTOLATHE_MAIN_MENU 1 +#define AUTOLATHE_CATEGORY_MENU 2 +#define AUTOLATHE_SEARCH_MENU 3 + +/obj/machinery/autolathe + name = "autolathe" + desc = "It produces items using metal and glass." + icon_state = "autolathe" + density = TRUE + use_power = IDLE_POWER_USE + idle_power_usage = 10 + active_power_usage = 100 + circuit = /obj/item/circuitboard/machine/autolathe + layer = BELOW_OBJ_LAYER + + var/operating = FALSE + var/list/L = list() + var/list/LL = list() + var/hacked = FALSE + var/disabled = 0 + var/shocked = FALSE + var/hack_wire + var/disable_wire + var/shock_wire + + var/busy = FALSE + var/prod_coeff = 1 + + var/datum/design/being_built + var/datum/techweb/stored_research + var/list/datum/design/matching_designs + var/selected_category + var/screen = 1 + + var/list/categories = list( + "Tools", + "Electronics", + "Construction", + "T-Comm", + "Security", + "Machinery", + "Medical", + "Misc", + "Dinnerware", + "Imported" + ) + +/obj/machinery/autolathe/Initialize() + AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS), 0, TRUE, null, null, CALLBACK(src, .proc/AfterMaterialInsert)) + . = ..() + + wires = new /datum/wires/autolathe(src) + stored_research = new /datum/techweb/specialized/autounlocking/autolathe + matching_designs = list() + +/obj/machinery/autolathe/Destroy() + QDEL_NULL(wires) + return ..() + +/obj/machinery/autolathe/ui_interact(mob/user) + . = ..() + if(!is_operational()) + return + + if(shocked && !(stat & NOPOWER)) + shock(user,50) + + var/dat + + switch(screen) + if(AUTOLATHE_MAIN_MENU) + dat = main_win(user) + if(AUTOLATHE_CATEGORY_MENU) + dat = category_win(user,selected_category) + if(AUTOLATHE_SEARCH_MENU) + dat = search_win(user) + + var/datum/browser/popup = new(user, "autolathe", name, 400, 500) + popup.set_content(dat) + popup.open() + +/obj/machinery/autolathe/on_deconstruction() + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + materials.retrieve_all() + +/obj/machinery/autolathe/attackby(obj/item/O, mob/user, params) + if (busy) + to_chat(user, "The autolathe is busy. Please wait for completion of previous operation.") + return TRUE + + if(default_deconstruction_screwdriver(user, "autolathe_t", "autolathe", O)) + updateUsrDialog() + return TRUE + + if(default_deconstruction_crowbar(O)) + return TRUE + + if(panel_open && is_wire_tool(O)) + wires.interact(user) + return TRUE + + if(user.a_intent == INTENT_HARM) //so we can hit the machine + return ..() + + if(stat) + return TRUE + + if(istype(O, /obj/item/disk/design_disk)) + user.visible_message("[user] begins to load \the [O] in \the [src]...", + "You begin to load a design from \the [O]...", + "You hear the chatter of a floppy drive.") + busy = TRUE + var/obj/item/disk/design_disk/D = O + if(do_after(user, 14.4, target = src)) + for(var/B in D.blueprints) + if(B) + stored_research.add_design(B) + busy = FALSE + return TRUE + + return ..() + +/obj/machinery/autolathe/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted) + if(ispath(type_inserted, /obj/item/stack/ore/bluespace_crystal)) + use_power(MINERAL_MATERIAL_AMOUNT / 10) + else + switch(id_inserted) + if (MAT_METAL) + flick("autolathe_o",src)//plays metal insertion animation + if (MAT_GLASS) + flick("autolathe_r",src)//plays glass insertion animation + use_power(min(1000, amount_inserted / 100)) + updateUsrDialog() + +/obj/machinery/autolathe/Topic(href, href_list) + if(..()) + return + if (!busy) + if(href_list["menu"]) + screen = text2num(href_list["menu"]) + updateUsrDialog() + + if(href_list["category"]) + selected_category = href_list["category"] + updateUsrDialog() + + if(href_list["make"]) + + ///////////////// + //href protection + being_built = stored_research.isDesignResearchedID(href_list["make"]) + if(!being_built) + return + + var/multiplier = text2num(href_list["multiplier"]) + var/is_stack = ispath(being_built.build_path, /obj/item/stack) + multiplier = CLAMP(multiplier,1,50) + + ///////////////// + + var/coeff = (is_stack ? 1 : prod_coeff) //stacks are unaffected by production coefficient + var/metal_cost = being_built.materials[MAT_METAL] + var/glass_cost = being_built.materials[MAT_GLASS] + + var/power = max(2000, (metal_cost+glass_cost)*multiplier/5) + + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + if((materials.amount(MAT_METAL) >= metal_cost*multiplier*coeff) && (materials.amount(MAT_GLASS) >= glass_cost*multiplier*coeff)) + busy = TRUE + use_power(power) + icon_state = "autolathe_n" + var/time = is_stack ? 32 : 32*coeff*multiplier + addtimer(CALLBACK(src, .proc/make_item, power, metal_cost, glass_cost, multiplier, coeff, is_stack), time) + + if(href_list["search"]) + matching_designs.Cut() + + for(var/v in stored_research.researched_designs) + var/datum/design/D = SSresearch.techweb_design_by_id(v) + if(findtext(D.name,href_list["to_search"])) + matching_designs.Add(D) + updateUsrDialog() + else + to_chat(usr, "The autolathe is busy. Please wait for completion of previous operation.") + + updateUsrDialog() + + return + +/obj/machinery/autolathe/proc/make_item(power, metal_cost, glass_cost, multiplier, coeff, is_stack) + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + var/atom/A = drop_location() + use_power(power) + var/list/materials_used = list(MAT_METAL=metal_cost*coeff*multiplier, MAT_GLASS=glass_cost*coeff*multiplier) + materials.use_amount(materials_used) + + if(is_stack) + var/obj/item/stack/N = new being_built.build_path(A, multiplier) + N.update_icon() + N.autolathe_crafted(src) + else + for(var/i=1, i<=multiplier, i++) + var/obj/item/new_item = new being_built.build_path(A) + new_item.materials = new_item.materials.Copy() + for(var/mat in materials_used) + new_item.materials[mat] = materials_used[mat] / multiplier + new_item.autolathe_crafted(src) + icon_state = "autolathe" + busy = FALSE + updateDialog() + +/obj/machinery/autolathe/RefreshParts() + var/T = 0 + for(var/obj/item/stock_parts/matter_bin/MB in component_parts) + T += MB.rating*75000 + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + materials.max_amount = T + T=1.2 + for(var/obj/item/stock_parts/manipulator/M in component_parts) + T -= M.rating*0.2 + prod_coeff = min(1,max(0,T)) // Coeff going 1 -> 0,8 -> 0,6 -> 0,4 + +/obj/machinery/autolathe/proc/main_win(mob/user) + var/dat = "

      Autolathe Menu:


      " + dat += materials_printout() + + dat += "
      \ + \ + \ + \ + \ + \ +

      " + + var/line_length = 1 + dat += "" + + for(var/C in categories) + if(line_length > 2) + dat += "" + line_length = 1 + + dat += "" + line_length++ + + dat += "
      [C]
      " + return dat + +/obj/machinery/autolathe/proc/category_win(mob/user,selected_category) + var/dat = "Return to main menu" + dat += "

      Browsing [selected_category]:


      " + dat += materials_printout() + + for(var/v in stored_research.researched_designs) + var/datum/design/D = SSresearch.techweb_design_by_id(v) + if(!(selected_category in D.category)) + continue + + if(disabled || !can_build(D)) + dat += "[D.name]" + else + dat += "[D.name]" + + if(ispath(D.build_path, /obj/item/stack)) + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + var/max_multiplier = min(D.maxstack, D.materials[MAT_METAL] ?round(materials.amount(MAT_METAL)/D.materials[MAT_METAL]):INFINITY,D.materials[MAT_GLASS]?round(materials.amount(MAT_GLASS)/D.materials[MAT_GLASS]):INFINITY) + if (max_multiplier>10 && !disabled) + dat += " x10" + if (max_multiplier>25 && !disabled) + dat += " x25" + if(max_multiplier > 0 && !disabled) + dat += " x[max_multiplier]" + else + if(!disabled && can_build(D, 5)) + dat += " x5" + if(!disabled && can_build(D, 10)) + dat += " x10" + + dat += "[get_design_cost(D)]
      " + + dat += "
      " + return dat + +/obj/machinery/autolathe/proc/search_win(mob/user) + var/dat = "Return to main menu" + dat += "

      Search results:


      " + dat += materials_printout() + + for(var/v in matching_designs) + var/datum/design/D = v + if(disabled || !can_build(D)) + dat += "[D.name]" + else + dat += "[D.name]" + + if(ispath(D.build_path, /obj/item/stack)) + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + var/max_multiplier = min(D.maxstack, D.materials[MAT_METAL] ?round(materials.amount(MAT_METAL)/D.materials[MAT_METAL]):INFINITY,D.materials[MAT_GLASS]?round(materials.amount(MAT_GLASS)/D.materials[MAT_GLASS]):INFINITY) + if (max_multiplier>10 && !disabled) + dat += " x10" + if (max_multiplier>25 && !disabled) + dat += " x25" + if(max_multiplier > 0 && !disabled) + dat += " x[max_multiplier]" + + dat += "[get_design_cost(D)]
      " + + dat += "
      " + return dat + +/obj/machinery/autolathe/proc/materials_printout() + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + var/dat = "Total amount: [materials.total_amount] / [materials.max_amount] cm3
      " + for(var/mat_id in materials.materials) + var/datum/material/M = materials.materials[mat_id] + dat += "[M.name] amount: [M.amount] cm3
      " + return dat + +/obj/machinery/autolathe/proc/can_build(datum/design/D, amount = 1) + if(D.make_reagents.len) + return FALSE + + var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff) + + var/datum/component/material_container/materials = GetComponent(/datum/component/material_container) + if(D.materials[MAT_METAL] && (materials.amount(MAT_METAL) < (D.materials[MAT_METAL] * coeff * amount))) + return FALSE + if(D.materials[MAT_GLASS] && (materials.amount(MAT_GLASS) < (D.materials[MAT_GLASS] * coeff * amount))) + return FALSE + return TRUE + +/obj/machinery/autolathe/proc/get_design_cost(datum/design/D) + var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff) + var/dat + if(D.materials[MAT_METAL]) + dat += "[D.materials[MAT_METAL] * coeff] metal " + if(D.materials[MAT_GLASS]) + dat += "[D.materials[MAT_GLASS] * coeff] glass" + return dat + +/obj/machinery/autolathe/proc/reset(wire) + switch(wire) + if(WIRE_HACK) + if(!wires.is_cut(wire)) + adjust_hacked(FALSE) + if(WIRE_SHOCK) + if(!wires.is_cut(wire)) + shocked = FALSE + if(WIRE_DISABLE) + if(!wires.is_cut(wire)) + disabled = FALSE + +/obj/machinery/autolathe/proc/shock(mob/user, prb) + if(stat & (BROKEN|NOPOWER)) // unpowered, no shock + return FALSE + if(!prob(prb)) + return FALSE + 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, get_area(src), src, 0.7, TRUE)) + return TRUE + else + return FALSE + +/obj/machinery/autolathe/proc/adjust_hacked(state) + hacked = state + for(var/id in SSresearch.techweb_designs) + var/datum/design/D = SSresearch.techweb_design_by_id(id) + if((D.build_type & AUTOLATHE) && ("hacked" in D.category)) + if(hacked) + stored_research.add_design(D) + else + stored_research.remove_design(D) + +/obj/machinery/autolathe/hacked/Initialize() + . = ..() + adjust_hacked(TRUE) + +//Called when the object is constructed by an autolathe +//Has a reference to the autolathe so you can do !!FUN!! things with hacked lathes +/obj/item/proc/autolathe_crafted(obj/machinery/autolathe/A) return \ No newline at end of file diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 24c9e32969..3a9b560bd6 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -1,268 +1,268 @@ -/obj/machinery/button - name = "button" - desc = "A remote control switch." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "doorctrl" - var/skin = "doorctrl" - power_channel = ENVIRON - var/obj/item/assembly/device - var/obj/item/electronics/airlock/board - var/device_type = null - var/id = null - var/initialized_button = 0 - armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 70) - use_power = IDLE_POWER_USE - idle_power_usage = 2 - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - -/obj/machinery/button/Initialize(mapload, ndir = 0, built = 0) - . = ..() - if(built) - setDir(ndir) - pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) - pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0 - panel_open = TRUE - update_icon() - - - if(!built && !device && device_type) - device = new device_type(src) - - src.check_access(null) - - if(req_access.len || req_one_access.len) - board = new(src) - if(req_access.len) - board.accesses = req_access - else - board.one_access = 1 - board.accesses = req_one_access - -/obj/machinery/button/update_icon_state() - if(panel_open) - icon_state = "button-open" - else if(stat & (NOPOWER|BROKEN)) - icon_state = "[skin]-p" - else - icon_state = skin - -/obj/machinery/button/update_overlays() - . = ..() - if(!panel_open) - return - if(device) - . += "button-device" - if(board) - . += "button-board" - -/obj/machinery/button/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/screwdriver)) - if(panel_open || allowed(user)) - default_deconstruction_screwdriver(user, "button-open", "[skin]",W) - update_icon() - else - to_chat(user, "Maintenance Access Denied") - flick("[skin]-denied", src) - return - - if(panel_open) - if(!device && istype(W, /obj/item/assembly)) - if(!user.transferItemToLoc(W, src)) - to_chat(user, "\The [W] is stuck to you!") - return - device = W - to_chat(user, "You add [W] to the button.") - - if(!board && istype(W, /obj/item/electronics/airlock)) - if(!user.transferItemToLoc(W, src)) - to_chat(user, "\The [W] is stuck to you!") - return - board = W - if(board.one_access) - req_one_access = board.accesses - else - req_access = board.accesses - to_chat(user, "You add [W] to the button.") - - if(!device && !board && istype(W, /obj/item/wrench)) - to_chat(user, "You start unsecuring the button frame...") - W.play_tool_sound(src) - if(W.use_tool(src, user, 40)) - to_chat(user, "You unsecure the button frame.") - transfer_fingerprints_to(new /obj/item/wallframe/button(get_turf(src))) - playsound(loc, 'sound/items/deconstruct.ogg', 50, 1) - qdel(src) - - update_icon() - return - - if(user.a_intent != INTENT_HARM && !(W.item_flags & NOBLUDGEON)) - return attack_hand(user) - else - return ..() - -/obj/machinery/button/emag_act(mob/user) - . = ..() - if(obj_flags & EMAGGED) - return - req_access = list() - req_one_access = list() - playsound(src, "sparks", 100, 1) - obj_flags |= EMAGGED - return TRUE - -/obj/machinery/button/attack_ai(mob/user) - if(!panel_open) - return attack_hand(user) - -/obj/machinery/button/attack_robot(mob/user) - return attack_ai(user) - -/obj/machinery/button/proc/setup_device() - if(id && istype(device, /obj/item/assembly/control)) - var/obj/item/assembly/control/A = device - A.id = id - initialized_button = 1 - -/obj/machinery/button/attack_hand(mob/user) - . = ..() - if(.) - return - if(!initialized_button) - setup_device() - add_fingerprint(user) - if(panel_open) - if(device || board) - if(device) - device.forceMove(drop_location()) - device = null - if(board) - board.forceMove(drop_location()) - req_access = list() - req_one_access = list() - board = null - update_icon() - to_chat(user, "You remove electronics from the button frame.") - - else - if(skin == "doorctrl") - skin = "launcher" - else - skin = "doorctrl" - to_chat(user, "You change the button frame's front panel.") - return - - if((stat & (NOPOWER|BROKEN))) - return - - if(device && device.next_activate > world.time) - return - - if(!allowed(user)) - to_chat(user, "Access Denied") - flick("[skin]-denied", src) - return - - use_power(5) - icon_state = "[skin]1" - - if(device) - device.pulsed() - - addtimer(CALLBACK(src, /atom/.proc/update_icon), 15) - -/obj/machinery/button/power_change() - ..() - update_icon() - - -/obj/machinery/button/door - name = "door button" - desc = "A door remote control switch." - var/normaldoorcontrol = FALSE - var/specialfunctions = OPEN // Bitflag, see assembly file - -/obj/machinery/button/door/setup_device() - if(!device) - if(normaldoorcontrol) - var/obj/item/assembly/control/airlock/A = new(src) - device = A - A.specialfunctions = specialfunctions - else - device = new /obj/item/assembly/control(src) - ..() - -/obj/machinery/button/door/incinerator_vent_toxmix - name = "combustion chamber vent control" - id = INCINERATOR_TOXMIX_VENT - req_access = list(ACCESS_TOX) - -/obj/machinery/button/door/incinerator_vent_atmos_main - name = "turbine vent control" - id = INCINERATOR_ATMOS_MAINVENT - req_one_access = list(ACCESS_ATMOSPHERICS, ACCESS_MAINT_TUNNELS) - -/obj/machinery/button/door/incinerator_vent_atmos_aux - name = "combustion chamber vent control" - id = INCINERATOR_ATMOS_AUXVENT - req_one_access = list(ACCESS_ATMOSPHERICS, ACCESS_MAINT_TUNNELS) - -/obj/machinery/button/door/incinerator_vent_syndicatelava_main - name = "turbine vent control" - id = INCINERATOR_SYNDICATELAVA_MAINVENT - req_access = list(ACCESS_SYNDICATE) - -/obj/machinery/button/door/incinerator_vent_syndicatelava_aux - name = "combustion chamber vent control" - id = INCINERATOR_SYNDICATELAVA_AUXVENT - req_access = list(ACCESS_SYNDICATE) - -/obj/machinery/button/massdriver - name = "mass driver button" - desc = "A remote control switch for a mass driver." - icon_state = "launcher" - skin = "launcher" - device_type = /obj/item/assembly/control/massdriver - -/obj/machinery/button/ignition - name = "ignition switch" - desc = "A remote control switch for a mounted igniter." - icon_state = "launcher" - skin = "launcher" - device_type = /obj/item/assembly/control/igniter - -/obj/machinery/button/ignition/incinerator - name = "combustion chamber ignition switch" - desc = "A remote control switch for the combustion chamber's igniter." - -/obj/machinery/button/ignition/incinerator/toxmix - id = INCINERATOR_TOXMIX_IGNITER - -/obj/machinery/button/ignition/incinerator/atmos - id = INCINERATOR_ATMOS_IGNITER - -/obj/machinery/button/ignition/incinerator/syndicatelava - id = INCINERATOR_SYNDICATELAVA_IGNITER - -/obj/machinery/button/flasher - name = "flasher button" - desc = "A remote control switch for a mounted flasher." - icon_state = "launcher" - skin = "launcher" - device_type = /obj/item/assembly/control/flasher - -/obj/machinery/button/crematorium - name = "crematorium igniter" - desc = "Burn baby burn!" - icon_state = "launcher" - skin = "launcher" - device_type = /obj/item/assembly/control/crematorium - req_access = list() - id = 1 - -/obj/item/wallframe/button - name = "button frame" - desc = "Used for building buttons." - icon_state = "button" - result_path = /obj/machinery/button - materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT) +/obj/machinery/button + name = "button" + desc = "A remote control switch." + icon = 'icons/obj/stationobjs.dmi' + icon_state = "doorctrl" + var/skin = "doorctrl" + power_channel = ENVIRON + var/obj/item/assembly/device + var/obj/item/electronics/airlock/board + var/device_type = null + var/id = null + var/initialized_button = 0 + armor = list("melee" = 50, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 90, "acid" = 70) + use_power = IDLE_POWER_USE + idle_power_usage = 2 + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + +/obj/machinery/button/Initialize(mapload, ndir = 0, built = 0) + . = ..() + if(built) + setDir(ndir) + pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) + pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0 + panel_open = TRUE + update_icon() + + + if(!built && !device && device_type) + device = new device_type(src) + + src.check_access(null) + + if(req_access.len || req_one_access.len) + board = new(src) + if(req_access.len) + board.accesses = req_access + else + board.one_access = 1 + board.accesses = req_one_access + +/obj/machinery/button/update_icon_state() + if(panel_open) + icon_state = "button-open" + else if(stat & (NOPOWER|BROKEN)) + icon_state = "[skin]-p" + else + icon_state = skin + +/obj/machinery/button/update_overlays() + . = ..() + if(!panel_open) + return + if(device) + . += "button-device" + if(board) + . += "button-board" + +/obj/machinery/button/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/screwdriver)) + if(panel_open || allowed(user)) + default_deconstruction_screwdriver(user, "button-open", "[skin]",W) + update_icon() + else + to_chat(user, "Maintenance Access Denied") + flick("[skin]-denied", src) + return + + if(panel_open) + if(!device && istype(W, /obj/item/assembly)) + if(!user.transferItemToLoc(W, src)) + to_chat(user, "\The [W] is stuck to you!") + return + device = W + to_chat(user, "You add [W] to the button.") + + if(!board && istype(W, /obj/item/electronics/airlock)) + if(!user.transferItemToLoc(W, src)) + to_chat(user, "\The [W] is stuck to you!") + return + board = W + if(board.one_access) + req_one_access = board.accesses + else + req_access = board.accesses + to_chat(user, "You add [W] to the button.") + + if(!device && !board && istype(W, /obj/item/wrench)) + to_chat(user, "You start unsecuring the button frame...") + W.play_tool_sound(src) + if(W.use_tool(src, user, 40)) + to_chat(user, "You unsecure the button frame.") + transfer_fingerprints_to(new /obj/item/wallframe/button(get_turf(src))) + playsound(loc, 'sound/items/deconstruct.ogg', 50, 1) + qdel(src) + + update_icon() + return + + if(user.a_intent != INTENT_HARM && !(W.item_flags & NOBLUDGEON)) + return attack_hand(user) + else + return ..() + +/obj/machinery/button/emag_act(mob/user) + . = ..() + if(obj_flags & EMAGGED) + return + req_access = list() + req_one_access = list() + playsound(src, "sparks", 100, 1) + obj_flags |= EMAGGED + return TRUE + +/obj/machinery/button/attack_ai(mob/user) + if(!panel_open) + return attack_hand(user) + +/obj/machinery/button/attack_robot(mob/user) + return attack_ai(user) + +/obj/machinery/button/proc/setup_device() + if(id && istype(device, /obj/item/assembly/control)) + var/obj/item/assembly/control/A = device + A.id = id + initialized_button = 1 + +/obj/machinery/button/attack_hand(mob/user) + . = ..() + if(.) + return + if(!initialized_button) + setup_device() + add_fingerprint(user) + if(panel_open) + if(device || board) + if(device) + device.forceMove(drop_location()) + device = null + if(board) + board.forceMove(drop_location()) + req_access = list() + req_one_access = list() + board = null + update_icon() + to_chat(user, "You remove electronics from the button frame.") + + else + if(skin == "doorctrl") + skin = "launcher" + else + skin = "doorctrl" + to_chat(user, "You change the button frame's front panel.") + return + + if((stat & (NOPOWER|BROKEN))) + return + + if(device && device.next_activate > world.time) + return + + if(!allowed(user)) + to_chat(user, "Access Denied") + flick("[skin]-denied", src) + return + + use_power(5) + icon_state = "[skin]1" + + if(device) + device.pulsed() + + addtimer(CALLBACK(src, /atom/.proc/update_icon), 15) + +/obj/machinery/button/power_change() + ..() + update_icon() + + +/obj/machinery/button/door + name = "door button" + desc = "A door remote control switch." + var/normaldoorcontrol = FALSE + var/specialfunctions = OPEN // Bitflag, see assembly file + +/obj/machinery/button/door/setup_device() + if(!device) + if(normaldoorcontrol) + var/obj/item/assembly/control/airlock/A = new(src) + device = A + A.specialfunctions = specialfunctions + else + device = new /obj/item/assembly/control(src) + ..() + +/obj/machinery/button/door/incinerator_vent_toxmix + name = "combustion chamber vent control" + id = INCINERATOR_TOXMIX_VENT + req_access = list(ACCESS_TOX) + +/obj/machinery/button/door/incinerator_vent_atmos_main + name = "turbine vent control" + id = INCINERATOR_ATMOS_MAINVENT + req_one_access = list(ACCESS_ATMOSPHERICS, ACCESS_MAINT_TUNNELS) + +/obj/machinery/button/door/incinerator_vent_atmos_aux + name = "combustion chamber vent control" + id = INCINERATOR_ATMOS_AUXVENT + req_one_access = list(ACCESS_ATMOSPHERICS, ACCESS_MAINT_TUNNELS) + +/obj/machinery/button/door/incinerator_vent_syndicatelava_main + name = "turbine vent control" + id = INCINERATOR_SYNDICATELAVA_MAINVENT + req_access = list(ACCESS_SYNDICATE) + +/obj/machinery/button/door/incinerator_vent_syndicatelava_aux + name = "combustion chamber vent control" + id = INCINERATOR_SYNDICATELAVA_AUXVENT + req_access = list(ACCESS_SYNDICATE) + +/obj/machinery/button/massdriver + name = "mass driver button" + desc = "A remote control switch for a mass driver." + icon_state = "launcher" + skin = "launcher" + device_type = /obj/item/assembly/control/massdriver + +/obj/machinery/button/ignition + name = "ignition switch" + desc = "A remote control switch for a mounted igniter." + icon_state = "launcher" + skin = "launcher" + device_type = /obj/item/assembly/control/igniter + +/obj/machinery/button/ignition/incinerator + name = "combustion chamber ignition switch" + desc = "A remote control switch for the combustion chamber's igniter." + +/obj/machinery/button/ignition/incinerator/toxmix + id = INCINERATOR_TOXMIX_IGNITER + +/obj/machinery/button/ignition/incinerator/atmos + id = INCINERATOR_ATMOS_IGNITER + +/obj/machinery/button/ignition/incinerator/syndicatelava + id = INCINERATOR_SYNDICATELAVA_IGNITER + +/obj/machinery/button/flasher + name = "flasher button" + desc = "A remote control switch for a mounted flasher." + icon_state = "launcher" + skin = "launcher" + device_type = /obj/item/assembly/control/flasher + +/obj/machinery/button/crematorium + name = "crematorium igniter" + desc = "Burn baby burn!" + icon_state = "launcher" + skin = "launcher" + device_type = /obj/item/assembly/control/crematorium + req_access = list() + id = 1 + +/obj/item/wallframe/button + name = "button frame" + desc = "Used for building buttons." + icon_state = "button" + result_path = /obj/machinery/button + materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT) diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm index b120720992..66e302bab6 100644 --- a/code/game/machinery/camera/camera_assembly.dm +++ b/code/game/machinery/camera/camera_assembly.dm @@ -1,148 +1,148 @@ -/obj/item/wallframe/camera - name = "camera assembly" - desc = "The basic construction for Nanotrasen-Always-Watching-You cameras." - icon = 'icons/obj/machines/camera.dmi' - icon_state = "cameracase" - materials = list(MAT_METAL=400, MAT_GLASS=250) - result_path = /obj/structure/camera_assembly - - -/obj/structure/camera_assembly - name = "camera assembly" - desc = "The basic construction for Nanotrasen-Always-Watching-You cameras." - icon = 'icons/obj/machines/camera.dmi' - icon_state = "camera1" - max_integrity = 150 - // Motion, EMP-Proof, X-ray - var/static/list/possible_upgrades = typecacheof(list(/obj/item/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma, /obj/item/analyzer)) - var/list/upgrades - var/state = 1 - - /* - 1 = Wrenched in place - 2 = Welded in place - 3 = Wires attached to it (you can now attach/dettach upgrades) - 4 = Screwdriver panel closed and is fully built (you cannot attach upgrades) - */ - -/obj/structure/camera_assembly/Initialize(mapload, ndir, building) - . = ..() - if(building) - setDir(ndir) - upgrades = list() - -/obj/structure/camera_assembly/Destroy() - QDEL_LIST(upgrades) - return ..() - -/obj/structure/camera_assembly/attackby(obj/item/W, mob/living/user, params) - switch(state) - if(1) - // State 1 - if(istype(W, /obj/item/weldingtool)) - if(weld(W, user)) - to_chat(user, "You weld the assembly securely into place.") - setAnchored(TRUE) - state = 2 - return - if(2) - // State 2 - if(istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/C = W - if(C.use(2)) - to_chat(user, "You add wires to the assembly.") - state = 3 - else - to_chat(user, "You need two lengths of cable to wire a camera!") - return - return - - else if(istype(W, /obj/item/weldingtool)) - - if(weld(W, user)) - to_chat(user, "You unweld the assembly from its place.") - state = 1 - setAnchored(TRUE) - return - - // Upgrades! - if(is_type_in_typecache(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already. - if(!user.transferItemToLoc(W, src)) - return - to_chat(user, "You attach \the [W] into the assembly inner circuits.") - upgrades += W - return - - return ..() - -/obj/structure/camera_assembly/crowbar_act(mob/user, obj/item/tool) - if(!upgrades.len) - return FALSE - var/obj/U = locate(/obj) in upgrades - if(U) - to_chat(user, "You detach an upgrade from the assembly.") - tool.play_tool_sound(src) - U.forceMove(drop_location()) - upgrades -= U - return TRUE - -/obj/structure/camera_assembly/screwdriver_act(mob/user, obj/item/tool) - . = ..() - if(.) - return TRUE - if(state != 3) - return FALSE - - tool.play_tool_sound(src) - var/input = stripped_input(user, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13") - if(!input) - to_chat(user, "No input found, please hang up and try your call again!") - return - var/list/tempnetwork = splittext(input, ",") - if(tempnetwork.len < 1) - to_chat(user, "No network found, please hang up and try your call again!") - return - for(var/i in tempnetwork) - tempnetwork -= i - tempnetwork += lowertext(i) - state = 4 - var/obj/machinery/camera/C = new(loc, src) - forceMove(C) - C.setDir(src.dir) - - C.network = tempnetwork - var/area/A = get_area(src) - C.c_tag = "[A.name] ([rand(1, 999)])" - return TRUE - -/obj/structure/camera_assembly/wirecutter_act(mob/user, obj/item/I) - if(state != 3) - return FALSE - - new /obj/item/stack/cable_coil(drop_location(), 2) - I.play_tool_sound(src) - to_chat(user, "You cut the wires from the circuits.") - state = 2 - return TRUE - -/obj/structure/camera_assembly/wrench_act(mob/user, obj/item/I) - if(state != 1) - return FALSE - I.play_tool_sound(src) - to_chat(user, "You detach the assembly from its place.") - new /obj/item/wallframe/camera(drop_location()) - qdel(src) - return TRUE - -/obj/structure/camera_assembly/proc/weld(obj/item/weldingtool/W, mob/living/user) - if(!W.tool_start_check(user, amount=0)) - return FALSE - to_chat(user, "You start to weld \the [src]...") - if(W.use_tool(src, user, 20, volume=50)) - return TRUE - return FALSE - -/obj/structure/camera_assembly/deconstruct(disassembled = TRUE) - if(!(flags_1 & NODECONSTRUCT_1)) - new /obj/item/stack/sheet/metal(loc) - qdel(src) +/obj/item/wallframe/camera + name = "camera assembly" + desc = "The basic construction for Nanotrasen-Always-Watching-You cameras." + icon = 'icons/obj/machines/camera.dmi' + icon_state = "cameracase" + materials = list(MAT_METAL=400, MAT_GLASS=250) + result_path = /obj/structure/camera_assembly + + +/obj/structure/camera_assembly + name = "camera assembly" + desc = "The basic construction for Nanotrasen-Always-Watching-You cameras." + icon = 'icons/obj/machines/camera.dmi' + icon_state = "camera1" + max_integrity = 150 + // Motion, EMP-Proof, X-ray + var/static/list/possible_upgrades = typecacheof(list(/obj/item/assembly/prox_sensor, /obj/item/stack/sheet/mineral/plasma, /obj/item/analyzer)) + var/list/upgrades + var/state = 1 + + /* + 1 = Wrenched in place + 2 = Welded in place + 3 = Wires attached to it (you can now attach/dettach upgrades) + 4 = Screwdriver panel closed and is fully built (you cannot attach upgrades) + */ + +/obj/structure/camera_assembly/Initialize(mapload, ndir, building) + . = ..() + if(building) + setDir(ndir) + upgrades = list() + +/obj/structure/camera_assembly/Destroy() + QDEL_LIST(upgrades) + return ..() + +/obj/structure/camera_assembly/attackby(obj/item/W, mob/living/user, params) + switch(state) + if(1) + // State 1 + if(istype(W, /obj/item/weldingtool)) + if(weld(W, user)) + to_chat(user, "You weld the assembly securely into place.") + setAnchored(TRUE) + state = 2 + return + if(2) + // State 2 + if(istype(W, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/C = W + if(C.use(2)) + to_chat(user, "You add wires to the assembly.") + state = 3 + else + to_chat(user, "You need two lengths of cable to wire a camera!") + return + return + + else if(istype(W, /obj/item/weldingtool)) + + if(weld(W, user)) + to_chat(user, "You unweld the assembly from its place.") + state = 1 + setAnchored(TRUE) + return + + // Upgrades! + if(is_type_in_typecache(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already. + if(!user.transferItemToLoc(W, src)) + return + to_chat(user, "You attach \the [W] into the assembly inner circuits.") + upgrades += W + return + + return ..() + +/obj/structure/camera_assembly/crowbar_act(mob/user, obj/item/tool) + if(!upgrades.len) + return FALSE + var/obj/U = locate(/obj) in upgrades + if(U) + to_chat(user, "You detach an upgrade from the assembly.") + tool.play_tool_sound(src) + U.forceMove(drop_location()) + upgrades -= U + return TRUE + +/obj/structure/camera_assembly/screwdriver_act(mob/user, obj/item/tool) + . = ..() + if(.) + return TRUE + if(state != 3) + return FALSE + + tool.play_tool_sound(src) + var/input = stripped_input(user, "Which networks would you like to connect this camera to? Separate networks with a comma. No Spaces!\nFor example: SS13,Security,Secret ", "Set Network", "SS13") + if(!input) + to_chat(user, "No input found, please hang up and try your call again!") + return + var/list/tempnetwork = splittext(input, ",") + if(tempnetwork.len < 1) + to_chat(user, "No network found, please hang up and try your call again!") + return + for(var/i in tempnetwork) + tempnetwork -= i + tempnetwork += lowertext(i) + state = 4 + var/obj/machinery/camera/C = new(loc, src) + forceMove(C) + C.setDir(src.dir) + + C.network = tempnetwork + var/area/A = get_area(src) + C.c_tag = "[A.name] ([rand(1, 999)])" + return TRUE + +/obj/structure/camera_assembly/wirecutter_act(mob/user, obj/item/I) + if(state != 3) + return FALSE + + new /obj/item/stack/cable_coil(drop_location(), 2) + I.play_tool_sound(src) + to_chat(user, "You cut the wires from the circuits.") + state = 2 + return TRUE + +/obj/structure/camera_assembly/wrench_act(mob/user, obj/item/I) + if(state != 1) + return FALSE + I.play_tool_sound(src) + to_chat(user, "You detach the assembly from its place.") + new /obj/item/wallframe/camera(drop_location()) + qdel(src) + return TRUE + +/obj/structure/camera_assembly/proc/weld(obj/item/weldingtool/W, mob/living/user) + if(!W.tool_start_check(user, amount=0)) + return FALSE + to_chat(user, "You start to weld \the [src]...") + if(W.use_tool(src, user, 20, volume=50)) + return TRUE + return FALSE + +/obj/structure/camera_assembly/deconstruct(disassembled = TRUE) + if(!(flags_1 & NODECONSTRUCT_1)) + new /obj/item/stack/sheet/metal(loc) + qdel(src) diff --git a/code/game/machinery/camera/motion.dm b/code/game/machinery/camera/motion.dm index 6c134417bb..d103e2a856 100644 --- a/code/game/machinery/camera/motion.dm +++ b/code/game/machinery/camera/motion.dm @@ -1,77 +1,77 @@ -/obj/machinery/camera - - var/list/datum/weakref/localMotionTargets = list() - var/detectTime = 0 - var/area/ai_monitored/area_motion = null - var/alarm_delay = 30 // Don't forget, there's another 3 seconds in queueAlarm() - -/obj/machinery/camera/process() - // motion camera event loop - if(!isMotion()) - . = PROCESS_KILL - return - if(stat & EMPED) - return - if (detectTime > 0) - var/elapsed = world.time - detectTime - if (elapsed > alarm_delay) - triggerAlarm() - else if (detectTime == -1) - for (var/datum/weakref/targetref in getTargetList()) - var/mob/target = targetref.resolve() - if(QDELETED(target) || target.stat == DEAD || (!area_motion && !in_range(src, target))) - //If not part of a monitored area and the camera is not in range or the target is dead - lostTargetRef(targetref) - -/obj/machinery/camera/proc/getTargetList() - if(area_motion) - return area_motion.motionTargets - return localMotionTargets - -/obj/machinery/camera/proc/newTarget(mob/target) - if(isAI(target)) - return FALSE - if (detectTime == 0) - detectTime = world.time // start the clock - var/list/targets = getTargetList() - targets |= WEAKREF(target) - return TRUE - -/obj/machinery/camera/Destroy() - var/area/ai_monitored/A = get_area(src) - localMotionTargets = null - if(istype(A)) - A.motioncameras -= src - cancelAlarm() - return ..() - -/obj/machinery/camera/proc/lostTargetRef(datum/weakref/R) - var/list/targets = getTargetList() - targets -= R - if (targets.len == 0) - cancelAlarm() - -/obj/machinery/camera/proc/cancelAlarm() - if (detectTime == -1) - for (var/i in GLOB.silicon_mobs) - var/mob/living/silicon/aiPlayer = i - if (status) - aiPlayer.cancelAlarm("Motion", get_area(src), src) - detectTime = 0 - return TRUE - -/obj/machinery/camera/proc/triggerAlarm() - if (!detectTime) - return FALSE - for (var/mob/living/silicon/aiPlayer in GLOB.player_list) - if (status) - aiPlayer.triggerAlarm("Motion", get_area(src), list(src), src) - visible_message("A red light flashes on the [src]!") - detectTime = -1 - return TRUE - -/obj/machinery/camera/HasProximity(atom/movable/AM as mob|obj) - // Motion cameras outside of an "ai monitored" area will use this to detect stuff. - if (!area_motion) - if(isliving(AM)) - newTarget(AM) +/obj/machinery/camera + + var/list/datum/weakref/localMotionTargets = list() + var/detectTime = 0 + var/area/ai_monitored/area_motion = null + var/alarm_delay = 30 // Don't forget, there's another 3 seconds in queueAlarm() + +/obj/machinery/camera/process() + // motion camera event loop + if(!isMotion()) + . = PROCESS_KILL + return + if(stat & EMPED) + return + if (detectTime > 0) + var/elapsed = world.time - detectTime + if (elapsed > alarm_delay) + triggerAlarm() + else if (detectTime == -1) + for (var/datum/weakref/targetref in getTargetList()) + var/mob/target = targetref.resolve() + if(QDELETED(target) || target.stat == DEAD || (!area_motion && !in_range(src, target))) + //If not part of a monitored area and the camera is not in range or the target is dead + lostTargetRef(targetref) + +/obj/machinery/camera/proc/getTargetList() + if(area_motion) + return area_motion.motionTargets + return localMotionTargets + +/obj/machinery/camera/proc/newTarget(mob/target) + if(isAI(target)) + return FALSE + if (detectTime == 0) + detectTime = world.time // start the clock + var/list/targets = getTargetList() + targets |= WEAKREF(target) + return TRUE + +/obj/machinery/camera/Destroy() + var/area/ai_monitored/A = get_area(src) + localMotionTargets = null + if(istype(A)) + A.motioncameras -= src + cancelAlarm() + return ..() + +/obj/machinery/camera/proc/lostTargetRef(datum/weakref/R) + var/list/targets = getTargetList() + targets -= R + if (targets.len == 0) + cancelAlarm() + +/obj/machinery/camera/proc/cancelAlarm() + if (detectTime == -1) + for (var/i in GLOB.silicon_mobs) + var/mob/living/silicon/aiPlayer = i + if (status) + aiPlayer.cancelAlarm("Motion", get_area(src), src) + detectTime = 0 + return TRUE + +/obj/machinery/camera/proc/triggerAlarm() + if (!detectTime) + return FALSE + for (var/mob/living/silicon/aiPlayer in GLOB.player_list) + if (status) + aiPlayer.triggerAlarm("Motion", get_area(src), list(src), src) + visible_message("A red light flashes on the [src]!") + detectTime = -1 + return TRUE + +/obj/machinery/camera/HasProximity(atom/movable/AM as mob|obj) + // Motion cameras outside of an "ai monitored" area will use this to detect stuff. + if (!area_motion) + if(isliving(AM)) + newTarget(AM) diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm index afcc1fee7c..021232f435 100644 --- a/code/game/machinery/camera/presets.dm +++ b/code/game/machinery/camera/presets.dm @@ -1,89 +1,89 @@ -// PRESETS - -// EMP -/obj/machinery/camera/emp_proof - start_active = TRUE - -/obj/machinery/camera/emp_proof/Initialize() - . = ..() - upgradeEmpProof() - -// X-ray - -/obj/machinery/camera/xray - start_active = TRUE - icon_state = "xraycam" // Thanks to Krutchen for the icons. - -/obj/machinery/camera/xray/Initialize() - . = ..() - upgradeXRay() - -// MOTION -/obj/machinery/camera/motion - start_active = TRUE - name = "motion-sensitive security camera" - -/obj/machinery/camera/motion/Initialize() - . = ..() - upgradeMotion() - -// ALL UPGRADES -/obj/machinery/camera/all - start_active = TRUE - -/obj/machinery/camera/all/Initialize() - . = ..() - upgradeEmpProof() - upgradeXRay() - upgradeMotion() - -// AUTONAME - -/obj/machinery/camera/autoname - var/number = 0 //camera number in area - -//This camera type automatically sets it's name to whatever the area that it's in is called. -/obj/machinery/camera/autoname/Initialize() - ..() - return INITIALIZE_HINT_LATELOAD - -/obj/machinery/camera/autoname/LateInitialize() - . = ..() - number = 1 - var/area/A = get_area(src) - if(A) - for(var/obj/machinery/camera/autoname/C in GLOB.machines) - if(C == src) - continue - var/area/CA = get_area(C) - if(CA.type == A.type) - if(C.number) - number = max(number, C.number+1) - c_tag = "[A.name] #[number]" - -// CHECKS - -/obj/machinery/camera/proc/isEmpProof() - return upgrades & CAMERA_UPGRADE_EMP_PROOF - -/obj/machinery/camera/proc/isXRay() - return upgrades & CAMERA_UPGRADE_XRAY - -/obj/machinery/camera/proc/isMotion() - return upgrades & CAMERA_UPGRADE_MOTION - -// UPGRADE PROCS - -/obj/machinery/camera/proc/upgradeEmpProof() - AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES | EMP_PROTECT_CONTENTS) - assembly.upgrades.Add(new /obj/item/stack/sheet/mineral/plasma(assembly)) - upgrades |= CAMERA_UPGRADE_EMP_PROOF - -/obj/machinery/camera/proc/upgradeXRay() - assembly.upgrades.Add(new /obj/item/analyzer(assembly)) - upgrades |= CAMERA_UPGRADE_XRAY - -// If you are upgrading Motion, and it isn't in the camera's Initialize(), add it to the machines list. -/obj/machinery/camera/proc/upgradeMotion() - assembly.upgrades.Add(new /obj/item/assembly/prox_sensor(assembly)) - upgrades |= CAMERA_UPGRADE_MOTION +// PRESETS + +// EMP +/obj/machinery/camera/emp_proof + start_active = TRUE + +/obj/machinery/camera/emp_proof/Initialize() + . = ..() + upgradeEmpProof() + +// X-ray + +/obj/machinery/camera/xray + start_active = TRUE + icon_state = "xraycam" // Thanks to Krutchen for the icons. + +/obj/machinery/camera/xray/Initialize() + . = ..() + upgradeXRay() + +// MOTION +/obj/machinery/camera/motion + start_active = TRUE + name = "motion-sensitive security camera" + +/obj/machinery/camera/motion/Initialize() + . = ..() + upgradeMotion() + +// ALL UPGRADES +/obj/machinery/camera/all + start_active = TRUE + +/obj/machinery/camera/all/Initialize() + . = ..() + upgradeEmpProof() + upgradeXRay() + upgradeMotion() + +// AUTONAME + +/obj/machinery/camera/autoname + var/number = 0 //camera number in area + +//This camera type automatically sets it's name to whatever the area that it's in is called. +/obj/machinery/camera/autoname/Initialize() + ..() + return INITIALIZE_HINT_LATELOAD + +/obj/machinery/camera/autoname/LateInitialize() + . = ..() + number = 1 + var/area/A = get_area(src) + if(A) + for(var/obj/machinery/camera/autoname/C in GLOB.machines) + if(C == src) + continue + var/area/CA = get_area(C) + if(CA.type == A.type) + if(C.number) + number = max(number, C.number+1) + c_tag = "[A.name] #[number]" + +// CHECKS + +/obj/machinery/camera/proc/isEmpProof() + return upgrades & CAMERA_UPGRADE_EMP_PROOF + +/obj/machinery/camera/proc/isXRay() + return upgrades & CAMERA_UPGRADE_XRAY + +/obj/machinery/camera/proc/isMotion() + return upgrades & CAMERA_UPGRADE_MOTION + +// UPGRADE PROCS + +/obj/machinery/camera/proc/upgradeEmpProof() + AddComponent(/datum/component/empprotection, EMP_PROTECT_SELF | EMP_PROTECT_WIRES | EMP_PROTECT_CONTENTS) + assembly.upgrades.Add(new /obj/item/stack/sheet/mineral/plasma(assembly)) + upgrades |= CAMERA_UPGRADE_EMP_PROOF + +/obj/machinery/camera/proc/upgradeXRay() + assembly.upgrades.Add(new /obj/item/analyzer(assembly)) + upgrades |= CAMERA_UPGRADE_XRAY + +// If you are upgrading Motion, and it isn't in the camera's Initialize(), add it to the machines list. +/obj/machinery/camera/proc/upgradeMotion() + assembly.upgrades.Add(new /obj/item/assembly/prox_sensor(assembly)) + upgrades |= CAMERA_UPGRADE_MOTION diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm index 1dbfe9d055..bf1b84fe5d 100644 --- a/code/game/machinery/camera/tracking.dm +++ b/code/game/machinery/camera/tracking.dm @@ -1,151 +1,151 @@ -/mob/living/silicon/ai/proc/get_camera_list() - var/list/L = list() - for (var/obj/machinery/camera/C in GLOB.cameranet.cameras) - L.Add(C) - - camera_sort(L) - - var/list/T = list() - - for (var/obj/machinery/camera/C in L) - var/list/tempnetwork = C.network&src.network - if (tempnetwork.len) - T[text("[][]", C.c_tag, (C.can_use() ? null : " (Deactivated)"))] = C - - return T - -/mob/living/silicon/ai/proc/show_camera_list() - var/list/cameras = get_camera_list() - var/camera = input(src, "Choose which camera you want to view", "Cameras") as null|anything in cameras - switchCamera(cameras[camera]) - -/datum/trackable - var/initialized = FALSE - var/list/names = list() - var/list/namecounts = list() - var/list/humans = list() - var/list/others = list() - -/mob/living/silicon/ai/proc/trackable_mobs() - track.initialized = TRUE - track.names.Cut() - track.namecounts.Cut() - track.humans.Cut() - track.others.Cut() - - if(usr.stat == DEAD) - return list() - - for(var/i in GLOB.mob_living_list) - var/mob/living/L = i - if(!L.can_track(usr)) - continue - - var/name = L.name - while(name in track.names) - track.namecounts[name]++ - name = text("[] ([])", name, track.namecounts[name]) - track.names.Add(name) - track.namecounts[name] = 1 - - if(ishuman(L)) - track.humans[name] = L - else - track.others[name] = L - - var/list/targets = sortList(track.humans) + sortList(track.others) - - return targets - -/mob/living/silicon/ai/verb/ai_camera_track(target_name in trackable_mobs()) - set name = "track" - set hidden = 1 //Don't display it on the verb lists. This verb exists purely so you can type "track Oldman Robustin" and follow his ass - - if(!target_name) - return - - if(!track.initialized) - trackable_mobs() - - var/mob/target = (isnull(track.humans[target_name]) ? track.others[target_name] : track.humans[target_name]) - - ai_actual_track(target) - -/mob/living/silicon/ai/proc/ai_actual_track(mob/living/target) - if(!istype(target)) - return - var/mob/living/silicon/ai/U = usr - - U.cameraFollow = target - U.tracking = 1 - - if(!target || !target.can_track(usr)) - to_chat(U, "Target is not near any active cameras.") - U.cameraFollow = null - return - - to_chat(U, "Now tracking [target.get_visible_name()] on camera.") - - var/cameraticks = 0 - spawn(0) - while(U.cameraFollow == target) - if(U.cameraFollow == null) - return - - if(!target.can_track(usr)) - U.tracking = 1 - if(!cameraticks) - to_chat(U, "Target is not near any active cameras. Attempting to reacquire...") - cameraticks++ - if(cameraticks > 9) - U.cameraFollow = null - to_chat(U, "Unable to reacquire, cancelling track...") - tracking = 0 - return - else - sleep(10) - continue - - else - cameraticks = 0 - U.tracking = 0 - - if(U.eyeobj) - U.eyeobj.setLoc(get_turf(target)) - - else - view_core() - U.cameraFollow = null - return - - sleep(10) - -/proc/near_camera(mob/living/M) - if (!isturf(M.loc)) - return FALSE - if(issilicon(M)) - var/mob/living/silicon/S = M - if((QDELETED(S.builtInCamera) || !S.builtInCamera.can_use()) && !GLOB.cameranet.checkCameraVis(M)) - return FALSE - else if(!GLOB.cameranet.checkCameraVis(M)) - return FALSE - return TRUE - -/obj/machinery/camera/attack_ai(mob/living/silicon/ai/user) - if (!istype(user)) - return - if (!can_use()) - return - user.switchCamera(src) - -/proc/camera_sort(list/L) - var/obj/machinery/camera/a - var/obj/machinery/camera/b - - for (var/i = L.len, i > 0, i--) - for (var/j = 1 to i - 1) - a = L[j] - b = L[j + 1] - if (sorttext(a.c_tag, b.c_tag) < 0) - L.Swap(j, j + 1) - return L +/mob/living/silicon/ai/proc/get_camera_list() + var/list/L = list() + for (var/obj/machinery/camera/C in GLOB.cameranet.cameras) + L.Add(C) + + camera_sort(L) + + var/list/T = list() + + for (var/obj/machinery/camera/C in L) + var/list/tempnetwork = C.network&src.network + if (tempnetwork.len) + T[text("[][]", C.c_tag, (C.can_use() ? null : " (Deactivated)"))] = C + + return T + +/mob/living/silicon/ai/proc/show_camera_list() + var/list/cameras = get_camera_list() + var/camera = input(src, "Choose which camera you want to view", "Cameras") as null|anything in cameras + switchCamera(cameras[camera]) + +/datum/trackable + var/initialized = FALSE + var/list/names = list() + var/list/namecounts = list() + var/list/humans = list() + var/list/others = list() + +/mob/living/silicon/ai/proc/trackable_mobs() + track.initialized = TRUE + track.names.Cut() + track.namecounts.Cut() + track.humans.Cut() + track.others.Cut() + + if(usr.stat == DEAD) + return list() + + for(var/i in GLOB.mob_living_list) + var/mob/living/L = i + if(!L.can_track(usr)) + continue + + var/name = L.name + while(name in track.names) + track.namecounts[name]++ + name = text("[] ([])", name, track.namecounts[name]) + track.names.Add(name) + track.namecounts[name] = 1 + + if(ishuman(L)) + track.humans[name] = L + else + track.others[name] = L + + var/list/targets = sortList(track.humans) + sortList(track.others) + + return targets + +/mob/living/silicon/ai/verb/ai_camera_track(target_name in trackable_mobs()) + set name = "track" + set hidden = 1 //Don't display it on the verb lists. This verb exists purely so you can type "track Oldman Robustin" and follow his ass + + if(!target_name) + return + + if(!track.initialized) + trackable_mobs() + + var/mob/target = (isnull(track.humans[target_name]) ? track.others[target_name] : track.humans[target_name]) + + ai_actual_track(target) + +/mob/living/silicon/ai/proc/ai_actual_track(mob/living/target) + if(!istype(target)) + return + var/mob/living/silicon/ai/U = usr + + U.cameraFollow = target + U.tracking = 1 + + if(!target || !target.can_track(usr)) + to_chat(U, "Target is not near any active cameras.") + U.cameraFollow = null + return + + to_chat(U, "Now tracking [target.get_visible_name()] on camera.") + + var/cameraticks = 0 + spawn(0) + while(U.cameraFollow == target) + if(U.cameraFollow == null) + return + + if(!target.can_track(usr)) + U.tracking = 1 + if(!cameraticks) + to_chat(U, "Target is not near any active cameras. Attempting to reacquire...") + cameraticks++ + if(cameraticks > 9) + U.cameraFollow = null + to_chat(U, "Unable to reacquire, cancelling track...") + tracking = 0 + return + else + sleep(10) + continue + + else + cameraticks = 0 + U.tracking = 0 + + if(U.eyeobj) + U.eyeobj.setLoc(get_turf(target)) + + else + view_core() + U.cameraFollow = null + return + + sleep(10) + +/proc/near_camera(mob/living/M) + if (!isturf(M.loc)) + return FALSE + if(issilicon(M)) + var/mob/living/silicon/S = M + if((QDELETED(S.builtInCamera) || !S.builtInCamera.can_use()) && !GLOB.cameranet.checkCameraVis(M)) + return FALSE + else if(!GLOB.cameranet.checkCameraVis(M)) + return FALSE + return TRUE + +/obj/machinery/camera/attack_ai(mob/living/silicon/ai/user) + if (!istype(user)) + return + if (!can_use()) + return + user.switchCamera(src) + +/proc/camera_sort(list/L) + var/obj/machinery/camera/a + var/obj/machinery/camera/b + + for (var/i = L.len, i > 0, i--) + for (var/j = 1 to i - 1) + a = L[j] + b = L[j + 1] + if (sorttext(a.c_tag, b.c_tag) < 0) + L.Swap(j, j + 1) + return L diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index 1c0635fd3d..a982411692 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -1,130 +1,130 @@ -/obj/machinery/cell_charger - name = "cell charger" - desc = "It charges power cells." - icon = 'icons/obj/power.dmi' - icon_state = "ccharger" - use_power = IDLE_POWER_USE - idle_power_usage = 5 - active_power_usage = 60 - power_channel = EQUIP - circuit = /obj/item/circuitboard/machine/cell_charger - pass_flags = PASSTABLE - var/obj/item/stock_parts/cell/charging = null - var/chargelevel = -1 - var/charge_rate = 500 - -/obj/machinery/cell_charger/update_icon() - cut_overlays() - if(charging) - add_overlay(image(charging.icon, charging.icon_state)) - add_overlay("ccharger-on") - if(!(stat & (BROKEN|NOPOWER))) - var/newlevel = round(charging.percent() * 4 / 100) - chargelevel = newlevel - add_overlay("ccharger-o[newlevel]") - -/obj/machinery/cell_charger/examine(mob/user) - . = ..() - . += "There's [charging ? "a" : "no"] cell in the charger." - if(charging) - . += "Current charge: [round(charging.percent(), 1)]%." - -/obj/machinery/cell_charger/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/stock_parts/cell) && !panel_open) - if(stat & BROKEN) - to_chat(user, "[src] is broken!") - return - if(!anchored) - to_chat(user, "[src] isn't attached to the ground!") - return - if(charging) - to_chat(user, "There is already a cell in the charger!") - return - else - var/area/a = loc.loc // Gets our locations location, like a dream within a dream - if(!isarea(a)) - return - if(a.power_equip == 0) // There's no APC in this area, don't try to cheat power! - to_chat(user, "[src] blinks red as you try to insert the cell!") - return - if(!user.transferItemToLoc(W,src)) - return - - charging = W - user.visible_message("[user] inserts a cell into [src].", "You insert a cell into [src].") - chargelevel = -1 - update_icon() - else - if(!charging && default_deconstruction_screwdriver(user, icon_state, icon_state, W)) - return - if(default_deconstruction_crowbar(W)) - return - if(!charging && default_unfasten_wrench(user, W)) - return - return ..() - -/obj/machinery/cell_charger/deconstruct() - if(charging) - charging.forceMove(drop_location()) - return ..() - -/obj/machinery/cell_charger/Destroy() - QDEL_NULL(charging) - return ..() - -/obj/machinery/cell_charger/proc/removecell() - charging.update_icon() - charging = null - chargelevel = -1 - update_icon() - -/obj/machinery/cell_charger/attack_hand(mob/user) - . = ..() - if(.) - return - if(!charging) - return - - user.put_in_hands(charging) - charging.add_fingerprint(user) - - user.visible_message("[user] removes [charging] from [src].", "You remove [charging] from [src].") - - removecell() - -/obj/machinery/cell_charger/attack_tk(mob/user) - if(!charging) - return - - charging.forceMove(loc) - to_chat(user, "You telekinetically remove [charging] from [src].") - - removecell() - -/obj/machinery/cell_charger/attack_ai(mob/user) - return - -/obj/machinery/cell_charger/emp_act(severity) - . = ..() - - if(stat & (BROKEN|NOPOWER) || . & EMP_PROTECT_CONTENTS) - return - - if(charging) - charging.emp_act(severity) - -/obj/machinery/cell_charger/RefreshParts() - charge_rate = 500 - for(var/obj/item/stock_parts/capacitor/C in component_parts) - charge_rate *= C.rating - -/obj/machinery/cell_charger/process() - if(!charging || !anchored || (stat & (BROKEN|NOPOWER))) - return - - if(charging.percent() >= 100) - return - use_power(charge_rate) - charging.give(charge_rate) //this is 2558, efficient batteries exist - - update_icon() +/obj/machinery/cell_charger + name = "cell charger" + desc = "It charges power cells." + icon = 'icons/obj/power.dmi' + icon_state = "ccharger" + use_power = IDLE_POWER_USE + idle_power_usage = 5 + active_power_usage = 60 + power_channel = EQUIP + circuit = /obj/item/circuitboard/machine/cell_charger + pass_flags = PASSTABLE + var/obj/item/stock_parts/cell/charging = null + var/chargelevel = -1 + var/charge_rate = 500 + +/obj/machinery/cell_charger/update_icon() + cut_overlays() + if(charging) + add_overlay(image(charging.icon, charging.icon_state)) + add_overlay("ccharger-on") + if(!(stat & (BROKEN|NOPOWER))) + var/newlevel = round(charging.percent() * 4 / 100) + chargelevel = newlevel + add_overlay("ccharger-o[newlevel]") + +/obj/machinery/cell_charger/examine(mob/user) + . = ..() + . += "There's [charging ? "a" : "no"] cell in the charger." + if(charging) + . += "Current charge: [round(charging.percent(), 1)]%." + +/obj/machinery/cell_charger/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/stock_parts/cell) && !panel_open) + if(stat & BROKEN) + to_chat(user, "[src] is broken!") + return + if(!anchored) + to_chat(user, "[src] isn't attached to the ground!") + return + if(charging) + to_chat(user, "There is already a cell in the charger!") + return + else + var/area/a = loc.loc // Gets our locations location, like a dream within a dream + if(!isarea(a)) + return + if(a.power_equip == 0) // There's no APC in this area, don't try to cheat power! + to_chat(user, "[src] blinks red as you try to insert the cell!") + return + if(!user.transferItemToLoc(W,src)) + return + + charging = W + user.visible_message("[user] inserts a cell into [src].", "You insert a cell into [src].") + chargelevel = -1 + update_icon() + else + if(!charging && default_deconstruction_screwdriver(user, icon_state, icon_state, W)) + return + if(default_deconstruction_crowbar(W)) + return + if(!charging && default_unfasten_wrench(user, W)) + return + return ..() + +/obj/machinery/cell_charger/deconstruct() + if(charging) + charging.forceMove(drop_location()) + return ..() + +/obj/machinery/cell_charger/Destroy() + QDEL_NULL(charging) + return ..() + +/obj/machinery/cell_charger/proc/removecell() + charging.update_icon() + charging = null + chargelevel = -1 + update_icon() + +/obj/machinery/cell_charger/attack_hand(mob/user) + . = ..() + if(.) + return + if(!charging) + return + + user.put_in_hands(charging) + charging.add_fingerprint(user) + + user.visible_message("[user] removes [charging] from [src].", "You remove [charging] from [src].") + + removecell() + +/obj/machinery/cell_charger/attack_tk(mob/user) + if(!charging) + return + + charging.forceMove(loc) + to_chat(user, "You telekinetically remove [charging] from [src].") + + removecell() + +/obj/machinery/cell_charger/attack_ai(mob/user) + return + +/obj/machinery/cell_charger/emp_act(severity) + . = ..() + + if(stat & (BROKEN|NOPOWER) || . & EMP_PROTECT_CONTENTS) + return + + if(charging) + charging.emp_act(severity) + +/obj/machinery/cell_charger/RefreshParts() + charge_rate = 500 + for(var/obj/item/stock_parts/capacitor/C in component_parts) + charge_rate *= C.rating + +/obj/machinery/cell_charger/process() + if(!charging || !anchored || (stat & (BROKEN|NOPOWER))) + return + + if(charging.percent() >= 100) + return + use_power(charge_rate) + charging.give(charge_rate) //this is 2558, efficient batteries exist + + update_icon() diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 97b260f3bf..413621d8b9 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -1,556 +1,556 @@ -//Cloning revival method. -//The pod handles the actual cloning while the computer manages the clone profiles - -//Potential replacement for genetics revives or something I dunno (?) - -#define CLONE_INITIAL_DAMAGE 150 //Clones in clonepods start with 150 cloneloss damage and 150 brainloss damage, thats just logical -#define MINIMUM_HEAL_LEVEL 40 - -#define SPEAK(message) radio.talk_into(src, message, radio_channel) - -/obj/machinery/clonepod - name = "cloning pod" - desc = "An electronically-lockable pod for growing organic tissue." - density = TRUE - icon = 'icons/obj/machines/cloning.dmi' - icon_state = "pod_0" - req_access = list(ACCESS_CLONING) //FOR PREMATURE UNLOCKING. - verb_say = "states" - circuit = /obj/item/circuitboard/machine/clonepod - - var/heal_level //The clone is released once its health reaches this level. - var/obj/machinery/computer/cloning/connected = null //So we remember the connected clone machine. - var/mess = FALSE //Need to clean out it if it's full of exploded clone. - var/attempting = FALSE //One clone attempt at a time thanks - var/speed_coeff - var/efficiency - - var/datum/mind/clonemind - var/grab_ghost_when = CLONER_MATURE_CLONE - - var/internal_radio = TRUE - var/obj/item/radio/radio - var/radio_key = /obj/item/encryptionkey/headset_med - var/radio_channel = RADIO_CHANNEL_MEDICAL - - var/obj/effect/countdown/clonepod/countdown - - var/list/unattached_flesh - var/flesh_number = 0 - -/obj/machinery/clonepod/Initialize() - . = ..() - - countdown = new(src) - - if(internal_radio) - radio = new(src) - radio.keyslot = new radio_key - radio.subspace_transmission = TRUE - radio.canhear_range = 0 - radio.recalculateChannels() - - update_icon() - -/obj/machinery/clonepod/Destroy() - go_out() - QDEL_NULL(radio) - QDEL_NULL(countdown) - if(connected) - connected.DetachCloner(src) - QDEL_LIST(unattached_flesh) - . = ..() - -/obj/machinery/clonepod/RefreshParts() - speed_coeff = 0 - efficiency = 0 - for(var/obj/item/stock_parts/scanning_module/S in component_parts) - efficiency += S.rating - for(var/obj/item/stock_parts/manipulator/P in component_parts) - speed_coeff += P.rating - heal_level = (efficiency * 15) + 10 - if(heal_level < MINIMUM_HEAL_LEVEL) - heal_level = MINIMUM_HEAL_LEVEL - if(heal_level > 100) - heal_level = 100 - -//The return of data disks?? Just for transferring between genetics machine/cloning machine. -//TO-DO: Make the genetics machine accept them. -/obj/item/disk/data - name = "cloning data disk" - icon_state = "datadisk0" //Gosh I hope syndies don't mistake them for the nuke disk. - var/list/fields = list() - var/read_only = 0 //Well,it's still a floppy disk - -//Disk stuff. -/obj/item/disk/data/Initialize() - . = ..() - icon_state = "datadisk[rand(0,6)]" - add_overlay("datadisk_gene") - -/obj/item/disk/data/attack_self(mob/user) - read_only = !read_only - to_chat(user, "You flip the write-protect tab to [read_only ? "protected" : "unprotected"].") - -/obj/item/disk/data/examine(mob/user) - . = ..() - . += "The write-protect tab is set to [read_only ? "protected" : "unprotected"]." - - -//Clonepod - -/obj/machinery/clonepod/examine(mob/user) - . = ..() - var/mob/living/mob_occupant = occupant - if(mess) - . += "It's filled with blood and viscera. You swear you can see it moving..." - if(is_operational() && mob_occupant) - if(mob_occupant.stat != DEAD) - . += "Current clone cycle is [round(get_completion())]% complete." - -/obj/machinery/clonepod/return_air() - // We want to simulate the clone not being in contact with - // the atmosphere, so we'll put them in a constant pressure - // nitrogen. They don't need to breathe while cloning anyway. - var/static/datum/gas_mixture/immutable/cloner/GM //global so that there's only one instance made for all cloning pods - if(!GM) - GM = new - return GM - -/obj/machinery/clonepod/proc/get_completion() - . = FALSE - var/mob/living/mob_occupant = occupant - if(mob_occupant) - . = (100 * ((mob_occupant.health + 100) / (heal_level + 100))) - -/obj/machinery/clonepod/attack_ai(mob/user) - return examine(user) - -//Start growing a human clone in the pod! -/obj/machinery/clonepod/proc/growclone(ckey, clonename, ui, se, mindref, datum/species/mrace, list/features, factions, list/quirks) - if(panel_open) - return FALSE - if(mess || attempting) - return FALSE - clonemind = locate(mindref) in SSticker.minds - if(!istype(clonemind)) //not a mind - return FALSE - if(!QDELETED(clonemind.current)) - if(clonemind.current.stat != DEAD) //mind is associated with a non-dead body - return FALSE - if(clonemind.current.suiciding) // Mind is associated with a body that is suiciding. - return FALSE - if(clonemind.active) //somebody is using that mind - if( ckey(clonemind.key)!=ckey ) - return FALSE - else - // get_ghost() will fail if they're unable to reenter their body - var/mob/dead/observer/G = clonemind.get_ghost() - if(!G) - return FALSE - if(G.suiciding) // The ghost came from a body that is suiciding. - return FALSE - if(clonemind.damnation_type) //Can't clone the damned. - INVOKE_ASYNC(src, .proc/horrifyingsound) - mess = TRUE - update_icon() - return FALSE - if(isvamp(clonemind)) //If the mind is a bloodsucker - return FALSE - - attempting = TRUE //One at a time!! - countdown.start() - - var/mob/living/carbon/human/H = new /mob/living/carbon/human(src) - - H.hardset_dna(ui, se, H.real_name, null, mrace, features) - - if(prob(50 - efficiency*10)) //Chance to give a bad mutation. - H.randmutb() //100% bad mutation. Can be cured with mutadone. - - H.silent = 20 //Prevents an extreme edge case where clones could speak if they said something at exactly the right moment. - occupant = H - - if(!clonename) //to prevent null names - clonename = "clone ([rand(1,999)])" - H.real_name = clonename - - //Get the clone body ready - maim_clone(H) - ADD_TRAIT(H, TRAIT_STABLEHEART, CLONING_POD_TRAIT) - ADD_TRAIT(H, TRAIT_STABLELIVER, CLONING_POD_TRAIT) - ADD_TRAIT(H, TRAIT_EMOTEMUTE, CLONING_POD_TRAIT) - ADD_TRAIT(H, TRAIT_MUTE, CLONING_POD_TRAIT) - ADD_TRAIT(H, TRAIT_NOBREATH, CLONING_POD_TRAIT) - ADD_TRAIT(H, TRAIT_NOCRITDAMAGE, CLONING_POD_TRAIT) - H.Unconscious(80) - - clonemind.transfer_to(H) - - if(grab_ghost_when == CLONER_FRESH_CLONE) - H.grab_ghost() - to_chat(H, "Consciousness slowly creeps over you as your body regenerates.
      So this is what cloning feels like?
      ") - - if(grab_ghost_when == CLONER_MATURE_CLONE) - H.ghostize(TRUE) //Only does anything if they were still in their old body and not already a ghost - to_chat(H.get_ghost(TRUE), "Your body is beginning to regenerate in a cloning pod. You will become conscious when it is complete.") - - if(H) - H.faction |= factions - - for(var/V in quirks) - var/datum/quirk/Q = new V(H) - Q.on_clone(quirks[V]) - - H.set_cloned_appearance() - H.give_genitals(TRUE) - - H.suiciding = FALSE - attempting = FALSE - return TRUE - -//Grow clones to maturity then kick them out. FREELOADERS -/obj/machinery/clonepod/process() - var/mob/living/mob_occupant = occupant - - if(!is_operational()) //Autoeject if power is lost - if(mob_occupant) - go_out() - mob_occupant.apply_vore_prefs() - connected_message("Clone Ejected: Loss of power.") - - else if(mob_occupant && (mob_occupant.loc == src)) - if((mob_occupant.stat == DEAD) || (mob_occupant.suiciding) || mob_occupant.hellbound) //Autoeject corpses and suiciding dudes. - connected_message("Clone Rejected: Deceased.") - if(internal_radio) - SPEAK("The cloning has been \ - aborted due to unrecoverable tissue failure.") - go_out() - mob_occupant.apply_vore_prefs() - - else if(mob_occupant.cloneloss > (100 - heal_level)) - mob_occupant.Unconscious(80) - var/dmg_mult = CONFIG_GET(number/damage_multiplier) - //Slowly get that clone healed and finished. - mob_occupant.adjustCloneLoss(-((speed_coeff / 2) * dmg_mult)) - var/progress = CLONE_INITIAL_DAMAGE - mob_occupant.getCloneLoss() - // To avoid the default cloner making incomplete clones - progress += (100 - MINIMUM_HEAL_LEVEL) - var/milestone = CLONE_INITIAL_DAMAGE / flesh_number - var/installed = flesh_number - unattached_flesh.len - - if((progress / milestone) >= installed) - // attach some flesh - var/obj/item/I = pick_n_take(unattached_flesh) - if(isorgan(I)) - var/obj/item/organ/O = I - O.organ_flags &= ~ORGAN_FROZEN - O.Insert(mob_occupant) - else if(isbodypart(I)) - var/obj/item/bodypart/BP = I - BP.attach_limb(mob_occupant) - - //Premature clones may have brain damage. - mob_occupant.adjustOrganLoss(ORGAN_SLOT_BRAIN, -((speed_coeff / 2) * dmg_mult)) - - use_power(7500) //This might need tweaking. - - else if((mob_occupant.cloneloss <= (100 - heal_level))) - connected_message("Cloning Process Complete.") - if(internal_radio) - SPEAK("The cloning cycle is complete.") - - // If the cloner is upgraded to debugging high levels, sometimes - // organs and limbs can be missing. - for(var/i in unattached_flesh) - if(isorgan(i)) - var/obj/item/organ/O = i - O.organ_flags &= ~ORGAN_FROZEN - O.Insert(mob_occupant) - else if(isbodypart(i)) - var/obj/item/bodypart/BP = i - BP.attach_limb(mob_occupant) - - go_out() - mob_occupant.apply_vore_prefs() - - else if (!mob_occupant || mob_occupant.loc != src) - occupant = null - use_power(200) - - update_icon() - -//Let's unlock this early I guess. Might be too early, needs tweaking. -/obj/machinery/clonepod/attackby(obj/item/W, mob/user, params) - if(!(occupant || mess)) - if(default_deconstruction_screwdriver(user, "[icon_state]_maintenance", "[initial(icon_state)]",W)) - return - - if(default_deconstruction_crowbar(W)) - return - - if(istype(W, /obj/item/multitool)) - var/obj/item/multitool/P = W - - if(istype(P.buffer, /obj/machinery/computer/cloning)) - 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/computer/cloning/comp = P.buffer - if(connected) - connected.DetachCloner(src) - comp.AttachCloner(src) - else - P.buffer = src - to_chat(user, "-% Successfully stored [REF(P.buffer)] [P.buffer.name] in buffer %-") - return - - var/mob/living/mob_occupant = occupant - if(W.GetID()) - if(!check_access(W)) - to_chat(user, "Access Denied.") - return - if(!(mob_occupant || mess)) - to_chat(user, "Error: Pod has no occupant.") - return - else - connected_message("Emergency Ejection") - SPEAK("An emergency ejection of the current clone has occurred. Survival not guaranteed.") - to_chat(user, "You force an emergency ejection. ") - go_out() - mob_occupant.apply_vore_prefs() - else - return ..() - -/obj/machinery/clonepod/emag_act(mob/user) - . = ..() - if(!occupant) - return - to_chat(user, "You corrupt the genetic compiler.") - malfunction() - return TRUE - -//Put messages in the connected computer's temp var for display. -/obj/machinery/clonepod/proc/connected_message(message) - if ((isnull(connected)) || (!istype(connected, /obj/machinery/computer/cloning))) - return FALSE - if (!message) - return FALSE - - connected.temp = message - connected.updateUsrDialog() - return TRUE - -/obj/machinery/clonepod/proc/go_out() - countdown.stop() - var/mob/living/mob_occupant = occupant - var/turf/T = get_turf(src) - - if(mess) //Clean that mess and dump those gibs! - for(var/obj/fl in unattached_flesh) - fl.forceMove(T) - if(istype(fl, /obj/item/organ)) - var/obj/item/organ/O = fl - O.organ_flags &= ~ORGAN_FROZEN - unattached_flesh.Cut() - mess = FALSE - if(mob_occupant) - mob_occupant.spawn_gibs() - audible_message("You hear a splat.") - update_icon() - return - - if(!mob_occupant) - return - - REMOVE_TRAIT(mob_occupant, TRAIT_STABLEHEART, CLONING_POD_TRAIT) - REMOVE_TRAIT(mob_occupant, TRAIT_STABLELIVER, CLONING_POD_TRAIT) - REMOVE_TRAIT(mob_occupant, TRAIT_EMOTEMUTE, CLONING_POD_TRAIT) - REMOVE_TRAIT(mob_occupant, TRAIT_MUTE, CLONING_POD_TRAIT) - REMOVE_TRAIT(mob_occupant, TRAIT_NOCRITDAMAGE, CLONING_POD_TRAIT) - REMOVE_TRAIT(mob_occupant, TRAIT_NOBREATH, CLONING_POD_TRAIT) - - if(grab_ghost_when == CLONER_MATURE_CLONE) - mob_occupant.grab_ghost() - to_chat(occupant, "There is a bright flash!
      You feel like a new being.
      ") - mob_occupant.flash_act() - - occupant.forceMove(T) - update_icon() - mob_occupant.domutcheck(1) //Waiting until they're out before possible monkeyizing. The 1 argument forces powers to manifest. - for(var/fl in unattached_flesh) - qdel(fl) - unattached_flesh.Cut() - - occupant = null - -/obj/machinery/clonepod/proc/malfunction() - var/mob/living/mob_occupant = occupant - if(mob_occupant) - connected_message("Critical Error!") - SPEAK("Critical error! Please contact a Thinktronic Systems \ - technician, as your warranty may be affected.") - mess = TRUE - maim_clone(mob_occupant) //Remove every bit that's grown back so far to drop later, also destroys bits that haven't grown yet - update_icon() - if(mob_occupant.mind != clonemind) - clonemind.transfer_to(mob_occupant) - mob_occupant.grab_ghost() // We really just want to make you suffer. - flash_color(mob_occupant, flash_color="#960000", flash_time=100) - to_chat(mob_occupant, "Agony blazes across your consciousness as your body is torn apart.
      Is this what dying is like? Yes it is.
      ") - playsound(src.loc, 'sound/machines/warning-buzzer.ogg', 50, 0) - SEND_SOUND(mob_occupant, sound('sound/hallucinations/veryfar_noise.ogg',0,1,50)) - QDEL_IN(mob_occupant, 40) - -/obj/machinery/clonepod/relaymove(mob/user) - container_resist(user) - -/obj/machinery/clonepod/container_resist(mob/living/user) - if(user.stat == CONSCIOUS) - go_out() - -/obj/machinery/clonepod/emp_act(severity) - . = ..() - if (!(. & EMP_PROTECT_SELF)) - var/mob/living/mob_occupant = occupant - if(mob_occupant && prob(100/(severity*efficiency))) - connected_message(Gibberish("EMP-caused Accidental Ejection", 0)) - SPEAK(Gibberish("Exposure to electromagnetic fields has caused the ejection of, ERROR: John Doe, prematurely." ,0)) - mob_occupant.apply_vore_prefs() - go_out() - -/obj/machinery/clonepod/ex_act(severity, target) - ..() - if(!QDELETED(src)) - go_out() - -/obj/machinery/clonepod/handle_atom_del(atom/A) - if(A == occupant) - occupant = null - countdown.stop() - -/obj/machinery/clonepod/proc/horrifyingsound() - for(var/i in 1 to 5) - playsound(loc,pick('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg'), 100, rand(0.95,1.05)) - sleep(1) - sleep(10) - playsound(loc,'sound/hallucinations/wail.ogg',100,1) - -/obj/machinery/clonepod/deconstruct(disassembled = TRUE) - if(occupant) - go_out() - ..() - -/obj/machinery/clonepod/proc/maim_clone(mob/living/carbon/human/H) - if(!unattached_flesh) - unattached_flesh = list() - else - for(var/fl in unattached_flesh) - qdel(fl) - unattached_flesh.Cut() - - H.setCloneLoss(CLONE_INITIAL_DAMAGE) //Yeah, clones start with very low health, not with random, because why would they start with random health - //H.setOrganLoss(ORGAN_SLOT_BRAIN, CLONE_INITIAL_DAMAGE) - // In addition to being cellularly damaged and having barely any - - // brain function, they also have no limbs or internal organs. - - if(!HAS_TRAIT(H, TRAIT_NODISMEMBER)) - var/static/list/zones = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) - for(var/zone in zones) - var/obj/item/bodypart/BP = H.get_bodypart(zone) - if(BP) - BP.drop_limb() - BP.forceMove(src) - unattached_flesh += BP - - for(var/o in H.internal_organs) - var/obj/item/organ/organ = o - if(!istype(organ) || (organ.organ_flags & ORGAN_VITAL)) - continue - organ.organ_flags |= ORGAN_FROZEN - organ.Remove(H, special=TRUE) - organ.forceMove(src) - unattached_flesh += organ - - flesh_number = unattached_flesh.len - -/obj/machinery/clonepod/update_icon() - cut_overlays() - - if(mess) - icon_state = "pod_g" - var/image/gib1 = image(CRYOMOBS, "gibup") - var/image/gib2 = image(CRYOMOBS, "gibdown") - gib1.pixel_y = 27 + round(sin(world.time) * 3) - gib1.pixel_x = round(sin(world.time * 3)) - gib2.pixel_y = 27 + round(cos(world.time) * 3) - gib2.pixel_x = round(cos(world.time * 3)) - add_overlay(gib2) - add_overlay(gib1) - add_overlay("cover-on") - - else if(occupant) - icon_state = "pod_1" - - var/image/occupant_overlay - var/completion = (flesh_number - unattached_flesh.len) / flesh_number - - if(unattached_flesh.len <= 0) - occupant_overlay = image(occupant.icon, occupant.icon_state) - occupant_overlay.copy_overlays(occupant) - else - occupant_overlay = image(CRYOMOBS, "clone_meat") - var/matrix/tform = matrix() - tform.Scale(completion) - tform.Turn(cos(world.time * 2) * 3) - occupant_overlay.transform = tform - occupant_overlay.appearance_flags = 0 - - occupant_overlay.dir = SOUTH - occupant_overlay.pixel_y = 27 + round(sin(world.time) * 3) - occupant_overlay.pixel_x = round(sin(world.time * 3)) - - add_overlay(occupant_overlay) - add_overlay("cover-on") - else - icon_state = "pod_0" - - if(panel_open) - icon_state = "pod_0_maintenance" - - add_overlay("panel") - -/* - * Manual -- A big ol' manual. - */ - -/obj/item/paper/guides/jobs/medical/cloning - name = "paper - 'H-87 Cloning Apparatus Manual" - info = {"

      Getting Started

      - Congratulations, your station has purchased the H-87 industrial cloning device!
      - Using the H-87 is almost as simple as brain surgery! Simply insert the target humanoid into the scanning chamber and select the scan option to create a new profile!
      - That's all there is to it!
      - Notice, cloning system cannot scan inorganic life or small primates. Scan may fail if subject has suffered extreme brain damage.
      -

      Clone profiles may be viewed through the profiles menu. Scanning implants a complementary HEALTH MONITOR IMPLANT into the subject, which may be viewed from each profile. - Profile Deletion has been restricted to \[Station Head\] level access.

      -

      Cloning from a profile

      - Cloning is as simple as pressing the CLONE option at the bottom of the desired profile.
      - Per your company's EMPLOYEE PRIVACY RIGHTS agreement, the H-87 has been blocked from cloning crewmembers while they are still alive.
      -
      -

      The provided CLONEPOD SYSTEM will produce the desired clone. Standard clone maturation times (With SPEEDCLONE technology) are roughly 90 seconds. - The cloning pod may be unlocked early with any \[Medical Researcher\] ID after initial maturation is complete.


      - Please note that resulting clones may have a small DEVELOPMENTAL DEFECT as a result of genetic drift.
      -

      Profile Management

      -

      The H-87 (as well as your station's standard genetics machine) can accept STANDARD DATA DISKETTES. - These diskettes are used to transfer genetic information between machines and profiles. - A load/save dialog will become available in each profile if a disk is inserted.


      - A good diskette is a great way to counter aforementioned genetic drift!
      -
      - This technology produced under license from Thinktronic Systems, LTD."} - -#undef CLONE_INITIAL_DAMAGE -#undef SPEAK -#undef MINIMUM_HEAL_LEVEL +//Cloning revival method. +//The pod handles the actual cloning while the computer manages the clone profiles + +//Potential replacement for genetics revives or something I dunno (?) + +#define CLONE_INITIAL_DAMAGE 150 //Clones in clonepods start with 150 cloneloss damage and 150 brainloss damage, thats just logical +#define MINIMUM_HEAL_LEVEL 40 + +#define SPEAK(message) radio.talk_into(src, message, radio_channel) + +/obj/machinery/clonepod + name = "cloning pod" + desc = "An electronically-lockable pod for growing organic tissue." + density = TRUE + icon = 'icons/obj/machines/cloning.dmi' + icon_state = "pod_0" + req_access = list(ACCESS_CLONING) //FOR PREMATURE UNLOCKING. + verb_say = "states" + circuit = /obj/item/circuitboard/machine/clonepod + + var/heal_level //The clone is released once its health reaches this level. + var/obj/machinery/computer/cloning/connected = null //So we remember the connected clone machine. + var/mess = FALSE //Need to clean out it if it's full of exploded clone. + var/attempting = FALSE //One clone attempt at a time thanks + var/speed_coeff + var/efficiency + + var/datum/mind/clonemind + var/grab_ghost_when = CLONER_MATURE_CLONE + + var/internal_radio = TRUE + var/obj/item/radio/radio + var/radio_key = /obj/item/encryptionkey/headset_med + var/radio_channel = RADIO_CHANNEL_MEDICAL + + var/obj/effect/countdown/clonepod/countdown + + var/list/unattached_flesh + var/flesh_number = 0 + +/obj/machinery/clonepod/Initialize() + . = ..() + + countdown = new(src) + + if(internal_radio) + radio = new(src) + radio.keyslot = new radio_key + radio.subspace_transmission = TRUE + radio.canhear_range = 0 + radio.recalculateChannels() + + update_icon() + +/obj/machinery/clonepod/Destroy() + go_out() + QDEL_NULL(radio) + QDEL_NULL(countdown) + if(connected) + connected.DetachCloner(src) + QDEL_LIST(unattached_flesh) + . = ..() + +/obj/machinery/clonepod/RefreshParts() + speed_coeff = 0 + efficiency = 0 + for(var/obj/item/stock_parts/scanning_module/S in component_parts) + efficiency += S.rating + for(var/obj/item/stock_parts/manipulator/P in component_parts) + speed_coeff += P.rating + heal_level = (efficiency * 15) + 10 + if(heal_level < MINIMUM_HEAL_LEVEL) + heal_level = MINIMUM_HEAL_LEVEL + if(heal_level > 100) + heal_level = 100 + +//The return of data disks?? Just for transferring between genetics machine/cloning machine. +//TO-DO: Make the genetics machine accept them. +/obj/item/disk/data + name = "cloning data disk" + icon_state = "datadisk0" //Gosh I hope syndies don't mistake them for the nuke disk. + var/list/fields = list() + var/read_only = 0 //Well,it's still a floppy disk + +//Disk stuff. +/obj/item/disk/data/Initialize() + . = ..() + icon_state = "datadisk[rand(0,6)]" + add_overlay("datadisk_gene") + +/obj/item/disk/data/attack_self(mob/user) + read_only = !read_only + to_chat(user, "You flip the write-protect tab to [read_only ? "protected" : "unprotected"].") + +/obj/item/disk/data/examine(mob/user) + . = ..() + . += "The write-protect tab is set to [read_only ? "protected" : "unprotected"]." + + +//Clonepod + +/obj/machinery/clonepod/examine(mob/user) + . = ..() + var/mob/living/mob_occupant = occupant + if(mess) + . += "It's filled with blood and viscera. You swear you can see it moving..." + if(is_operational() && mob_occupant) + if(mob_occupant.stat != DEAD) + . += "Current clone cycle is [round(get_completion())]% complete." + +/obj/machinery/clonepod/return_air() + // We want to simulate the clone not being in contact with + // the atmosphere, so we'll put them in a constant pressure + // nitrogen. They don't need to breathe while cloning anyway. + var/static/datum/gas_mixture/immutable/cloner/GM //global so that there's only one instance made for all cloning pods + if(!GM) + GM = new + return GM + +/obj/machinery/clonepod/proc/get_completion() + . = FALSE + var/mob/living/mob_occupant = occupant + if(mob_occupant) + . = (100 * ((mob_occupant.health + 100) / (heal_level + 100))) + +/obj/machinery/clonepod/attack_ai(mob/user) + return examine(user) + +//Start growing a human clone in the pod! +/obj/machinery/clonepod/proc/growclone(ckey, clonename, ui, se, mindref, datum/species/mrace, list/features, factions, list/quirks) + if(panel_open) + return FALSE + if(mess || attempting) + return FALSE + clonemind = locate(mindref) in SSticker.minds + if(!istype(clonemind)) //not a mind + return FALSE + if(!QDELETED(clonemind.current)) + if(clonemind.current.stat != DEAD) //mind is associated with a non-dead body + return FALSE + if(clonemind.current.suiciding) // Mind is associated with a body that is suiciding. + return FALSE + if(clonemind.active) //somebody is using that mind + if( ckey(clonemind.key)!=ckey ) + return FALSE + else + // get_ghost() will fail if they're unable to reenter their body + var/mob/dead/observer/G = clonemind.get_ghost() + if(!G) + return FALSE + if(G.suiciding) // The ghost came from a body that is suiciding. + return FALSE + if(clonemind.damnation_type) //Can't clone the damned. + INVOKE_ASYNC(src, .proc/horrifyingsound) + mess = TRUE + update_icon() + return FALSE + if(isvamp(clonemind)) //If the mind is a bloodsucker + return FALSE + + attempting = TRUE //One at a time!! + countdown.start() + + var/mob/living/carbon/human/H = new /mob/living/carbon/human(src) + + H.hardset_dna(ui, se, H.real_name, null, mrace, features) + + if(prob(50 - efficiency*10)) //Chance to give a bad mutation. + H.randmutb() //100% bad mutation. Can be cured with mutadone. + + H.silent = 20 //Prevents an extreme edge case where clones could speak if they said something at exactly the right moment. + occupant = H + + if(!clonename) //to prevent null names + clonename = "clone ([rand(1,999)])" + H.real_name = clonename + + //Get the clone body ready + maim_clone(H) + ADD_TRAIT(H, TRAIT_STABLEHEART, CLONING_POD_TRAIT) + ADD_TRAIT(H, TRAIT_STABLELIVER, CLONING_POD_TRAIT) + ADD_TRAIT(H, TRAIT_EMOTEMUTE, CLONING_POD_TRAIT) + ADD_TRAIT(H, TRAIT_MUTE, CLONING_POD_TRAIT) + ADD_TRAIT(H, TRAIT_NOBREATH, CLONING_POD_TRAIT) + ADD_TRAIT(H, TRAIT_NOCRITDAMAGE, CLONING_POD_TRAIT) + H.Unconscious(80) + + clonemind.transfer_to(H) + + if(grab_ghost_when == CLONER_FRESH_CLONE) + H.grab_ghost() + to_chat(H, "Consciousness slowly creeps over you as your body regenerates.
      So this is what cloning feels like?
      ") + + if(grab_ghost_when == CLONER_MATURE_CLONE) + H.ghostize(TRUE) //Only does anything if they were still in their old body and not already a ghost + to_chat(H.get_ghost(TRUE), "Your body is beginning to regenerate in a cloning pod. You will become conscious when it is complete.") + + if(H) + H.faction |= factions + + for(var/V in quirks) + var/datum/quirk/Q = new V(H) + Q.on_clone(quirks[V]) + + H.set_cloned_appearance() + H.give_genitals(TRUE) + + H.suiciding = FALSE + attempting = FALSE + return TRUE + +//Grow clones to maturity then kick them out. FREELOADERS +/obj/machinery/clonepod/process() + var/mob/living/mob_occupant = occupant + + if(!is_operational()) //Autoeject if power is lost + if(mob_occupant) + go_out() + mob_occupant.apply_vore_prefs() + connected_message("Clone Ejected: Loss of power.") + + else if(mob_occupant && (mob_occupant.loc == src)) + if((mob_occupant.stat == DEAD) || (mob_occupant.suiciding) || mob_occupant.hellbound) //Autoeject corpses and suiciding dudes. + connected_message("Clone Rejected: Deceased.") + if(internal_radio) + SPEAK("The cloning has been \ + aborted due to unrecoverable tissue failure.") + go_out() + mob_occupant.apply_vore_prefs() + + else if(mob_occupant.cloneloss > (100 - heal_level)) + mob_occupant.Unconscious(80) + var/dmg_mult = CONFIG_GET(number/damage_multiplier) + //Slowly get that clone healed and finished. + mob_occupant.adjustCloneLoss(-((speed_coeff / 2) * dmg_mult)) + var/progress = CLONE_INITIAL_DAMAGE - mob_occupant.getCloneLoss() + // To avoid the default cloner making incomplete clones + progress += (100 - MINIMUM_HEAL_LEVEL) + var/milestone = CLONE_INITIAL_DAMAGE / flesh_number + var/installed = flesh_number - unattached_flesh.len + + if((progress / milestone) >= installed) + // attach some flesh + var/obj/item/I = pick_n_take(unattached_flesh) + if(isorgan(I)) + var/obj/item/organ/O = I + O.organ_flags &= ~ORGAN_FROZEN + O.Insert(mob_occupant) + else if(isbodypart(I)) + var/obj/item/bodypart/BP = I + BP.attach_limb(mob_occupant) + + //Premature clones may have brain damage. + mob_occupant.adjustOrganLoss(ORGAN_SLOT_BRAIN, -((speed_coeff / 2) * dmg_mult)) + + use_power(7500) //This might need tweaking. + + else if((mob_occupant.cloneloss <= (100 - heal_level))) + connected_message("Cloning Process Complete.") + if(internal_radio) + SPEAK("The cloning cycle is complete.") + + // If the cloner is upgraded to debugging high levels, sometimes + // organs and limbs can be missing. + for(var/i in unattached_flesh) + if(isorgan(i)) + var/obj/item/organ/O = i + O.organ_flags &= ~ORGAN_FROZEN + O.Insert(mob_occupant) + else if(isbodypart(i)) + var/obj/item/bodypart/BP = i + BP.attach_limb(mob_occupant) + + go_out() + mob_occupant.apply_vore_prefs() + + else if (!mob_occupant || mob_occupant.loc != src) + occupant = null + use_power(200) + + update_icon() + +//Let's unlock this early I guess. Might be too early, needs tweaking. +/obj/machinery/clonepod/attackby(obj/item/W, mob/user, params) + if(!(occupant || mess)) + if(default_deconstruction_screwdriver(user, "[icon_state]_maintenance", "[initial(icon_state)]",W)) + return + + if(default_deconstruction_crowbar(W)) + return + + if(istype(W, /obj/item/multitool)) + var/obj/item/multitool/P = W + + if(istype(P.buffer, /obj/machinery/computer/cloning)) + 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/computer/cloning/comp = P.buffer + if(connected) + connected.DetachCloner(src) + comp.AttachCloner(src) + else + P.buffer = src + to_chat(user, "-% Successfully stored [REF(P.buffer)] [P.buffer.name] in buffer %-") + return + + var/mob/living/mob_occupant = occupant + if(W.GetID()) + if(!check_access(W)) + to_chat(user, "Access Denied.") + return + if(!(mob_occupant || mess)) + to_chat(user, "Error: Pod has no occupant.") + return + else + connected_message("Emergency Ejection") + SPEAK("An emergency ejection of the current clone has occurred. Survival not guaranteed.") + to_chat(user, "You force an emergency ejection. ") + go_out() + mob_occupant.apply_vore_prefs() + else + return ..() + +/obj/machinery/clonepod/emag_act(mob/user) + . = ..() + if(!occupant) + return + to_chat(user, "You corrupt the genetic compiler.") + malfunction() + return TRUE + +//Put messages in the connected computer's temp var for display. +/obj/machinery/clonepod/proc/connected_message(message) + if ((isnull(connected)) || (!istype(connected, /obj/machinery/computer/cloning))) + return FALSE + if (!message) + return FALSE + + connected.temp = message + connected.updateUsrDialog() + return TRUE + +/obj/machinery/clonepod/proc/go_out() + countdown.stop() + var/mob/living/mob_occupant = occupant + var/turf/T = get_turf(src) + + if(mess) //Clean that mess and dump those gibs! + for(var/obj/fl in unattached_flesh) + fl.forceMove(T) + if(istype(fl, /obj/item/organ)) + var/obj/item/organ/O = fl + O.organ_flags &= ~ORGAN_FROZEN + unattached_flesh.Cut() + mess = FALSE + if(mob_occupant) + mob_occupant.spawn_gibs() + audible_message("You hear a splat.") + update_icon() + return + + if(!mob_occupant) + return + + REMOVE_TRAIT(mob_occupant, TRAIT_STABLEHEART, CLONING_POD_TRAIT) + REMOVE_TRAIT(mob_occupant, TRAIT_STABLELIVER, CLONING_POD_TRAIT) + REMOVE_TRAIT(mob_occupant, TRAIT_EMOTEMUTE, CLONING_POD_TRAIT) + REMOVE_TRAIT(mob_occupant, TRAIT_MUTE, CLONING_POD_TRAIT) + REMOVE_TRAIT(mob_occupant, TRAIT_NOCRITDAMAGE, CLONING_POD_TRAIT) + REMOVE_TRAIT(mob_occupant, TRAIT_NOBREATH, CLONING_POD_TRAIT) + + if(grab_ghost_when == CLONER_MATURE_CLONE) + mob_occupant.grab_ghost() + to_chat(occupant, "There is a bright flash!
      You feel like a new being.
      ") + mob_occupant.flash_act() + + occupant.forceMove(T) + update_icon() + mob_occupant.domutcheck(1) //Waiting until they're out before possible monkeyizing. The 1 argument forces powers to manifest. + for(var/fl in unattached_flesh) + qdel(fl) + unattached_flesh.Cut() + + occupant = null + +/obj/machinery/clonepod/proc/malfunction() + var/mob/living/mob_occupant = occupant + if(mob_occupant) + connected_message("Critical Error!") + SPEAK("Critical error! Please contact a Thinktronic Systems \ + technician, as your warranty may be affected.") + mess = TRUE + maim_clone(mob_occupant) //Remove every bit that's grown back so far to drop later, also destroys bits that haven't grown yet + update_icon() + if(mob_occupant.mind != clonemind) + clonemind.transfer_to(mob_occupant) + mob_occupant.grab_ghost() // We really just want to make you suffer. + flash_color(mob_occupant, flash_color="#960000", flash_time=100) + to_chat(mob_occupant, "Agony blazes across your consciousness as your body is torn apart.
      Is this what dying is like? Yes it is.
      ") + playsound(src.loc, 'sound/machines/warning-buzzer.ogg', 50, 0) + SEND_SOUND(mob_occupant, sound('sound/hallucinations/veryfar_noise.ogg',0,1,50)) + QDEL_IN(mob_occupant, 40) + +/obj/machinery/clonepod/relaymove(mob/user) + container_resist(user) + +/obj/machinery/clonepod/container_resist(mob/living/user) + if(user.stat == CONSCIOUS) + go_out() + +/obj/machinery/clonepod/emp_act(severity) + . = ..() + if (!(. & EMP_PROTECT_SELF)) + var/mob/living/mob_occupant = occupant + if(mob_occupant && prob(100/(severity*efficiency))) + connected_message(Gibberish("EMP-caused Accidental Ejection", 0)) + SPEAK(Gibberish("Exposure to electromagnetic fields has caused the ejection of, ERROR: John Doe, prematurely." ,0)) + mob_occupant.apply_vore_prefs() + go_out() + +/obj/machinery/clonepod/ex_act(severity, target) + ..() + if(!QDELETED(src)) + go_out() + +/obj/machinery/clonepod/handle_atom_del(atom/A) + if(A == occupant) + occupant = null + countdown.stop() + +/obj/machinery/clonepod/proc/horrifyingsound() + for(var/i in 1 to 5) + playsound(loc,pick('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg'), 100, rand(0.95,1.05)) + sleep(1) + sleep(10) + playsound(loc,'sound/hallucinations/wail.ogg',100,1) + +/obj/machinery/clonepod/deconstruct(disassembled = TRUE) + if(occupant) + go_out() + ..() + +/obj/machinery/clonepod/proc/maim_clone(mob/living/carbon/human/H) + if(!unattached_flesh) + unattached_flesh = list() + else + for(var/fl in unattached_flesh) + qdel(fl) + unattached_flesh.Cut() + + H.setCloneLoss(CLONE_INITIAL_DAMAGE) //Yeah, clones start with very low health, not with random, because why would they start with random health + //H.setOrganLoss(ORGAN_SLOT_BRAIN, CLONE_INITIAL_DAMAGE) + // In addition to being cellularly damaged and having barely any + + // brain function, they also have no limbs or internal organs. + + if(!HAS_TRAIT(H, TRAIT_NODISMEMBER)) + var/static/list/zones = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) + for(var/zone in zones) + var/obj/item/bodypart/BP = H.get_bodypart(zone) + if(BP) + BP.drop_limb() + BP.forceMove(src) + unattached_flesh += BP + + for(var/o in H.internal_organs) + var/obj/item/organ/organ = o + if(!istype(organ) || (organ.organ_flags & ORGAN_VITAL)) + continue + organ.organ_flags |= ORGAN_FROZEN + organ.Remove(H, special=TRUE) + organ.forceMove(src) + unattached_flesh += organ + + flesh_number = unattached_flesh.len + +/obj/machinery/clonepod/update_icon() + cut_overlays() + + if(mess) + icon_state = "pod_g" + var/image/gib1 = image(CRYOMOBS, "gibup") + var/image/gib2 = image(CRYOMOBS, "gibdown") + gib1.pixel_y = 27 + round(sin(world.time) * 3) + gib1.pixel_x = round(sin(world.time * 3)) + gib2.pixel_y = 27 + round(cos(world.time) * 3) + gib2.pixel_x = round(cos(world.time * 3)) + add_overlay(gib2) + add_overlay(gib1) + add_overlay("cover-on") + + else if(occupant) + icon_state = "pod_1" + + var/image/occupant_overlay + var/completion = (flesh_number - unattached_flesh.len) / flesh_number + + if(unattached_flesh.len <= 0) + occupant_overlay = image(occupant.icon, occupant.icon_state) + occupant_overlay.copy_overlays(occupant) + else + occupant_overlay = image(CRYOMOBS, "clone_meat") + var/matrix/tform = matrix() + tform.Scale(completion) + tform.Turn(cos(world.time * 2) * 3) + occupant_overlay.transform = tform + occupant_overlay.appearance_flags = 0 + + occupant_overlay.dir = SOUTH + occupant_overlay.pixel_y = 27 + round(sin(world.time) * 3) + occupant_overlay.pixel_x = round(sin(world.time * 3)) + + add_overlay(occupant_overlay) + add_overlay("cover-on") + else + icon_state = "pod_0" + + if(panel_open) + icon_state = "pod_0_maintenance" + + add_overlay("panel") + +/* + * Manual -- A big ol' manual. + */ + +/obj/item/paper/guides/jobs/medical/cloning + name = "paper - 'H-87 Cloning Apparatus Manual" + info = {"

      Getting Started

      + Congratulations, your station has purchased the H-87 industrial cloning device!
      + Using the H-87 is almost as simple as brain surgery! Simply insert the target humanoid into the scanning chamber and select the scan option to create a new profile!
      + That's all there is to it!
      + Notice, cloning system cannot scan inorganic life or small primates. Scan may fail if subject has suffered extreme brain damage.
      +

      Clone profiles may be viewed through the profiles menu. Scanning implants a complementary HEALTH MONITOR IMPLANT into the subject, which may be viewed from each profile. + Profile Deletion has been restricted to \[Station Head\] level access.

      +

      Cloning from a profile

      + Cloning is as simple as pressing the CLONE option at the bottom of the desired profile.
      + Per your company's EMPLOYEE PRIVACY RIGHTS agreement, the H-87 has been blocked from cloning crewmembers while they are still alive.
      +
      +

      The provided CLONEPOD SYSTEM will produce the desired clone. Standard clone maturation times (With SPEEDCLONE technology) are roughly 90 seconds. + The cloning pod may be unlocked early with any \[Medical Researcher\] ID after initial maturation is complete.


      + Please note that resulting clones may have a small DEVELOPMENTAL DEFECT as a result of genetic drift.
      +

      Profile Management

      +

      The H-87 (as well as your station's standard genetics machine) can accept STANDARD DATA DISKETTES. + These diskettes are used to transfer genetic information between machines and profiles. + A load/save dialog will become available in each profile if a disk is inserted.


      + A good diskette is a great way to counter aforementioned genetic drift!
      +
      + This technology produced under license from Thinktronic Systems, LTD."} + +#undef CLONE_INITIAL_DAMAGE +#undef SPEAK +#undef MINIMUM_HEAL_LEVEL diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index 858a0a995b..3c021d0bd1 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -1,128 +1,128 @@ -#define MENU_OPERATION 1 -#define MENU_SURGERIES 2 - -/obj/machinery/computer/operating - name = "operating computer" - desc = "Monitors patient vitals and displays surgery steps. Can be loaded with surgery disks to perform experimental procedures." - icon_screen = "crew" - icon_keyboard = "med_key" - circuit = /obj/item/circuitboard/computer/operating - var/mob/living/carbon/human/patient - var/obj/structure/table/optable/table - var/list/advanced_surgeries = list() - var/datum/techweb/linked_techweb - var/menu = MENU_OPERATION - light_color = LIGHT_COLOR_BLUE - -/obj/machinery/computer/operating/Initialize() - . = ..() - linked_techweb = SSresearch.science_tech - find_table() - -/obj/machinery/computer/operating/attackby(obj/item/O, mob/user, params) - if(istype(O, /obj/item/disk/surgery)) - user.visible_message("[user] begins to load \the [O] in \the [src]...", - "You begin to load a surgery protocol from \the [O]...", - "You hear the chatter of a floppy drive.") - var/obj/item/disk/surgery/D = O - if(do_after(user, 10, target = src)) - advanced_surgeries |= D.surgeries - return TRUE - return ..() - -/obj/machinery/computer/operating/proc/sync_surgeries() - for(var/i in linked_techweb.researched_designs) - var/datum/design/surgery/D = SSresearch.techweb_design_by_id(i) - if(!istype(D)) - continue - advanced_surgeries |= D.surgery - -/obj/machinery/computer/operating/proc/find_table() - for(var/direction in GLOB.cardinals) - table = locate(/obj/structure/table/optable, get_step(src, direction)) - if(table) - table.computer = src - break - -/obj/machinery/computer/operating/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.not_incapacitated_state) - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - if(!ui) - ui = new(user, src, ui_key, "operating_computer", name, 350, 470, master_ui, state) - ui.open() - -/obj/machinery/computer/operating/ui_data(mob/user) - var/list/data = list() - data["table"] = table - if(table) - data["menu"] = menu - - var/list/surgeries = list() - for(var/X in advanced_surgeries) - var/datum/surgery/S = X - var/list/surgery = list() - surgery["name"] = initial(S.name) - surgery["desc"] = initial(S.desc) - surgeries += list(surgery) - data["surgeries"] = surgeries - - data["patient"] = list() - if(table.check_patient()) - patient = table.patient - switch(patient.stat) - if(CONSCIOUS) - data["patient"]["stat"] = "Conscious" - data["patient"]["statstate"] = "good" - if(SOFT_CRIT) - data["patient"]["stat"] = "Conscious" - data["patient"]["statstate"] = "average" - if(UNCONSCIOUS) - data["patient"]["stat"] = "Unconscious" - data["patient"]["statstate"] = "average" - if(DEAD) - data["patient"]["stat"] = "Dead" - data["patient"]["statstate"] = "bad" - data["patient"]["health"] = patient.health - data["patient"]["blood_type"] = patient.dna.blood_type - data["patient"]["maxHealth"] = patient.maxHealth - data["patient"]["minHealth"] = HEALTH_THRESHOLD_DEAD - data["patient"]["bruteLoss"] = patient.getBruteLoss() - data["patient"]["fireLoss"] = patient.getFireLoss() - data["patient"]["toxLoss"] = patient.getToxLoss() - data["patient"]["oxyLoss"] = patient.getOxyLoss() - if(patient.surgeries.len) - data["procedures"] = list() - for(var/datum/surgery/procedure in patient.surgeries) - var/datum/surgery_step/surgery_step = procedure.get_surgery_step() - var/chems_needed = surgery_step.get_chem_list() - var/alternative_step - var/alt_chems_needed = "" - if(surgery_step.repeatable) - var/datum/surgery_step/next_step = procedure.get_surgery_next_step() - if(next_step) - alternative_step = capitalize(next_step.name) - alt_chems_needed = next_step.get_chem_list() - else - alternative_step = "Finish operation" - data["procedures"] += list(list( - "name" = capitalize(procedure.name), - "next_step" = capitalize(surgery_step.name), - "chems_needed" = chems_needed, - "alternative_step" = alternative_step, - "alt_chems_needed" = alt_chems_needed - )) - return data - -/obj/machinery/computer/operating/ui_act(action, params) - if(..()) - return - switch(action) - if("change_menu") - menu = text2num(params["menu"]) - . = TRUE - if("sync") - sync_surgeries() - . = TRUE - . = TRUE - -#undef MENU_OPERATION -#undef MENU_SURGERIES +#define MENU_OPERATION 1 +#define MENU_SURGERIES 2 + +/obj/machinery/computer/operating + name = "operating computer" + desc = "Monitors patient vitals and displays surgery steps. Can be loaded with surgery disks to perform experimental procedures." + icon_screen = "crew" + icon_keyboard = "med_key" + circuit = /obj/item/circuitboard/computer/operating + var/mob/living/carbon/human/patient + var/obj/structure/table/optable/table + var/list/advanced_surgeries = list() + var/datum/techweb/linked_techweb + var/menu = MENU_OPERATION + light_color = LIGHT_COLOR_BLUE + +/obj/machinery/computer/operating/Initialize() + . = ..() + linked_techweb = SSresearch.science_tech + find_table() + +/obj/machinery/computer/operating/attackby(obj/item/O, mob/user, params) + if(istype(O, /obj/item/disk/surgery)) + user.visible_message("[user] begins to load \the [O] in \the [src]...", + "You begin to load a surgery protocol from \the [O]...", + "You hear the chatter of a floppy drive.") + var/obj/item/disk/surgery/D = O + if(do_after(user, 10, target = src)) + advanced_surgeries |= D.surgeries + return TRUE + return ..() + +/obj/machinery/computer/operating/proc/sync_surgeries() + for(var/i in linked_techweb.researched_designs) + var/datum/design/surgery/D = SSresearch.techweb_design_by_id(i) + if(!istype(D)) + continue + advanced_surgeries |= D.surgery + +/obj/machinery/computer/operating/proc/find_table() + for(var/direction in GLOB.cardinals) + table = locate(/obj/structure/table/optable, get_step(src, direction)) + if(table) + table.computer = src + break + +/obj/machinery/computer/operating/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.not_incapacitated_state) + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + ui = new(user, src, ui_key, "operating_computer", name, 350, 470, master_ui, state) + ui.open() + +/obj/machinery/computer/operating/ui_data(mob/user) + var/list/data = list() + data["table"] = table + if(table) + data["menu"] = menu + + var/list/surgeries = list() + for(var/X in advanced_surgeries) + var/datum/surgery/S = X + var/list/surgery = list() + surgery["name"] = initial(S.name) + surgery["desc"] = initial(S.desc) + surgeries += list(surgery) + data["surgeries"] = surgeries + + data["patient"] = list() + if(table.check_patient()) + patient = table.patient + switch(patient.stat) + if(CONSCIOUS) + data["patient"]["stat"] = "Conscious" + data["patient"]["statstate"] = "good" + if(SOFT_CRIT) + data["patient"]["stat"] = "Conscious" + data["patient"]["statstate"] = "average" + if(UNCONSCIOUS) + data["patient"]["stat"] = "Unconscious" + data["patient"]["statstate"] = "average" + if(DEAD) + data["patient"]["stat"] = "Dead" + data["patient"]["statstate"] = "bad" + data["patient"]["health"] = patient.health + data["patient"]["blood_type"] = patient.dna.blood_type + data["patient"]["maxHealth"] = patient.maxHealth + data["patient"]["minHealth"] = HEALTH_THRESHOLD_DEAD + data["patient"]["bruteLoss"] = patient.getBruteLoss() + data["patient"]["fireLoss"] = patient.getFireLoss() + data["patient"]["toxLoss"] = patient.getToxLoss() + data["patient"]["oxyLoss"] = patient.getOxyLoss() + if(patient.surgeries.len) + data["procedures"] = list() + for(var/datum/surgery/procedure in patient.surgeries) + var/datum/surgery_step/surgery_step = procedure.get_surgery_step() + var/chems_needed = surgery_step.get_chem_list() + var/alternative_step + var/alt_chems_needed = "" + if(surgery_step.repeatable) + var/datum/surgery_step/next_step = procedure.get_surgery_next_step() + if(next_step) + alternative_step = capitalize(next_step.name) + alt_chems_needed = next_step.get_chem_list() + else + alternative_step = "Finish operation" + data["procedures"] += list(list( + "name" = capitalize(procedure.name), + "next_step" = capitalize(surgery_step.name), + "chems_needed" = chems_needed, + "alternative_step" = alternative_step, + "alt_chems_needed" = alt_chems_needed + )) + return data + +/obj/machinery/computer/operating/ui_act(action, params) + if(..()) + return + switch(action) + if("change_menu") + menu = text2num(params["menu"]) + . = TRUE + if("sync") + sync_surgeries() + . = TRUE + . = TRUE + +#undef MENU_OPERATION +#undef MENU_SURGERIES diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index 5d6c92a97d..8bb0894cdb 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -1,150 +1,150 @@ -/obj/machinery/computer/aifixer - name = "\improper AI system integrity restorer" - desc = "Used with intelliCards containing nonfunctional AIs to restore them to working order." - req_access = list(ACCESS_CAPTAIN, ACCESS_ROBOTICS, ACCESS_HEADS) - var/mob/living/silicon/ai/occupier = null - var/active = 0 - circuit = /obj/item/circuitboard/computer/aifixer - icon_keyboard = "tech_key" - icon_screen = "ai-fixer" - light_color = LIGHT_COLOR_PINK - -/obj/machinery/computer/aifixer/attackby(obj/I, mob/user, params) - if(occupier && istype(I, /obj/item/screwdriver)) - if(stat & (NOPOWER|BROKEN)) - to_chat(user, "The screws on [name]'s screen won't budge.") - else - to_chat(user, "The screws on [name]'s screen won't budge and it emits a warning beep.") - else - return ..() - -/obj/machinery/computer/aifixer/ui_interact(mob/user) - . = ..() - - var/dat = "" - - if (src.occupier) - var/laws - dat += "

      Stored AI: [src.occupier.name]

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

      Begin Reconstruction"} - else - dat += "

      Reconstruction in process, please wait.
      " - dat += {"
      Close"} - var/datum/browser/popup = new(user, "computer", "AI System Integrity Restorer", 400, 500) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - return - -/obj/machinery/computer/aifixer/proc/Fix() - use_power(1000) - occupier.adjustOxyLoss(-1, 0) - occupier.adjustFireLoss(-1, 0) - occupier.adjustToxLoss(-1, 0) - occupier.adjustBruteLoss(-1, 0) - occupier.updatehealth() - if(occupier.health >= 0 && occupier.stat == DEAD) - occupier.revive() - return occupier.health < 100 - -/obj/machinery/computer/aifixer/process() - if(..()) - if(active) - var/oldstat = occupier.stat - active = Fix() - if(oldstat != occupier.stat) - update_icon() - updateDialog() - -/obj/machinery/computer/aifixer/Topic(href, href_list) - if(..()) - return - if(href_list["fix"]) - to_chat(usr, "Reconstruction in progress. This will take several minutes.") - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0) - active = TRUE - add_fingerprint(usr) - updateUsrDialog() - -/obj/machinery/computer/aifixer/update_icon() - ..() - if(stat & (NOPOWER|BROKEN)) - return - else - if(active) - add_overlay("ai-fixer-on") - if (occupier) - switch (occupier.stat) - if (0) - add_overlay("ai-fixer-full") - if (2) - add_overlay("ai-fixer-404") - else - add_overlay("ai-fixer-empty") - -/obj/machinery/computer/aifixer/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card) - if(!..()) - return - //Downloading AI from card to terminal. - if(interaction == AI_TRANS_FROM_CARD) - if(stat & (NOPOWER|BROKEN)) - to_chat(user, "[src] is offline and cannot take an AI at this time!") - return - AI.forceMove(src) - occupier = AI - AI.control_disabled = 1 - AI.radio_enabled = 0 - to_chat(AI, "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here.") - to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.") - card.AI = null - update_icon() - - else //Uploading AI from terminal to card - if(occupier && !active) - to_chat(occupier, "You have been downloaded to a mobile storage device. Still no remote access.") - to_chat(user, "Transfer successful: [occupier.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory.") - occupier.forceMove(card) - card.AI = occupier - occupier = null - update_icon() - else if (active) - to_chat(user, "ERROR: Reconstruction in progress.") - else if (!occupier) - to_chat(user, "ERROR: Unable to locate artificial intelligence.") +/obj/machinery/computer/aifixer + name = "\improper AI system integrity restorer" + desc = "Used with intelliCards containing nonfunctional AIs to restore them to working order." + req_access = list(ACCESS_CAPTAIN, ACCESS_ROBOTICS, ACCESS_HEADS) + var/mob/living/silicon/ai/occupier = null + var/active = 0 + circuit = /obj/item/circuitboard/computer/aifixer + icon_keyboard = "tech_key" + icon_screen = "ai-fixer" + light_color = LIGHT_COLOR_PINK + +/obj/machinery/computer/aifixer/attackby(obj/I, mob/user, params) + if(occupier && istype(I, /obj/item/screwdriver)) + if(stat & (NOPOWER|BROKEN)) + to_chat(user, "The screws on [name]'s screen won't budge.") + else + to_chat(user, "The screws on [name]'s screen won't budge and it emits a warning beep.") + else + return ..() + +/obj/machinery/computer/aifixer/ui_interact(mob/user) + . = ..() + + var/dat = "" + + if (src.occupier) + var/laws + dat += "

      Stored AI: [src.occupier.name]

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

      Begin Reconstruction"} + else + dat += "

      Reconstruction in process, please wait.
      " + dat += {"
      Close"} + var/datum/browser/popup = new(user, "computer", "AI System Integrity Restorer", 400, 500) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + return + +/obj/machinery/computer/aifixer/proc/Fix() + use_power(1000) + occupier.adjustOxyLoss(-1, 0) + occupier.adjustFireLoss(-1, 0) + occupier.adjustToxLoss(-1, 0) + occupier.adjustBruteLoss(-1, 0) + occupier.updatehealth() + if(occupier.health >= 0 && occupier.stat == DEAD) + occupier.revive() + return occupier.health < 100 + +/obj/machinery/computer/aifixer/process() + if(..()) + if(active) + var/oldstat = occupier.stat + active = Fix() + if(oldstat != occupier.stat) + update_icon() + updateDialog() + +/obj/machinery/computer/aifixer/Topic(href, href_list) + if(..()) + return + if(href_list["fix"]) + to_chat(usr, "Reconstruction in progress. This will take several minutes.") + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0) + active = TRUE + add_fingerprint(usr) + updateUsrDialog() + +/obj/machinery/computer/aifixer/update_icon() + ..() + if(stat & (NOPOWER|BROKEN)) + return + else + if(active) + add_overlay("ai-fixer-on") + if (occupier) + switch (occupier.stat) + if (0) + add_overlay("ai-fixer-full") + if (2) + add_overlay("ai-fixer-404") + else + add_overlay("ai-fixer-empty") + +/obj/machinery/computer/aifixer/transfer_ai(interaction, mob/user, mob/living/silicon/ai/AI, obj/item/aicard/card) + if(!..()) + return + //Downloading AI from card to terminal. + if(interaction == AI_TRANS_FROM_CARD) + if(stat & (NOPOWER|BROKEN)) + to_chat(user, "[src] is offline and cannot take an AI at this time!") + return + AI.forceMove(src) + occupier = AI + AI.control_disabled = 1 + AI.radio_enabled = 0 + to_chat(AI, "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here.") + to_chat(user, "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed.") + card.AI = null + update_icon() + + else //Uploading AI from terminal to card + if(occupier && !active) + to_chat(occupier, "You have been downloaded to a mobile storage device. Still no remote access.") + to_chat(user, "Transfer successful: [occupier.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory.") + occupier.forceMove(card) + card.AI = occupier + occupier = null + update_icon() + else if (active) + to_chat(user, "ERROR: Reconstruction in progress.") + else if (!occupier) + to_chat(user, "ERROR: Unable to locate artificial intelligence.") diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm index cb3cbf2aa6..4c9e9aed19 100644 --- a/code/game/machinery/computer/atmos_alert.dm +++ b/code/game/machinery/computer/atmos_alert.dm @@ -1,100 +1,100 @@ -/obj/machinery/computer/atmos_alert - name = "atmospheric alert console" - desc = "Used to monitor the station's air alarms." - circuit = /obj/item/circuitboard/computer/atmos_alert - icon_screen = "alert:0" - icon_keyboard = "atmos_key" - var/list/priority_alarms = list() - var/list/minor_alarms = list() - var/receive_frequency = FREQ_ATMOS_ALARMS - var/datum/radio_frequency/radio_connection - - light_color = LIGHT_COLOR_CYAN - -/obj/machinery/computer/atmos_alert/Initialize() - . = ..() - set_frequency(receive_frequency) - -/obj/machinery/computer/atmos_alert/Destroy() - SSradio.remove_object(src, receive_frequency) - return ..() - -/obj/machinery/computer/atmos_alert/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, "atmos_alert", name, 350, 300, master_ui, state) - ui.open() - -/obj/machinery/computer/atmos_alert/ui_data(mob/user) - var/list/data = list() - - data["priority"] = list() - for(var/zone in priority_alarms) - data["priority"] += zone - data["minor"] = list() - for(var/zone in minor_alarms) - data["minor"] += zone - - return data - -/obj/machinery/computer/atmos_alert/ui_act(action, params) - if(..()) - return - switch(action) - if("clear") - var/zone = params["zone"] - if(zone in priority_alarms) - to_chat(usr, "Priority alarm for [zone] cleared.") - priority_alarms -= zone - . = TRUE - if(zone in minor_alarms) - to_chat(usr, "Minor alarm for [zone] cleared.") - minor_alarms -= zone - . = TRUE - update_icon() - -/obj/machinery/computer/atmos_alert/proc/set_frequency(new_frequency) - SSradio.remove_object(src, receive_frequency) - receive_frequency = new_frequency - radio_connection = SSradio.add_object(src, receive_frequency, RADIO_ATMOSIA) - -/obj/machinery/computer/atmos_alert/receive_signal(datum/signal/signal) - if(!signal) - return - - var/zone = signal.data["zone"] - var/severity = signal.data["alert"] - - if(!zone || !severity) - return - - minor_alarms -= zone - priority_alarms -= zone - if(severity == "severe") - priority_alarms += zone - else if (severity == "minor") - minor_alarms += zone - update_icon() - return - -/obj/machinery/computer/atmos_alert/update_icon() - ..() - cut_overlays() - SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) - var/overlay_state = icon_screen - if(stat & (NOPOWER|BROKEN)) - add_overlay("[icon_keyboard]_off") - return - add_overlay(icon_keyboard) - if(priority_alarms.len) - overlay_state = "alert:2" - add_overlay("alert:2") - else if(minor_alarms.len) - overlay_state = "alert:1" - add_overlay("alert:1") - else - overlay_state = "alert:0" - add_overlay("alert:0") - SSvis_overlays.add_vis_overlay(src, icon, overlay_state, layer, plane, dir) - SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir, alpha=128) +/obj/machinery/computer/atmos_alert + name = "atmospheric alert console" + desc = "Used to monitor the station's air alarms." + circuit = /obj/item/circuitboard/computer/atmos_alert + icon_screen = "alert:0" + icon_keyboard = "atmos_key" + var/list/priority_alarms = list() + var/list/minor_alarms = list() + var/receive_frequency = FREQ_ATMOS_ALARMS + var/datum/radio_frequency/radio_connection + + light_color = LIGHT_COLOR_CYAN + +/obj/machinery/computer/atmos_alert/Initialize() + . = ..() + set_frequency(receive_frequency) + +/obj/machinery/computer/atmos_alert/Destroy() + SSradio.remove_object(src, receive_frequency) + return ..() + +/obj/machinery/computer/atmos_alert/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, "atmos_alert", name, 350, 300, master_ui, state) + ui.open() + +/obj/machinery/computer/atmos_alert/ui_data(mob/user) + var/list/data = list() + + data["priority"] = list() + for(var/zone in priority_alarms) + data["priority"] += zone + data["minor"] = list() + for(var/zone in minor_alarms) + data["minor"] += zone + + return data + +/obj/machinery/computer/atmos_alert/ui_act(action, params) + if(..()) + return + switch(action) + if("clear") + var/zone = params["zone"] + if(zone in priority_alarms) + to_chat(usr, "Priority alarm for [zone] cleared.") + priority_alarms -= zone + . = TRUE + if(zone in minor_alarms) + to_chat(usr, "Minor alarm for [zone] cleared.") + minor_alarms -= zone + . = TRUE + update_icon() + +/obj/machinery/computer/atmos_alert/proc/set_frequency(new_frequency) + SSradio.remove_object(src, receive_frequency) + receive_frequency = new_frequency + radio_connection = SSradio.add_object(src, receive_frequency, RADIO_ATMOSIA) + +/obj/machinery/computer/atmos_alert/receive_signal(datum/signal/signal) + if(!signal) + return + + var/zone = signal.data["zone"] + var/severity = signal.data["alert"] + + if(!zone || !severity) + return + + minor_alarms -= zone + priority_alarms -= zone + if(severity == "severe") + priority_alarms += zone + else if (severity == "minor") + minor_alarms += zone + update_icon() + return + +/obj/machinery/computer/atmos_alert/update_icon() + ..() + cut_overlays() + SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) + var/overlay_state = icon_screen + if(stat & (NOPOWER|BROKEN)) + add_overlay("[icon_keyboard]_off") + return + add_overlay(icon_keyboard) + if(priority_alarms.len) + overlay_state = "alert:2" + add_overlay("alert:2") + else if(minor_alarms.len) + overlay_state = "alert:1" + add_overlay("alert:1") + else + overlay_state = "alert:0" + add_overlay("alert:0") + SSvis_overlays.add_vis_overlay(src, icon, overlay_state, layer, plane, dir) + SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir, alpha=128) diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index 6576f51e46..f9d2a3c103 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -1,305 +1,305 @@ -///////////////////////////////////////////////////////////// -// AIR SENSOR (found in gas tanks) -///////////////////////////////////////////////////////////// - -/obj/machinery/air_sensor - name = "gas sensor" - icon = 'icons/obj/stationobjs.dmi' - icon_state = "gsensor1" - - var/on = TRUE - - var/id_tag - var/frequency = FREQ_ATMOS_STORAGE - var/datum/radio_frequency/radio_connection - -/obj/machinery/air_sensor/atmos/toxin_tank - name = "plasma tank gas sensor" - id_tag = ATMOS_GAS_MONITOR_SENSOR_TOX -/obj/machinery/air_sensor/atmos/toxins_mixing_tank - name = "toxins mixing gas sensor" - id_tag = ATMOS_GAS_MONITOR_SENSOR_TOXINS_LAB -/obj/machinery/air_sensor/atmos/oxygen_tank - name = "oxygen tank gas sensor" - id_tag = ATMOS_GAS_MONITOR_SENSOR_O2 -/obj/machinery/air_sensor/atmos/nitrogen_tank - name = "nitrogen tank gas sensor" - id_tag = ATMOS_GAS_MONITOR_SENSOR_N2 -/obj/machinery/air_sensor/atmos/mix_tank - name = "mix tank gas sensor" - id_tag = ATMOS_GAS_MONITOR_SENSOR_MIX -/obj/machinery/air_sensor/atmos/nitrous_tank - name = "nitrous oxide tank gas sensor" - id_tag = ATMOS_GAS_MONITOR_SENSOR_N2O -/obj/machinery/air_sensor/atmos/air_tank - name = "air mix tank gas sensor" - id_tag = ATMOS_GAS_MONITOR_SENSOR_AIR -/obj/machinery/air_sensor/atmos/carbon_tank - name = "carbon dioxide tank gas sensor" - id_tag = ATMOS_GAS_MONITOR_SENSOR_CO2 -/obj/machinery/air_sensor/atmos/incinerator_tank - name = "incinerator chamber gas sensor" - id_tag = ATMOS_GAS_MONITOR_SENSOR_INCINERATOR - -/obj/machinery/air_sensor/update_icon() - icon_state = "gsensor[on]" - -/obj/machinery/air_sensor/process_atmos() - if(on) - var/datum/gas_mixture/air_sample = return_air() - - var/datum/signal/signal = new(list( - "sigtype" = "status", - "id_tag" = id_tag, - "timestamp" = world.time, - "pressure" = air_sample.return_pressure(), - "temperature" = air_sample.temperature, - "gases" = list() - )) - var/total_moles = air_sample.total_moles() - if(total_moles) - for(var/gas_id in air_sample.gases) - var/gas_name = GLOB.meta_gas_names[gas_id] - signal.data["gases"][gas_name] = air_sample.gases[gas_id] / total_moles * 100 - - radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) - - -/obj/machinery/air_sensor/proc/set_frequency(new_frequency) - SSradio.remove_object(src, frequency) - frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA) - -/obj/machinery/air_sensor/Initialize() - . = ..() - SSair.atmos_machinery += src - set_frequency(frequency) - -/obj/machinery/air_sensor/Destroy() - SSair.atmos_machinery -= src - SSradio.remove_object(src, frequency) - return ..() - -///////////////////////////////////////////////////////////// -// GENERAL AIR CONTROL (a.k.a atmos computer) -///////////////////////////////////////////////////////////// -GLOBAL_LIST_EMPTY(atmos_air_controllers) - -/obj/machinery/computer/atmos_control - name = "atmospherics monitoring" - desc = "Used to monitor the station's atmospherics sensors." - icon_screen = "tank" - icon_keyboard = "atmos_key" - circuit = /obj/item/circuitboard/computer/atmos_control - - var/frequency = FREQ_ATMOS_STORAGE - var/list/sensors = list( - ATMOS_GAS_MONITOR_SENSOR_N2 = "Nitrogen Tank", - ATMOS_GAS_MONITOR_SENSOR_O2 = "Oxygen Tank", - ATMOS_GAS_MONITOR_SENSOR_CO2 = "Carbon Dioxide Tank", - ATMOS_GAS_MONITOR_SENSOR_TOX = "Plasma Tank", - ATMOS_GAS_MONITOR_SENSOR_N2O = "Nitrous Oxide Tank", - ATMOS_GAS_MONITOR_SENSOR_AIR = "Mixed Air Tank", - ATMOS_GAS_MONITOR_SENSOR_MIX = "Mix Tank", - ATMOS_GAS_MONITOR_LOOP_DISTRIBUTION = "Distribution Loop", - ATMOS_GAS_MONITOR_LOOP_ATMOS_WASTE = "Atmos Waste Loop", - ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber", - ATMOS_GAS_MONITOR_SENSOR_TOXINS_LAB = "Toxins Mixing Chamber" - ) - var/list/sensor_information = list() - var/datum/radio_frequency/radio_connection - - light_color = LIGHT_COLOR_CYAN - -/obj/machinery/computer/atmos_control/Initialize() - . = ..() - GLOB.atmos_air_controllers += src - set_frequency(frequency) - -/obj/machinery/computer/atmos_control/Destroy() - GLOB.atmos_air_controllers -= src - SSradio.remove_object(src, frequency) - return ..() - -/obj/machinery/computer/atmos_control/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, "atmos_control", name, 400, 925, master_ui, state) - ui.open() - -/obj/machinery/computer/atmos_control/ui_data(mob/user) - var/data = list() - - data["sensors"] = list() - for(var/id_tag in sensors) - var/long_name = sensors[id_tag] - var/list/info = sensor_information[id_tag] - if(!info) - continue - data["sensors"] += list(list( - "id_tag" = id_tag, - "long_name" = sanitize(long_name), - "pressure" = info["pressure"], - "temperature" = info["temperature"], - "gases" = info["gases"] - )) - return data - -/obj/machinery/computer/atmos_control/receive_signal(datum/signal/signal) - if(!signal) - return - - var/id_tag = signal.data["id_tag"] - if(!id_tag || !sensors.Find(id_tag)) - return - - sensor_information[id_tag] = signal.data - -/obj/machinery/computer/atmos_control/proc/set_frequency(new_frequency) - SSradio.remove_object(src, frequency) - frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA) - -///////////////////////////////////////////////////////////// -// LARGE TANK CONTROL -///////////////////////////////////////////////////////////// - -/obj/machinery/computer/atmos_control/tank - var/input_tag - var/output_tag - frequency = FREQ_ATMOS_STORAGE - circuit = /obj/item/circuitboard/computer/atmos_control/tank - - var/list/input_info - var/list/output_info - -/obj/machinery/computer/atmos_control/tank/oxygen_tank - name = "Oxygen Supply Control" - input_tag = ATMOS_GAS_MONITOR_INPUT_O2 - output_tag = ATMOS_GAS_MONITOR_OUTPUT_O2 - sensors = list(ATMOS_GAS_MONITOR_SENSOR_O2 = "Oxygen Tank") - -/obj/machinery/computer/atmos_control/tank/toxin_tank - name = "Plasma Supply Control" - input_tag = ATMOS_GAS_MONITOR_INPUT_TOX - output_tag = ATMOS_GAS_MONITOR_OUTPUT_TOX - sensors = list(ATMOS_GAS_MONITOR_SENSOR_TOX = "Plasma Tank") - -/obj/machinery/computer/atmos_control/tank/air_tank - name = "Mixed Air Supply Control" - input_tag = ATMOS_GAS_MONITOR_INPUT_AIR - output_tag = ATMOS_GAS_MONITOR_OUTPUT_AIR - sensors = list(ATMOS_GAS_MONITOR_SENSOR_AIR = "Air Mix Tank") - -/obj/machinery/computer/atmos_control/tank/mix_tank - name = "Gas Mix Tank Control" - input_tag = ATMOS_GAS_MONITOR_INPUT_MIX - output_tag = ATMOS_GAS_MONITOR_OUTPUT_MIX - sensors = list(ATMOS_GAS_MONITOR_SENSOR_MIX = "Gas Mix Tank") - -/obj/machinery/computer/atmos_control/tank/nitrous_tank - name = "Nitrous Oxide Supply Control" - input_tag = ATMOS_GAS_MONITOR_INPUT_N2O - output_tag = ATMOS_GAS_MONITOR_OUTPUT_N2O - sensors = list(ATMOS_GAS_MONITOR_SENSOR_N2O = "Nitrous Oxide Tank") - -/obj/machinery/computer/atmos_control/tank/nitrogen_tank - name = "Nitrogen Supply Control" - input_tag = ATMOS_GAS_MONITOR_INPUT_N2 - output_tag = ATMOS_GAS_MONITOR_OUTPUT_N2 - sensors = list(ATMOS_GAS_MONITOR_SENSOR_N2 = "Nitrogen Tank") - -/obj/machinery/computer/atmos_control/tank/carbon_tank - name = "Carbon Dioxide Supply Control" - input_tag = ATMOS_GAS_MONITOR_INPUT_CO2 - output_tag = ATMOS_GAS_MONITOR_OUTPUT_CO2 - sensors = list(ATMOS_GAS_MONITOR_SENSOR_CO2 = "Carbon Dioxide Tank") - -/obj/machinery/computer/atmos_control/tank/incinerator - name = "Incinerator Air Control" - input_tag = ATMOS_GAS_MONITOR_INPUT_INCINERATOR - output_tag = ATMOS_GAS_MONITOR_OUTPUT_INCINERATOR - sensors = list(ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber") - -// This hacky madness is the evidence of the fact that a lot of machines were never meant to be constructable, im so sorry you had to see this -/obj/machinery/computer/atmos_control/tank/proc/reconnect(mob/user) - var/list/IO = list() - var/datum/radio_frequency/freq = SSradio.return_frequency(FREQ_ATMOS_STORAGE) - var/list/devices = freq.devices["_default"] - for(var/obj/machinery/atmospherics/components/unary/vent_pump/U in devices) - var/list/text = splittext(U.id_tag, "_") - IO |= text[1] - for(var/obj/machinery/atmospherics/components/unary/outlet_injector/U in devices) - var/list/text = splittext(U.id, "_") - IO |= text[1] - if(!IO.len) - to_chat(user, "No machinery detected.") - var/S = input("Select the device set: ", "Selection", IO[1]) as anything in IO - if(src) - src.input_tag = "[S]_in" - src.output_tag = "[S]_out" - name = "[uppertext(S)] Supply Control" - var/list/new_devices = freq.devices["4"] - for(var/obj/machinery/air_sensor/U in new_devices) - var/list/text = splittext(U.id_tag, "_") - if(text[1] == S) - sensors = list("[S]_sensor" = "Tank") - break - - for(var/obj/machinery/atmospherics/components/unary/outlet_injector/U in devices) - U.broadcast_status() - for(var/obj/machinery/atmospherics/components/unary/vent_pump/U in devices) - U.broadcast_status() - -/obj/machinery/computer/atmos_control/tank/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, "atmos_control", name, 500, 305, master_ui, state) - ui.open() - -/obj/machinery/computer/atmos_control/tank/ui_data(mob/user) - var/list/data = ..() - data["tank"] = TRUE - data["inputting"] = input_info ? input_info["power"] : FALSE - data["inputRate"] = input_info ? input_info["volume_rate"] : 0 - data["outputting"] = output_info ? output_info["power"] : FALSE - data["outputPressure"] = output_info ? output_info["internal"] : 0 - - return data - -/obj/machinery/computer/atmos_control/tank/ui_act(action, params) - if(..() || !radio_connection) - return - var/datum/signal/signal = new(list("sigtype" = "command", "user" = usr)) - switch(action) - if("reconnect") - reconnect(usr) - . = TRUE - if("input") - signal.data += list("tag" = input_tag, "power_toggle" = TRUE) - . = TRUE - if("output") - signal.data += list("tag" = output_tag, "power_toggle" = TRUE) - . = TRUE - if("pressure") - var/target = input("New target pressure:", name, output_info ? output_info["internal"] : 0) as num|null - if(!isnull(target) && !..()) - target = CLAMP(target, 0, 50 * ONE_ATMOSPHERE) - signal.data += list("tag" = output_tag, "set_internal_pressure" = target) - . = TRUE - radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) - -/obj/machinery/computer/atmos_control/tank/receive_signal(datum/signal/signal) - if(!signal) - return - - var/id_tag = signal.data["tag"] - - if(input_tag == id_tag) - input_info = signal.data - else if(output_tag == id_tag) - output_info = signal.data - else - ..(signal) +///////////////////////////////////////////////////////////// +// AIR SENSOR (found in gas tanks) +///////////////////////////////////////////////////////////// + +/obj/machinery/air_sensor + name = "gas sensor" + icon = 'icons/obj/stationobjs.dmi' + icon_state = "gsensor1" + + var/on = TRUE + + var/id_tag + var/frequency = FREQ_ATMOS_STORAGE + var/datum/radio_frequency/radio_connection + +/obj/machinery/air_sensor/atmos/toxin_tank + name = "plasma tank gas sensor" + id_tag = ATMOS_GAS_MONITOR_SENSOR_TOX +/obj/machinery/air_sensor/atmos/toxins_mixing_tank + name = "toxins mixing gas sensor" + id_tag = ATMOS_GAS_MONITOR_SENSOR_TOXINS_LAB +/obj/machinery/air_sensor/atmos/oxygen_tank + name = "oxygen tank gas sensor" + id_tag = ATMOS_GAS_MONITOR_SENSOR_O2 +/obj/machinery/air_sensor/atmos/nitrogen_tank + name = "nitrogen tank gas sensor" + id_tag = ATMOS_GAS_MONITOR_SENSOR_N2 +/obj/machinery/air_sensor/atmos/mix_tank + name = "mix tank gas sensor" + id_tag = ATMOS_GAS_MONITOR_SENSOR_MIX +/obj/machinery/air_sensor/atmos/nitrous_tank + name = "nitrous oxide tank gas sensor" + id_tag = ATMOS_GAS_MONITOR_SENSOR_N2O +/obj/machinery/air_sensor/atmos/air_tank + name = "air mix tank gas sensor" + id_tag = ATMOS_GAS_MONITOR_SENSOR_AIR +/obj/machinery/air_sensor/atmos/carbon_tank + name = "carbon dioxide tank gas sensor" + id_tag = ATMOS_GAS_MONITOR_SENSOR_CO2 +/obj/machinery/air_sensor/atmos/incinerator_tank + name = "incinerator chamber gas sensor" + id_tag = ATMOS_GAS_MONITOR_SENSOR_INCINERATOR + +/obj/machinery/air_sensor/update_icon() + icon_state = "gsensor[on]" + +/obj/machinery/air_sensor/process_atmos() + if(on) + var/datum/gas_mixture/air_sample = return_air() + + var/datum/signal/signal = new(list( + "sigtype" = "status", + "id_tag" = id_tag, + "timestamp" = world.time, + "pressure" = air_sample.return_pressure(), + "temperature" = air_sample.temperature, + "gases" = list() + )) + var/total_moles = air_sample.total_moles() + if(total_moles) + for(var/gas_id in air_sample.gases) + var/gas_name = GLOB.meta_gas_names[gas_id] + signal.data["gases"][gas_name] = air_sample.gases[gas_id] / total_moles * 100 + + radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) + + +/obj/machinery/air_sensor/proc/set_frequency(new_frequency) + SSradio.remove_object(src, frequency) + frequency = new_frequency + radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA) + +/obj/machinery/air_sensor/Initialize() + . = ..() + SSair.atmos_machinery += src + set_frequency(frequency) + +/obj/machinery/air_sensor/Destroy() + SSair.atmos_machinery -= src + SSradio.remove_object(src, frequency) + return ..() + +///////////////////////////////////////////////////////////// +// GENERAL AIR CONTROL (a.k.a atmos computer) +///////////////////////////////////////////////////////////// +GLOBAL_LIST_EMPTY(atmos_air_controllers) + +/obj/machinery/computer/atmos_control + name = "atmospherics monitoring" + desc = "Used to monitor the station's atmospherics sensors." + icon_screen = "tank" + icon_keyboard = "atmos_key" + circuit = /obj/item/circuitboard/computer/atmos_control + + var/frequency = FREQ_ATMOS_STORAGE + var/list/sensors = list( + ATMOS_GAS_MONITOR_SENSOR_N2 = "Nitrogen Tank", + ATMOS_GAS_MONITOR_SENSOR_O2 = "Oxygen Tank", + ATMOS_GAS_MONITOR_SENSOR_CO2 = "Carbon Dioxide Tank", + ATMOS_GAS_MONITOR_SENSOR_TOX = "Plasma Tank", + ATMOS_GAS_MONITOR_SENSOR_N2O = "Nitrous Oxide Tank", + ATMOS_GAS_MONITOR_SENSOR_AIR = "Mixed Air Tank", + ATMOS_GAS_MONITOR_SENSOR_MIX = "Mix Tank", + ATMOS_GAS_MONITOR_LOOP_DISTRIBUTION = "Distribution Loop", + ATMOS_GAS_MONITOR_LOOP_ATMOS_WASTE = "Atmos Waste Loop", + ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber", + ATMOS_GAS_MONITOR_SENSOR_TOXINS_LAB = "Toxins Mixing Chamber" + ) + var/list/sensor_information = list() + var/datum/radio_frequency/radio_connection + + light_color = LIGHT_COLOR_CYAN + +/obj/machinery/computer/atmos_control/Initialize() + . = ..() + GLOB.atmos_air_controllers += src + set_frequency(frequency) + +/obj/machinery/computer/atmos_control/Destroy() + GLOB.atmos_air_controllers -= src + SSradio.remove_object(src, frequency) + return ..() + +/obj/machinery/computer/atmos_control/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, "atmos_control", name, 400, 925, master_ui, state) + ui.open() + +/obj/machinery/computer/atmos_control/ui_data(mob/user) + var/data = list() + + data["sensors"] = list() + for(var/id_tag in sensors) + var/long_name = sensors[id_tag] + var/list/info = sensor_information[id_tag] + if(!info) + continue + data["sensors"] += list(list( + "id_tag" = id_tag, + "long_name" = sanitize(long_name), + "pressure" = info["pressure"], + "temperature" = info["temperature"], + "gases" = info["gases"] + )) + return data + +/obj/machinery/computer/atmos_control/receive_signal(datum/signal/signal) + if(!signal) + return + + var/id_tag = signal.data["id_tag"] + if(!id_tag || !sensors.Find(id_tag)) + return + + sensor_information[id_tag] = signal.data + +/obj/machinery/computer/atmos_control/proc/set_frequency(new_frequency) + SSradio.remove_object(src, frequency) + frequency = new_frequency + radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA) + +///////////////////////////////////////////////////////////// +// LARGE TANK CONTROL +///////////////////////////////////////////////////////////// + +/obj/machinery/computer/atmos_control/tank + var/input_tag + var/output_tag + frequency = FREQ_ATMOS_STORAGE + circuit = /obj/item/circuitboard/computer/atmos_control/tank + + var/list/input_info + var/list/output_info + +/obj/machinery/computer/atmos_control/tank/oxygen_tank + name = "Oxygen Supply Control" + input_tag = ATMOS_GAS_MONITOR_INPUT_O2 + output_tag = ATMOS_GAS_MONITOR_OUTPUT_O2 + sensors = list(ATMOS_GAS_MONITOR_SENSOR_O2 = "Oxygen Tank") + +/obj/machinery/computer/atmos_control/tank/toxin_tank + name = "Plasma Supply Control" + input_tag = ATMOS_GAS_MONITOR_INPUT_TOX + output_tag = ATMOS_GAS_MONITOR_OUTPUT_TOX + sensors = list(ATMOS_GAS_MONITOR_SENSOR_TOX = "Plasma Tank") + +/obj/machinery/computer/atmos_control/tank/air_tank + name = "Mixed Air Supply Control" + input_tag = ATMOS_GAS_MONITOR_INPUT_AIR + output_tag = ATMOS_GAS_MONITOR_OUTPUT_AIR + sensors = list(ATMOS_GAS_MONITOR_SENSOR_AIR = "Air Mix Tank") + +/obj/machinery/computer/atmos_control/tank/mix_tank + name = "Gas Mix Tank Control" + input_tag = ATMOS_GAS_MONITOR_INPUT_MIX + output_tag = ATMOS_GAS_MONITOR_OUTPUT_MIX + sensors = list(ATMOS_GAS_MONITOR_SENSOR_MIX = "Gas Mix Tank") + +/obj/machinery/computer/atmos_control/tank/nitrous_tank + name = "Nitrous Oxide Supply Control" + input_tag = ATMOS_GAS_MONITOR_INPUT_N2O + output_tag = ATMOS_GAS_MONITOR_OUTPUT_N2O + sensors = list(ATMOS_GAS_MONITOR_SENSOR_N2O = "Nitrous Oxide Tank") + +/obj/machinery/computer/atmos_control/tank/nitrogen_tank + name = "Nitrogen Supply Control" + input_tag = ATMOS_GAS_MONITOR_INPUT_N2 + output_tag = ATMOS_GAS_MONITOR_OUTPUT_N2 + sensors = list(ATMOS_GAS_MONITOR_SENSOR_N2 = "Nitrogen Tank") + +/obj/machinery/computer/atmos_control/tank/carbon_tank + name = "Carbon Dioxide Supply Control" + input_tag = ATMOS_GAS_MONITOR_INPUT_CO2 + output_tag = ATMOS_GAS_MONITOR_OUTPUT_CO2 + sensors = list(ATMOS_GAS_MONITOR_SENSOR_CO2 = "Carbon Dioxide Tank") + +/obj/machinery/computer/atmos_control/tank/incinerator + name = "Incinerator Air Control" + input_tag = ATMOS_GAS_MONITOR_INPUT_INCINERATOR + output_tag = ATMOS_GAS_MONITOR_OUTPUT_INCINERATOR + sensors = list(ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber") + +// This hacky madness is the evidence of the fact that a lot of machines were never meant to be constructable, im so sorry you had to see this +/obj/machinery/computer/atmos_control/tank/proc/reconnect(mob/user) + var/list/IO = list() + var/datum/radio_frequency/freq = SSradio.return_frequency(FREQ_ATMOS_STORAGE) + var/list/devices = freq.devices["_default"] + for(var/obj/machinery/atmospherics/components/unary/vent_pump/U in devices) + var/list/text = splittext(U.id_tag, "_") + IO |= text[1] + for(var/obj/machinery/atmospherics/components/unary/outlet_injector/U in devices) + var/list/text = splittext(U.id, "_") + IO |= text[1] + if(!IO.len) + to_chat(user, "No machinery detected.") + var/S = input("Select the device set: ", "Selection", IO[1]) as anything in IO + if(src) + src.input_tag = "[S]_in" + src.output_tag = "[S]_out" + name = "[uppertext(S)] Supply Control" + var/list/new_devices = freq.devices["4"] + for(var/obj/machinery/air_sensor/U in new_devices) + var/list/text = splittext(U.id_tag, "_") + if(text[1] == S) + sensors = list("[S]_sensor" = "Tank") + break + + for(var/obj/machinery/atmospherics/components/unary/outlet_injector/U in devices) + U.broadcast_status() + for(var/obj/machinery/atmospherics/components/unary/vent_pump/U in devices) + U.broadcast_status() + +/obj/machinery/computer/atmos_control/tank/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, "atmos_control", name, 500, 305, master_ui, state) + ui.open() + +/obj/machinery/computer/atmos_control/tank/ui_data(mob/user) + var/list/data = ..() + data["tank"] = TRUE + data["inputting"] = input_info ? input_info["power"] : FALSE + data["inputRate"] = input_info ? input_info["volume_rate"] : 0 + data["outputting"] = output_info ? output_info["power"] : FALSE + data["outputPressure"] = output_info ? output_info["internal"] : 0 + + return data + +/obj/machinery/computer/atmos_control/tank/ui_act(action, params) + if(..() || !radio_connection) + return + var/datum/signal/signal = new(list("sigtype" = "command", "user" = usr)) + switch(action) + if("reconnect") + reconnect(usr) + . = TRUE + if("input") + signal.data += list("tag" = input_tag, "power_toggle" = TRUE) + . = TRUE + if("output") + signal.data += list("tag" = output_tag, "power_toggle" = TRUE) + . = TRUE + if("pressure") + var/target = input("New target pressure:", name, output_info ? output_info["internal"] : 0) as num|null + if(!isnull(target) && !..()) + target = CLAMP(target, 0, 50 * ONE_ATMOSPHERE) + signal.data += list("tag" = output_tag, "set_internal_pressure" = target) + . = TRUE + radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) + +/obj/machinery/computer/atmos_control/tank/receive_signal(datum/signal/signal) + if(!signal) + return + + var/id_tag = signal.data["tag"] + + if(input_tag == id_tag) + input_info = signal.data + else if(output_tag == id_tag) + output_info = signal.data + else + ..(signal) diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index e8e15ff586..a21ebbeccf 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -1,145 +1,145 @@ -/obj/structure/frame/computer - name = "computer frame" - icon_state = "0" - state = 0 - -/obj/structure/frame/computer/attackby(obj/item/P, mob/user, params) - add_fingerprint(user) - switch(state) - if(0) - if(istype(P, /obj/item/wrench)) - to_chat(user, "You start wrenching the frame into place...") - if(P.use_tool(src, user, 20, volume=50)) - to_chat(user, "You wrench the frame into place.") - setAnchored(TRUE) - state = 1 - return - if(istype(P, /obj/item/weldingtool)) - if(!P.tool_start_check(user, amount=0)) - return - - to_chat(user, "You start deconstructing the frame...") - if(P.use_tool(src, user, 20, volume=50) && state == 0) - to_chat(user, "You deconstruct the frame.") - var/obj/item/stack/sheet/metal/M = new (drop_location(), 5) - M.add_fingerprint(user) - qdel(src) - return - if(1) - if(istype(P, /obj/item/wrench)) - to_chat(user, "You start to unfasten the frame...") - if(P.use_tool(src, user, 20, volume=50) && state == 1) - to_chat(user, "You unfasten the frame.") - setAnchored(FALSE) - state = 0 - return - if(istype(P, /obj/item/circuitboard/computer) && !circuit) - if(!user.transferItemToLoc(P, src)) - return - playsound(src, 'sound/items/deconstruct.ogg', 50, 1) - to_chat(user, "You place [P] inside the frame.") - icon_state = "1" - circuit = P - circuit.add_fingerprint(user) - return - - else if(istype(P, /obj/item/circuitboard) && !circuit) - to_chat(user, "This frame does not accept circuit boards of this type!") - return - if(istype(P, /obj/item/screwdriver) && circuit) - P.play_tool_sound(src) - to_chat(user, "You screw [circuit] into place.") - state = 2 - icon_state = "2" - return - if(istype(P, /obj/item/crowbar) && circuit) - P.play_tool_sound(src) - to_chat(user, "You remove [circuit].") - state = 1 - icon_state = "0" - circuit.forceMove(drop_location()) - circuit.add_fingerprint(user) - circuit = null - return - if(2) - if(istype(P, /obj/item/screwdriver) && circuit) - P.play_tool_sound(src) - to_chat(user, "You unfasten the circuit board.") - state = 1 - icon_state = "1" - return - if(istype(P, /obj/item/stack/cable_coil)) - if(!P.tool_start_check(user, amount=5)) - return - to_chat(user, "You start adding cables to the frame...") - if(P.use_tool(src, user, 20, 5, 50, CALLBACK(src, .proc/check_state, 2))) - to_chat(user, "You add cables to the frame.") - state = 3 - icon_state = "3" - return - if(3) - if(istype(P, /obj/item/wirecutters)) - P.play_tool_sound(src) - to_chat(user, "You remove the cables.") - state = 2 - icon_state = "2" - var/obj/item/stack/cable_coil/A = new (drop_location(), 5) - A.add_fingerprint(user) - return - - if(istype(P, /obj/item/stack/sheet/glass)) - if(!P.tool_start_check(user, amount=2)) - return - playsound(src, 'sound/items/deconstruct.ogg', 50, 1) - to_chat(user, "You start to put in the glass panel...") - if(P.use_tool(src, user, 20, 2, 0, CALLBACK(src, .proc/check_state, 3))) - to_chat(user, "You put in the glass panel.") - state = 4 - src.icon_state = "4" - return - if(4) - if(istype(P, /obj/item/crowbar)) - P.play_tool_sound(src) - to_chat(user, "You remove the glass panel.") - state = 3 - icon_state = "3" - var/obj/item/stack/sheet/glass/G = new(drop_location(), 2) - G.add_fingerprint(user) - return - if(istype(P, /obj/item/screwdriver)) - P.play_tool_sound(src) - to_chat(user, "You connect the monitor.") - var/obj/B = new circuit.build_path (loc, circuit) - B.setDir(dir) - transfer_fingerprints_to(B) - qdel(src) - return - if(user.a_intent == INTENT_HARM) - return ..() - -//callback proc used on stacks use_tool to stop unnecessary amounts being wasted from spam clicking. -/obj/structure/frame/computer/proc/check_state(target_state) - if(state == target_state) - return TRUE - return FALSE - -/obj/structure/frame/computer/deconstruct(disassembled = TRUE) - if(!(flags_1 & NODECONSTRUCT_1)) - if(state == 4) - new /obj/item/shard(drop_location()) - new /obj/item/shard(drop_location()) - if(state >= 3) - new /obj/item/stack/cable_coil(drop_location(), 5) - ..() - -/obj/structure/frame/computer/AltClick(mob/user) - . = ..() - if(!isliving(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) - return - - if(anchored) - to_chat(usr, "You must unwrench [src] before rotating it!") - return TRUE - - setDir(turn(dir, -90)) - return TRUE +/obj/structure/frame/computer + name = "computer frame" + icon_state = "0" + state = 0 + +/obj/structure/frame/computer/attackby(obj/item/P, mob/user, params) + add_fingerprint(user) + switch(state) + if(0) + if(istype(P, /obj/item/wrench)) + to_chat(user, "You start wrenching the frame into place...") + if(P.use_tool(src, user, 20, volume=50)) + to_chat(user, "You wrench the frame into place.") + setAnchored(TRUE) + state = 1 + return + if(istype(P, /obj/item/weldingtool)) + if(!P.tool_start_check(user, amount=0)) + return + + to_chat(user, "You start deconstructing the frame...") + if(P.use_tool(src, user, 20, volume=50) && state == 0) + to_chat(user, "You deconstruct the frame.") + var/obj/item/stack/sheet/metal/M = new (drop_location(), 5) + M.add_fingerprint(user) + qdel(src) + return + if(1) + if(istype(P, /obj/item/wrench)) + to_chat(user, "You start to unfasten the frame...") + if(P.use_tool(src, user, 20, volume=50) && state == 1) + to_chat(user, "You unfasten the frame.") + setAnchored(FALSE) + state = 0 + return + if(istype(P, /obj/item/circuitboard/computer) && !circuit) + if(!user.transferItemToLoc(P, src)) + return + playsound(src, 'sound/items/deconstruct.ogg', 50, 1) + to_chat(user, "You place [P] inside the frame.") + icon_state = "1" + circuit = P + circuit.add_fingerprint(user) + return + + else if(istype(P, /obj/item/circuitboard) && !circuit) + to_chat(user, "This frame does not accept circuit boards of this type!") + return + if(istype(P, /obj/item/screwdriver) && circuit) + P.play_tool_sound(src) + to_chat(user, "You screw [circuit] into place.") + state = 2 + icon_state = "2" + return + if(istype(P, /obj/item/crowbar) && circuit) + P.play_tool_sound(src) + to_chat(user, "You remove [circuit].") + state = 1 + icon_state = "0" + circuit.forceMove(drop_location()) + circuit.add_fingerprint(user) + circuit = null + return + if(2) + if(istype(P, /obj/item/screwdriver) && circuit) + P.play_tool_sound(src) + to_chat(user, "You unfasten the circuit board.") + state = 1 + icon_state = "1" + return + if(istype(P, /obj/item/stack/cable_coil)) + if(!P.tool_start_check(user, amount=5)) + return + to_chat(user, "You start adding cables to the frame...") + if(P.use_tool(src, user, 20, 5, 50, CALLBACK(src, .proc/check_state, 2))) + to_chat(user, "You add cables to the frame.") + state = 3 + icon_state = "3" + return + if(3) + if(istype(P, /obj/item/wirecutters)) + P.play_tool_sound(src) + to_chat(user, "You remove the cables.") + state = 2 + icon_state = "2" + var/obj/item/stack/cable_coil/A = new (drop_location(), 5) + A.add_fingerprint(user) + return + + if(istype(P, /obj/item/stack/sheet/glass)) + if(!P.tool_start_check(user, amount=2)) + return + playsound(src, 'sound/items/deconstruct.ogg', 50, 1) + to_chat(user, "You start to put in the glass panel...") + if(P.use_tool(src, user, 20, 2, 0, CALLBACK(src, .proc/check_state, 3))) + to_chat(user, "You put in the glass panel.") + state = 4 + src.icon_state = "4" + return + if(4) + if(istype(P, /obj/item/crowbar)) + P.play_tool_sound(src) + to_chat(user, "You remove the glass panel.") + state = 3 + icon_state = "3" + var/obj/item/stack/sheet/glass/G = new(drop_location(), 2) + G.add_fingerprint(user) + return + if(istype(P, /obj/item/screwdriver)) + P.play_tool_sound(src) + to_chat(user, "You connect the monitor.") + var/obj/B = new circuit.build_path (loc, circuit) + B.setDir(dir) + transfer_fingerprints_to(B) + qdel(src) + return + if(user.a_intent == INTENT_HARM) + return ..() + +//callback proc used on stacks use_tool to stop unnecessary amounts being wasted from spam clicking. +/obj/structure/frame/computer/proc/check_state(target_state) + if(state == target_state) + return TRUE + return FALSE + +/obj/structure/frame/computer/deconstruct(disassembled = TRUE) + if(!(flags_1 & NODECONSTRUCT_1)) + if(state == 4) + new /obj/item/shard(drop_location()) + new /obj/item/shard(drop_location()) + if(state >= 3) + new /obj/item/stack/cable_coil(drop_location(), 5) + ..() + +/obj/structure/frame/computer/AltClick(mob/user) + . = ..() + if(!isliving(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) + return + + if(anchored) + to_chat(usr, "You must unwrench [src] before rotating it!") + return TRUE + + setDir(turn(dir, -90)) + return TRUE diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 1bafa73aaa..1d54e8f772 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -1,254 +1,254 @@ -/obj/machinery/computer/security - name = "security camera console" - desc = "Used to access the various cameras on the station." - icon_screen = "cameras" - icon_keyboard = "security_key" - circuit = /obj/item/circuitboard/computer/security - var/last_pic = 1 - var/list/network = list("ss13") - var/list/watchers = list() //who's using the console, associated with the camera they're on. - - light_color = LIGHT_COLOR_RED - -/obj/machinery/computer/security/Initialize() - . = ..() - for(var/i in network) - network -= i - network += lowertext(i) - -/obj/machinery/computer/security/check_eye(mob/user) - if(!can_interact(user) || !(user in watchers) || !watchers[user]) - user.unset_machine() - return - var/obj/machinery/camera/C = watchers[user] - if(!C.can_use()) - user.unset_machine() - return - -/obj/machinery/computer/security/on_unset_machine(mob/user) - watchers.Remove(user) - user.reset_perspective(null) - -/obj/machinery/computer/security/Destroy() - if(watchers.len) - for(var/mob/M in watchers) - M.unset_machine() //to properly reset the view of the users if the console is deleted. - return ..() - -/obj/machinery/computer/security/can_interact(mob/user) - if((!issilicon(user) && !Adjacent(user)) || is_blind(user) || !in_view_range(user, src)) - return FALSE - return ..() - -/obj/machinery/computer/security/interact(mob/user, special_state) - . = ..() - if (ismob(user) && !isliving(user)) // ghosts don't need cameras - return - if (!network) - CRASH("No camera network") - user.unset_machine() - return FALSE - if (!(islist(network))) - CRASH("Camera network is not a list") - user.unset_machine() - return FALSE - - var/list/camera_list = get_available_cameras() - if(!(user in watchers)) - for(var/Num in camera_list) - var/obj/machinery/camera/CAM = camera_list[Num] - if(istype(CAM) && CAM.can_use()) - watchers[user] = CAM //let's give the user the first usable camera, and then let him change to the camera he wants. - break - if(!(user in watchers)) - user.unset_machine() // no usable camera on the network, we disconnect the user from the computer. - return FALSE - playsound(src, 'sound/machines/terminal_prompt.ogg', 25, 0) - use_camera_console(user) - -/obj/machinery/computer/security/proc/use_camera_console(mob/user) - var/list/camera_list = get_available_cameras() - var/t = input(user, "Which camera should you change to?") as null|anything in camera_list - if(!src || user.machine != src) //while we were choosing we got disconnected from our computer or are using another machine. - return - if(!t || t == "Cancel") - user.unset_machine() - playsound(src, 'sound/machines/terminal_off.ogg', 25, 0) - return - - var/obj/machinery/camera/C = camera_list[t] - - if(!C || !C.can_use() || !can_interact(user)) - user.unset_machine() - return FALSE - - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0) - if(isAI(user)) - var/mob/living/silicon/ai/A = user - A.eyeobj.setLoc(get_turf(C)) - A.client.eye = A.eyeobj - else - user.reset_perspective(C) - user.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static) - user.clear_fullscreen("flash", 5) - watchers[user] = C - use_power(50) - addtimer(CALLBACK(src, .proc/use_camera_console, user), 5) - -//returns the list of cameras accessible from this computer -/obj/machinery/computer/security/proc/get_available_cameras() - var/list/L = list() - for (var/obj/machinery/camera/C in GLOB.cameranet.cameras) - if((is_away_level(z) || is_away_level(C.z)) && (C.z != z))//if on away mission, can only receive feed from same z_level cameras - continue - L.Add(C) - - camera_sort(L) - - var/list/D = list() - D["Cancel"] = "Cancel" - for(var/obj/machinery/camera/C in L) - if(!C.network) - stack_trace("Camera in a cameranet has no camera network") - continue - if(!(islist(C.network))) - stack_trace("Camera in a cameranet has a non-list camera network") - continue - var/list/tempnetwork = C.network&network - if(tempnetwork.len) - D["[C.c_tag][(C.status ? null : " (Deactivated)")]"] = C - return D - -// SECURITY MONITORS - -/obj/machinery/computer/security/wooden_tv - name = "security camera monitor" - desc = "An old TV hooked into the station's camera network." - icon_state = "television" - icon_keyboard = null - icon_screen = "detective_tv" - clockwork = TRUE //it'd look weird - pass_flags = PASSTABLE - -/obj/machinery/computer/security/mining - name = "outpost camera console" - desc = "Used to access the various cameras on the outpost." - icon_screen = "mining" - icon_keyboard = "mining_key" - network = list("mine", "auxbase") - circuit = /obj/item/circuitboard/computer/mining - -/obj/machinery/computer/security/research - name = "research camera console" - desc = "Used to access the various cameras in science." - network = list("rd") - circuit = /obj/item/circuitboard/computer/research - -/obj/machinery/computer/security/hos - name = "Head of Security's camera console" - desc = "A custom security console with added access to the labor camp network." - network = list("ss13", "labor") - circuit = null - -/obj/machinery/computer/security/labor - name = "labor camp monitoring" - desc = "Used to access the various cameras on the labor camp." - network = list("labor") - circuit = null - -/obj/machinery/computer/security/qm - name = "Quartermaster's camera console" - desc = "A console with access to the mining, auxillary base and vault camera networks." - network = list("mine", "auxbase", "vault") - circuit = null - -// TELESCREENS - -/obj/machinery/computer/security/telescreen - name = "\improper Telescreen" - desc = "Used for watching an empty arena." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "telescreen" - network = list("thunder") - density = FALSE - circuit = null - clockwork = TRUE //it'd look very weird - light_power = 0 - -/obj/machinery/computer/security/telescreen/update_icon() - icon_state = initial(icon_state) - if(stat & BROKEN) - icon_state += "b" - return - -/obj/machinery/computer/security/telescreen/entertainment - name = "entertainment monitor" - desc = "Damn, they better have the /tg/ channel on these things." - icon = 'icons/obj/status_display.dmi' - icon_state = "entertainment" - network = list("thunder") - -/obj/machinery/computer/security/telescreen/rd - name = "Research Director's telescreen" - desc = "Used for watching the AI and the RD's goons from the safety of his office." - network = list("rd", "aicore", "aiupload", "minisat", "xeno", "test") - -/obj/machinery/computer/security/telescreen/circuitry - name = "circuitry telescreen" - desc = "Used for watching the other eggheads from the safety of the circuitry lab." - network = list("rd") - -/obj/machinery/computer/security/telescreen/ce - name = "Chief Engineer's telescreen" - desc = "Used for watching the engine, telecommunications and the minisat." - network = list("engine", "singularity", "tcomms", "minisat") - -/obj/machinery/computer/security/telescreen/cmo - name = "Chief Medical Officer's telescreen" - desc = "A telescreen with access to the medbay's camera network." - network = list("medbay") - -/obj/machinery/computer/security/telescreen/vault - name = "Vault monitor" - desc = "A telescreen that connects to the vault's camera network." - network = list("vault") - -/obj/machinery/computer/security/telescreen/toxins - name = "Bomb test site monitor" - desc = "A telescreen that connects to the bomb test site's camera." - network = list("toxin") - -/obj/machinery/computer/security/telescreen/engine - name = "engine monitor" - desc = "A telescreen that connects to the engine's camera network." - network = list("engine") - -/obj/machinery/computer/security/telescreen/turbine - name = "turbine monitor" - desc = "A telescreen that connects to the turbine's camera." - network = list("turbine") - -/obj/machinery/computer/security/telescreen/interrogation - name = "interrogation room monitor" - desc = "A telescreen that connects to the interrogation room's camera." - network = list("interrogation") - -/obj/machinery/computer/security/telescreen/prison - name = "prison monitor" - desc = "A telescreen that connects to the permabrig's camera network." - network = list("prison") - -/obj/machinery/computer/security/telescreen/auxbase - name = "auxillary base monitor" - desc = "A telescreen that connects to the auxillary base's camera." - network = list("auxbase") - -/obj/machinery/computer/security/telescreen/minisat - name = "minisat monitor" - desc = "A telescreen that connects to the minisat's camera network." - network = list("minisat") - -/obj/machinery/computer/security/telescreen/aiupload - name = "AI upload monitor" - desc = "A telescreen that connects to the AI upload's camera network." - network = list("aiupload") +/obj/machinery/computer/security + name = "security camera console" + desc = "Used to access the various cameras on the station." + icon_screen = "cameras" + icon_keyboard = "security_key" + circuit = /obj/item/circuitboard/computer/security + var/last_pic = 1 + var/list/network = list("ss13") + var/list/watchers = list() //who's using the console, associated with the camera they're on. + + light_color = LIGHT_COLOR_RED + +/obj/machinery/computer/security/Initialize() + . = ..() + for(var/i in network) + network -= i + network += lowertext(i) + +/obj/machinery/computer/security/check_eye(mob/user) + if(!can_interact(user) || !(user in watchers) || !watchers[user]) + user.unset_machine() + return + var/obj/machinery/camera/C = watchers[user] + if(!C.can_use()) + user.unset_machine() + return + +/obj/machinery/computer/security/on_unset_machine(mob/user) + watchers.Remove(user) + user.reset_perspective(null) + +/obj/machinery/computer/security/Destroy() + if(watchers.len) + for(var/mob/M in watchers) + M.unset_machine() //to properly reset the view of the users if the console is deleted. + return ..() + +/obj/machinery/computer/security/can_interact(mob/user) + if((!issilicon(user) && !Adjacent(user)) || is_blind(user) || !in_view_range(user, src)) + return FALSE + return ..() + +/obj/machinery/computer/security/interact(mob/user, special_state) + . = ..() + if (ismob(user) && !isliving(user)) // ghosts don't need cameras + return + if (!network) + CRASH("No camera network") + user.unset_machine() + return FALSE + if (!(islist(network))) + CRASH("Camera network is not a list") + user.unset_machine() + return FALSE + + var/list/camera_list = get_available_cameras() + if(!(user in watchers)) + for(var/Num in camera_list) + var/obj/machinery/camera/CAM = camera_list[Num] + if(istype(CAM) && CAM.can_use()) + watchers[user] = CAM //let's give the user the first usable camera, and then let him change to the camera he wants. + break + if(!(user in watchers)) + user.unset_machine() // no usable camera on the network, we disconnect the user from the computer. + return FALSE + playsound(src, 'sound/machines/terminal_prompt.ogg', 25, 0) + use_camera_console(user) + +/obj/machinery/computer/security/proc/use_camera_console(mob/user) + var/list/camera_list = get_available_cameras() + var/t = input(user, "Which camera should you change to?") as null|anything in camera_list + if(!src || user.machine != src) //while we were choosing we got disconnected from our computer or are using another machine. + return + if(!t || t == "Cancel") + user.unset_machine() + playsound(src, 'sound/machines/terminal_off.ogg', 25, 0) + return + + var/obj/machinery/camera/C = camera_list[t] + + if(!C || !C.can_use() || !can_interact(user)) + user.unset_machine() + return FALSE + + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0) + if(isAI(user)) + var/mob/living/silicon/ai/A = user + A.eyeobj.setLoc(get_turf(C)) + A.client.eye = A.eyeobj + else + user.reset_perspective(C) + user.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static) + user.clear_fullscreen("flash", 5) + watchers[user] = C + use_power(50) + addtimer(CALLBACK(src, .proc/use_camera_console, user), 5) + +//returns the list of cameras accessible from this computer +/obj/machinery/computer/security/proc/get_available_cameras() + var/list/L = list() + for (var/obj/machinery/camera/C in GLOB.cameranet.cameras) + if((is_away_level(z) || is_away_level(C.z)) && (C.z != z))//if on away mission, can only receive feed from same z_level cameras + continue + L.Add(C) + + camera_sort(L) + + var/list/D = list() + D["Cancel"] = "Cancel" + for(var/obj/machinery/camera/C in L) + if(!C.network) + stack_trace("Camera in a cameranet has no camera network") + continue + if(!(islist(C.network))) + stack_trace("Camera in a cameranet has a non-list camera network") + continue + var/list/tempnetwork = C.network&network + if(tempnetwork.len) + D["[C.c_tag][(C.status ? null : " (Deactivated)")]"] = C + return D + +// SECURITY MONITORS + +/obj/machinery/computer/security/wooden_tv + name = "security camera monitor" + desc = "An old TV hooked into the station's camera network." + icon_state = "television" + icon_keyboard = null + icon_screen = "detective_tv" + clockwork = TRUE //it'd look weird + pass_flags = PASSTABLE + +/obj/machinery/computer/security/mining + name = "outpost camera console" + desc = "Used to access the various cameras on the outpost." + icon_screen = "mining" + icon_keyboard = "mining_key" + network = list("mine", "auxbase") + circuit = /obj/item/circuitboard/computer/mining + +/obj/machinery/computer/security/research + name = "research camera console" + desc = "Used to access the various cameras in science." + network = list("rd") + circuit = /obj/item/circuitboard/computer/research + +/obj/machinery/computer/security/hos + name = "Head of Security's camera console" + desc = "A custom security console with added access to the labor camp network." + network = list("ss13", "labor") + circuit = null + +/obj/machinery/computer/security/labor + name = "labor camp monitoring" + desc = "Used to access the various cameras on the labor camp." + network = list("labor") + circuit = null + +/obj/machinery/computer/security/qm + name = "Quartermaster's camera console" + desc = "A console with access to the mining, auxillary base and vault camera networks." + network = list("mine", "auxbase", "vault") + circuit = null + +// TELESCREENS + +/obj/machinery/computer/security/telescreen + name = "\improper Telescreen" + desc = "Used for watching an empty arena." + icon = 'icons/obj/stationobjs.dmi' + icon_state = "telescreen" + network = list("thunder") + density = FALSE + circuit = null + clockwork = TRUE //it'd look very weird + light_power = 0 + +/obj/machinery/computer/security/telescreen/update_icon() + icon_state = initial(icon_state) + if(stat & BROKEN) + icon_state += "b" + return + +/obj/machinery/computer/security/telescreen/entertainment + name = "entertainment monitor" + desc = "Damn, they better have the /tg/ channel on these things." + icon = 'icons/obj/status_display.dmi' + icon_state = "entertainment" + network = list("thunder") + +/obj/machinery/computer/security/telescreen/rd + name = "Research Director's telescreen" + desc = "Used for watching the AI and the RD's goons from the safety of his office." + network = list("rd", "aicore", "aiupload", "minisat", "xeno", "test") + +/obj/machinery/computer/security/telescreen/circuitry + name = "circuitry telescreen" + desc = "Used for watching the other eggheads from the safety of the circuitry lab." + network = list("rd") + +/obj/machinery/computer/security/telescreen/ce + name = "Chief Engineer's telescreen" + desc = "Used for watching the engine, telecommunications and the minisat." + network = list("engine", "singularity", "tcomms", "minisat") + +/obj/machinery/computer/security/telescreen/cmo + name = "Chief Medical Officer's telescreen" + desc = "A telescreen with access to the medbay's camera network." + network = list("medbay") + +/obj/machinery/computer/security/telescreen/vault + name = "Vault monitor" + desc = "A telescreen that connects to the vault's camera network." + network = list("vault") + +/obj/machinery/computer/security/telescreen/toxins + name = "Bomb test site monitor" + desc = "A telescreen that connects to the bomb test site's camera." + network = list("toxin") + +/obj/machinery/computer/security/telescreen/engine + name = "engine monitor" + desc = "A telescreen that connects to the engine's camera network." + network = list("engine") + +/obj/machinery/computer/security/telescreen/turbine + name = "turbine monitor" + desc = "A telescreen that connects to the turbine's camera." + network = list("turbine") + +/obj/machinery/computer/security/telescreen/interrogation + name = "interrogation room monitor" + desc = "A telescreen that connects to the interrogation room's camera." + network = list("interrogation") + +/obj/machinery/computer/security/telescreen/prison + name = "prison monitor" + desc = "A telescreen that connects to the permabrig's camera network." + network = list("prison") + +/obj/machinery/computer/security/telescreen/auxbase + name = "auxillary base monitor" + desc = "A telescreen that connects to the auxillary base's camera." + network = list("auxbase") + +/obj/machinery/computer/security/telescreen/minisat + name = "minisat monitor" + desc = "A telescreen that connects to the minisat's camera network." + network = list("minisat") + +/obj/machinery/computer/security/telescreen/aiupload + name = "AI upload monitor" + desc = "A telescreen that connects to the AI upload's camera network." + network = list("aiupload") diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm index 3bdb635d39..6703bae525 100644 --- a/code/game/machinery/computer/card.dm +++ b/code/game/machinery/computer/card.dm @@ -1,630 +1,630 @@ - - -//Keeps track of the time for the ID console. Having it as a global variable prevents people from dismantling/reassembling it to -//increase the slots of many jobs. -GLOBAL_VAR_INIT(time_last_changed_position, 0) - -#define JOB_ALLOWED 1 -#define JOB_COOLDOWN -2 -#define JOB_MAX_POSITIONS -1 // Trying to reduce the number of slots below that of current holders of that job, or trying to open more slots than allowed -#define JOB_DENIED 0 - -/obj/machinery/computer/card - name = "identification console" - desc = "You can use this to manage jobs and ID access." - icon_screen = "id" - icon_keyboard = "id_key" - req_one_access = list(ACCESS_HEADS, ACCESS_CHANGE_IDS) - circuit = /obj/item/circuitboard/computer/card - var/mode = 0 - var/printing = null - var/target_dept = 0 //Which department this computer has access to. 0=all departments - - //Cooldown for closing positions in seconds - //if set to -1: No cooldown... probably a bad idea - //if set to 0: Not able to close "original" positions. You can only close positions that you have opened before - var/change_position_cooldown = 30 - //Jobs you cannot open new positions for - var/list/blacklisted = list( - "AI", - "Assistant", - "Cyborg", - "Captain", - "Head of Personnel", - "Head of Security", - "Chief Engineer", - "Research Director", - "Chief Medical Officer", - "Quartermaster") - - //The scaling factor of max total positions in relation to the total amount of people on board the station in % - var/max_relative_positions = 30 //30%: Seems reasonable, limit of 6 @ 20 players - - //This is used to keep track of opened positions for jobs to allow instant closing - //Assoc array: "JobName" = (int) - var/list/opened_positions = list() - var/obj/item/card/id/inserted_scan_id - var/obj/item/card/id/inserted_modify_id - var/list/region_access = null - var/list/head_subordinates = null - - light_color = LIGHT_COLOR_BLUE - -/obj/machinery/computer/card/proc/get_jobs() - return get_all_jobs() - -/obj/machinery/computer/card/centcom/get_jobs() - return get_all_centcom_jobs() - -/obj/machinery/computer/card/Initialize() - . = ..() - change_position_cooldown = CONFIG_GET(number/id_console_jobslot_delay) - -/obj/machinery/computer/card/examine(mob/user) - . = ..() - if(inserted_scan_id || inserted_modify_id) - . += "Alt-click to eject the ID card." - -/obj/machinery/computer/card/attackby(obj/I, mob/user, params) - if(isidcard(I)) - if(check_access(I) && !inserted_scan_id) - if(id_insert(user, I, inserted_scan_id)) - inserted_scan_id = I - updateUsrDialog() - else if(id_insert(user, I, inserted_modify_id)) - inserted_modify_id = I - updateUsrDialog() - else - return ..() - -/obj/machinery/computer/card/Destroy() - if(inserted_scan_id) - qdel(inserted_scan_id) - inserted_scan_id = null - if(inserted_modify_id) - qdel(inserted_modify_id) - inserted_modify_id = null - return ..() - -/obj/machinery/computer/card/handle_atom_del(atom/A) - ..() - if(A == inserted_scan_id) - inserted_scan_id = null - updateUsrDialog() - if(A == inserted_modify_id) - inserted_modify_id = null - updateUsrDialog() - -/obj/machinery/computer/card/on_deconstruction() - if(inserted_scan_id) - inserted_scan_id.forceMove(drop_location()) - inserted_scan_id = null - if(inserted_modify_id) - inserted_modify_id.forceMove(drop_location()) - inserted_modify_id = null - -//Check if you can't open a new position for a certain job -/obj/machinery/computer/card/proc/job_blacklisted(jobtitle) - return (jobtitle in blacklisted) - -//Logic check for Topic() if you can open the job -/obj/machinery/computer/card/proc/can_open_job(datum/job/job) - if(job) - if(!job_blacklisted(job.title)) - if((job.total_positions <= GLOB.player_list.len * (max_relative_positions / 100))) - var/delta = (world.time / 10) - GLOB.time_last_changed_position - if((change_position_cooldown < delta) || (opened_positions[job.title] < 0)) - return JOB_ALLOWED - return JOB_COOLDOWN - return JOB_MAX_POSITIONS - return JOB_DENIED - -//Logic check for Topic() if you can close the job -/obj/machinery/computer/card/proc/can_close_job(datum/job/job) - if(job) - if(!job_blacklisted(job.title)) - if(job.total_positions > job.current_positions) - var/delta = (world.time / 10) - GLOB.time_last_changed_position - if((change_position_cooldown < delta) || (opened_positions[job.title] > 0)) - return JOB_ALLOWED - return JOB_COOLDOWN - return JOB_MAX_POSITIONS - return JOB_DENIED - - -/obj/machinery/computer/card/proc/id_insert(mob/user, obj/item/inserting_item, obj/item/target) - var/obj/item/card/id/card_to_insert = inserting_item - var/holder_item = FALSE - - if(!isidcard(card_to_insert)) - card_to_insert = inserting_item.RemoveID() - holder_item = TRUE - - if(!card_to_insert || !user.transferItemToLoc(card_to_insert, src)) - return FALSE - - if(target) - if(holder_item && inserting_item.InsertID(target)) - playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) - else - id_eject(user, target) - - user.visible_message("[user] inserts \the [card_to_insert] into \the [src].", - "You insert \the [card_to_insert] into \the [src].") - playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) - updateUsrDialog() - return TRUE - -/obj/machinery/computer/card/proc/id_eject(mob/user, obj/target) - if(!target) - to_chat(user, "That slot is empty!") - return FALSE - else - target.forceMove(drop_location()) - if(!issilicon(user) && Adjacent(user)) - user.put_in_hands(target) - user.visible_message("[user] gets \the [target] from \the [src].", \ - "You get \the [target] from \the [src].") - playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) - updateUsrDialog() - return TRUE - -/obj/machinery/computer/card/AltClick(mob/user) - . = ..() - if(!user.canUseTopic(src, !issilicon(user)) || !is_operational()) - return - if(inserted_modify_id) - if(id_eject(user, inserted_modify_id)) - inserted_modify_id = null - updateUsrDialog() - return TRUE - if(inserted_scan_id) - if(id_eject(user, inserted_scan_id)) - inserted_scan_id = null - updateUsrDialog() - return TRUE - -/obj/machinery/computer/card/ui_interact(mob/user) - . = ..() - var/list/dat = list() - if (mode == 1) // accessing crew manifest - dat += "Crew Manifest:
      Please use security record computer to modify entries.

      " - for(var/datum/data/record/t in sortRecord(GLOB.data_core.general)) - dat += {"[t.fields["name"]] - [t.fields["rank"]]
      "} - dat += "Print

      Access ID modification console.
      " - - else if(mode == 2) - // JOB MANAGEMENT - dat += {"Return - - "} - for(var/datum/job/job in SSjob.occupations) - dat += "" - if(job.title in blacklisted) - continue - dat += {" - - " - dat += "
      JobSlotsOpen jobClose jobPrioritize
      [job.title][job.current_positions]/[job.total_positions]"} - switch(can_open_job(job)) - if(JOB_ALLOWED) - if(authenticated == 2) - dat += "Open Position
      " - else - dat += "Open Position" - if(JOB_COOLDOWN) - var/time_to_wait = round(change_position_cooldown - ((world.time / 10) - GLOB.time_last_changed_position), 1) - var/mins = round(time_to_wait / 60) - var/seconds = time_to_wait - (60*mins) - dat += "Cooldown ongoing: [mins]:[(seconds < 10) ? "0[seconds]" : "[seconds]"]" - else - dat += "Denied" - dat += "
      " - switch(can_close_job(job)) - if(JOB_ALLOWED) - if(authenticated == 2) - dat += "Close Position" - else - dat += "Close Position" - if(JOB_COOLDOWN) - var/time_to_wait = round(change_position_cooldown - ((world.time / 10) - GLOB.time_last_changed_position), 1) - var/mins = round(time_to_wait / 60) - var/seconds = time_to_wait - (60*mins) - dat += "Cooldown ongoing: [mins]:[(seconds < 10) ? "0[seconds]" : "[seconds]"]" - else - dat += "Denied" - dat += "" - switch(job.total_positions) - if(0) - dat += "Denied" - else - if(authenticated == 2) - if(job in SSjob.prioritized_jobs) - dat += "Deprioritize" - else - if(SSjob.prioritized_jobs.len < 5) - dat += "Prioritize" - else - dat += "Denied" - else - dat += "Prioritize" - - dat += "
      " - else - var/list/header = list() - - var/scan_name = inserted_scan_id ? html_encode(inserted_scan_id.name) : "--------" - var/target_name = inserted_modify_id ? html_encode(inserted_modify_id.name) : "--------" - var/target_owner = (inserted_modify_id && inserted_modify_id.registered_name) ? html_encode(inserted_modify_id.registered_name) : "--------" - var/target_rank = (inserted_modify_id && inserted_modify_id.assignment) ? html_encode(inserted_modify_id.assignment) : "Unassigned" - - if(!authenticated) - header += {"
      Please insert the cards into the slots
      - Target: [target_name]
      - Confirm Identity: [scan_name]
      "} - else - header += {"

      - Target: Remove [target_name] || - Confirm Identity: Remove [scan_name]
      - Access Crew Manifest
      - [!target_dept ? "Job Management
      " : ""] - Log Out
      "} - - header += "
      " - - var/body - - if (authenticated && inserted_modify_id) - var/list/carddesc = list() - var/list/jobs = list() - if (authenticated == 2) - var/list/jobs_all = list() - for(var/job in (list("Unassigned") + get_jobs() + "Custom")) - jobs_all += "[replacetext(job, " ", " ")] " //make sure there isn't a line break in the middle of a job - carddesc += {""} - carddesc += {"
      - - - registered name: - -
      - Assignment: "} - - jobs += "[target_rank]" //CHECK THIS - - else - carddesc += "registered_name: [target_owner]" - jobs += "Assignment: [target_rank] (Demote)" - - var/list/accesses = list() - if(istype(src, /obj/machinery/computer/card/centcom)) // REE - accesses += "
      Central Command:
      " - for(var/A in get_all_centcom_access()) - if(A in inserted_modify_id.access) - accesses += "[replacetext(get_centcom_access_desc(A), " ", " ")] " - else - accesses += "[replacetext(get_centcom_access_desc(A), " ", " ")] " - else - accesses += {"
      Access
      - - "} - for(var/i = 1; i <= 7; i++) - if(authenticated == 1 && !(i in region_access)) - continue - accesses += "" - accesses += "" - for(var/i = 1; i <= 7; i++) - if(authenticated == 1 && !(i in region_access)) - continue - accesses += "" - accesses += "
      [get_region_accesses_name(i)]:
      " - for(var/A in get_region_accesses(i)) - if(A in inserted_modify_id.access) - accesses += "[replacetext(get_access_desc(A), " ", " ")] " - else - accesses += "[replacetext(get_access_desc(A), " ", " ")] " - accesses += "
      " - accesses += "
      " - body = "[carddesc.Join()]
      [jobs.Join()]

      [accesses.Join()]
      " //CHECK THIS - - else if (!authenticated) - body = {"Log In

      - Access Crew Manifest

      "} - if(!target_dept) - body += "Job Management
      " - - dat = list("", header.Join(), body, "
      ") - var/datum/browser/popup = new(user, "id_com", src.name, 900, 620) - popup.set_content(dat.Join()) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - -/obj/machinery/computer/card/Topic(href, href_list) - if(..()) - return - - if(!usr.canUseTopic(src, !issilicon(usr)) || !is_operational()) - usr.unset_machine() - usr << browse(null, "window=id_com") - return - - usr.set_machine(src) - switch(href_list["choice"]) - if ("inserted_modify_id") - if(inserted_modify_id && !usr.get_active_held_item()) - if(id_eject(usr, inserted_modify_id)) - inserted_modify_id = null - updateUsrDialog() - return - if(usr.get_id_in_hand()) - var/obj/item/held_item = usr.get_active_held_item() - var/obj/item/card/id/id_to_insert = held_item.GetID() - if(id_insert(usr, held_item, inserted_modify_id)) - inserted_modify_id = id_to_insert - updateUsrDialog() - if ("inserted_scan_id") - if(inserted_scan_id && !usr.get_active_held_item()) - if(id_eject(usr, inserted_scan_id)) - inserted_scan_id = null - updateUsrDialog() - return - if(usr.get_id_in_hand()) - var/obj/item/held_item = usr.get_active_held_item() - var/obj/item/card/id/id_to_insert = held_item.GetID() - if(id_insert(usr, held_item, inserted_scan_id)) - inserted_scan_id = id_to_insert - updateUsrDialog() - if ("auth") - if ((!( authenticated ) && (inserted_scan_id || issilicon(usr)) || mode)) - if (check_access(inserted_scan_id)) - region_access = list() - head_subordinates = list() - if(ACCESS_CHANGE_IDS in inserted_scan_id.access) - if(target_dept) - head_subordinates = get_all_jobs() - region_access |= target_dept - authenticated = 1 - else - authenticated = 2 - playsound(src, 'sound/machines/terminal_on.ogg', 50, FALSE) - - else - if((ACCESS_HOP in inserted_scan_id.access) && ((target_dept==1) || !target_dept)) - region_access |= 1 - get_subordinates("Head of Personnel") - if((ACCESS_HOS in inserted_scan_id.access) && ((target_dept==2) || !target_dept)) - region_access |= 2 - get_subordinates("Head of Security") - if((ACCESS_CMO in inserted_scan_id.access) && ((target_dept==3) || !target_dept)) - region_access |= 3 - get_subordinates("Chief Medical Officer") - if((ACCESS_RD in inserted_scan_id.access) && ((target_dept==4) || !target_dept)) - region_access |= 4 - get_subordinates("Research Director") - if((ACCESS_CE in inserted_scan_id.access) && ((target_dept==5) || !target_dept)) - region_access |= 5 - get_subordinates("Chief Engineer") - if((ACCESS_QM in inserted_scan_id.access) && ((target_dept==6) || !target_dept)) - region_access |= 6 - get_subordinates("Quartermaster") - if(region_access) - authenticated = 1 - else if ((!( authenticated ) && issilicon(usr)) && (!inserted_modify_id)) - to_chat(usr, "You can't modify an ID without an ID inserted to modify! Once one is in the modify slot on the computer, you can log in.") - if ("logout") - region_access = null - head_subordinates = null - authenticated = 0 - playsound(src, 'sound/machines/terminal_off.ogg', 50, FALSE) - - if("access") - if(href_list["allowed"]) - if(authenticated) - var/access_type = text2num(href_list["access_target"]) - var/access_allowed = text2num(href_list["allowed"]) - if(access_type in (istype(src, /obj/machinery/computer/card/centcom)?get_all_centcom_access() : get_all_accesses())) - inserted_modify_id.access -= access_type - if(access_allowed == 1) - inserted_modify_id.access += access_type - playsound(src, "terminal_type", 50, FALSE) - if ("assign") - if (authenticated == 2) - var/t1 = href_list["assign_target"] - if(t1 == "Custom") - var/newJob = reject_bad_text(input("Enter a custom job assignment.", "Assignment", inserted_modify_id ? inserted_modify_id.assignment : "Unassigned"), MAX_NAME_LEN) - if(newJob) - t1 = newJob - - else if(t1 == "Unassigned") - inserted_modify_id.access -= get_all_accesses() - - else - var/datum/job/jobdatum - for(var/jobtype in typesof(/datum/job)) - var/datum/job/J = new jobtype - if(ckey(J.title) == ckey(t1)) - jobdatum = J - updateUsrDialog() - break - if(!jobdatum) - to_chat(usr, "No log exists for this job.") - updateUsrDialog() - return - - inserted_modify_id.access = ( istype(src, /obj/machinery/computer/card/centcom) ? get_centcom_access(t1) : jobdatum.get_access() ) - if (inserted_modify_id) - inserted_modify_id.assignment = t1 - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) - if ("demote") - if(inserted_modify_id.assignment in head_subordinates || inserted_modify_id.assignment == "Assistant") - inserted_modify_id.assignment = "Unassigned" - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) - else - to_chat(usr, "You are not authorized to demote this position.") - if ("reg") - if (authenticated) - var/t2 = inserted_modify_id - if ((authenticated && inserted_modify_id == t2 && (in_range(src, usr) || issilicon(usr)) && isturf(loc))) - var/newName = reject_bad_name(href_list["reg"]) - if(newName) - inserted_modify_id.registered_name = newName - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) - else - to_chat(usr, "Invalid name entered.") - updateUsrDialog() - return - if ("mode") - mode = text2num(href_list["mode_target"]) - - if("return") - //DISPLAY MAIN MENU - mode = 3; - playsound(src, "terminal_type", 25, FALSE) - - if("make_job_available") - // MAKE ANOTHER JOB POSITION AVAILABLE FOR LATE JOINERS - if(authenticated && !target_dept) - var/edit_job_target = href_list["job"] - var/datum/job/j = SSjob.GetJob(edit_job_target) - if(!j) - updateUsrDialog() - return 0 - if(can_open_job(j) != 1) - updateUsrDialog() - return 0 - if(opened_positions[edit_job_target] >= 0) - GLOB.time_last_changed_position = world.time / 10 - j.total_positions++ - opened_positions[edit_job_target]++ - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) - - if("make_job_unavailable") - // MAKE JOB POSITION UNAVAILABLE FOR LATE JOINERS - if(authenticated && !target_dept) - var/edit_job_target = href_list["job"] - var/datum/job/j = SSjob.GetJob(edit_job_target) - if(!j) - updateUsrDialog() - return 0 - if(can_close_job(j) != 1) - updateUsrDialog() - return 0 - //Allow instant closing without cooldown if a position has been opened before - if(opened_positions[edit_job_target] <= 0) - GLOB.time_last_changed_position = world.time / 10 - j.total_positions-- - opened_positions[edit_job_target]-- - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) - - if ("prioritize_job") - // TOGGLE WHETHER JOB APPEARS AS PRIORITIZED IN THE LOBBY - if(authenticated && !target_dept) - var/priority_target = href_list["job"] - var/datum/job/j = SSjob.GetJob(priority_target) - if(!j) - updateUsrDialog() - return 0 - var/priority = TRUE - if(j in SSjob.prioritized_jobs) - SSjob.prioritized_jobs -= j - priority = FALSE - else if(j.total_positions <= j.current_positions) - to_chat(usr, "[j.title] has had all positions filled. Open up more slots before prioritizing it.") - updateUsrDialog() - return - else - SSjob.prioritized_jobs += j - to_chat(usr, "[j.title] has been successfully [priority ? "prioritized" : "unprioritized"]. Potential employees will notice your request.") - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) - - if ("print") - if (!( printing )) - printing = 1 - sleep(50) - var/obj/item/paper/P = new /obj/item/paper( loc ) - var/t1 = "Crew Manifest:
      " - for(var/datum/data/record/t in sortRecord(GLOB.data_core.general)) - t1 += t.fields["name"] + " - " + t.fields["rank"] + "
      " - P.info = t1 - P.name = "paper- 'Crew Manifest'" - printing = null - playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) - if (inserted_modify_id) - inserted_modify_id.update_label() - updateUsrDialog() - -/obj/machinery/computer/card/proc/get_subordinates(rank) - for(var/datum/job/job in SSjob.occupations) - if(rank in job.department_head) - head_subordinates += job.title - -/obj/machinery/computer/card/centcom - name = "\improper CentCom identification console" - circuit = /obj/item/circuitboard/computer/card/centcom - req_access = list(ACCESS_CENT_CAPTAIN) - -/obj/machinery/computer/card/minor - name = "department management console" - desc = "You can use this to change ID's for specific departments." - icon_screen = "idminor" - circuit = /obj/item/circuitboard/computer/card/minor - -/obj/machinery/computer/card/minor/Initialize() - . = ..() - var/obj/item/circuitboard/computer/card/minor/typed_circuit = circuit - if(target_dept) - typed_circuit.target_dept = target_dept - else - target_dept = typed_circuit.target_dept - var/list/dept_list = list("civilian","security","medical","science","engineering","cargo") - name = "[dept_list[target_dept]] department console" - -/obj/machinery/computer/card/minor/hos - target_dept = 2 - icon_screen = "idhos" - - light_color = LIGHT_COLOR_RED - -/obj/machinery/computer/card/minor/cmo - target_dept = 3 - icon_screen = "idcmo" - -/obj/machinery/computer/card/minor/rd - target_dept = 4 - icon_screen = "idrd" - - light_color = LIGHT_COLOR_PINK - -/obj/machinery/computer/card/minor/ce - target_dept = 5 - icon_screen = "idce" - - light_color = LIGHT_COLOR_YELLOW - -/obj/machinery/computer/card/minor/qm - target_dept = 6 - icon_screen = "idqm" - - light_color = LIGHT_COLOR_ORANGE - -#undef JOB_ALLOWED -#undef JOB_COOLDOWN -#undef JOB_MAX_POSITIONS -#undef JOB_DENIED + + +//Keeps track of the time for the ID console. Having it as a global variable prevents people from dismantling/reassembling it to +//increase the slots of many jobs. +GLOBAL_VAR_INIT(time_last_changed_position, 0) + +#define JOB_ALLOWED 1 +#define JOB_COOLDOWN -2 +#define JOB_MAX_POSITIONS -1 // Trying to reduce the number of slots below that of current holders of that job, or trying to open more slots than allowed +#define JOB_DENIED 0 + +/obj/machinery/computer/card + name = "identification console" + desc = "You can use this to manage jobs and ID access." + icon_screen = "id" + icon_keyboard = "id_key" + req_one_access = list(ACCESS_HEADS, ACCESS_CHANGE_IDS) + circuit = /obj/item/circuitboard/computer/card + var/mode = 0 + var/printing = null + var/target_dept = 0 //Which department this computer has access to. 0=all departments + + //Cooldown for closing positions in seconds + //if set to -1: No cooldown... probably a bad idea + //if set to 0: Not able to close "original" positions. You can only close positions that you have opened before + var/change_position_cooldown = 30 + //Jobs you cannot open new positions for + var/list/blacklisted = list( + "AI", + "Assistant", + "Cyborg", + "Captain", + "Head of Personnel", + "Head of Security", + "Chief Engineer", + "Research Director", + "Chief Medical Officer", + "Quartermaster") + + //The scaling factor of max total positions in relation to the total amount of people on board the station in % + var/max_relative_positions = 30 //30%: Seems reasonable, limit of 6 @ 20 players + + //This is used to keep track of opened positions for jobs to allow instant closing + //Assoc array: "JobName" = (int) + var/list/opened_positions = list() + var/obj/item/card/id/inserted_scan_id + var/obj/item/card/id/inserted_modify_id + var/list/region_access = null + var/list/head_subordinates = null + + light_color = LIGHT_COLOR_BLUE + +/obj/machinery/computer/card/proc/get_jobs() + return get_all_jobs() + +/obj/machinery/computer/card/centcom/get_jobs() + return get_all_centcom_jobs() + +/obj/machinery/computer/card/Initialize() + . = ..() + change_position_cooldown = CONFIG_GET(number/id_console_jobslot_delay) + +/obj/machinery/computer/card/examine(mob/user) + . = ..() + if(inserted_scan_id || inserted_modify_id) + . += "Alt-click to eject the ID card." + +/obj/machinery/computer/card/attackby(obj/I, mob/user, params) + if(isidcard(I)) + if(check_access(I) && !inserted_scan_id) + if(id_insert(user, I, inserted_scan_id)) + inserted_scan_id = I + updateUsrDialog() + else if(id_insert(user, I, inserted_modify_id)) + inserted_modify_id = I + updateUsrDialog() + else + return ..() + +/obj/machinery/computer/card/Destroy() + if(inserted_scan_id) + qdel(inserted_scan_id) + inserted_scan_id = null + if(inserted_modify_id) + qdel(inserted_modify_id) + inserted_modify_id = null + return ..() + +/obj/machinery/computer/card/handle_atom_del(atom/A) + ..() + if(A == inserted_scan_id) + inserted_scan_id = null + updateUsrDialog() + if(A == inserted_modify_id) + inserted_modify_id = null + updateUsrDialog() + +/obj/machinery/computer/card/on_deconstruction() + if(inserted_scan_id) + inserted_scan_id.forceMove(drop_location()) + inserted_scan_id = null + if(inserted_modify_id) + inserted_modify_id.forceMove(drop_location()) + inserted_modify_id = null + +//Check if you can't open a new position for a certain job +/obj/machinery/computer/card/proc/job_blacklisted(jobtitle) + return (jobtitle in blacklisted) + +//Logic check for Topic() if you can open the job +/obj/machinery/computer/card/proc/can_open_job(datum/job/job) + if(job) + if(!job_blacklisted(job.title)) + if((job.total_positions <= GLOB.player_list.len * (max_relative_positions / 100))) + var/delta = (world.time / 10) - GLOB.time_last_changed_position + if((change_position_cooldown < delta) || (opened_positions[job.title] < 0)) + return JOB_ALLOWED + return JOB_COOLDOWN + return JOB_MAX_POSITIONS + return JOB_DENIED + +//Logic check for Topic() if you can close the job +/obj/machinery/computer/card/proc/can_close_job(datum/job/job) + if(job) + if(!job_blacklisted(job.title)) + if(job.total_positions > job.current_positions) + var/delta = (world.time / 10) - GLOB.time_last_changed_position + if((change_position_cooldown < delta) || (opened_positions[job.title] > 0)) + return JOB_ALLOWED + return JOB_COOLDOWN + return JOB_MAX_POSITIONS + return JOB_DENIED + + +/obj/machinery/computer/card/proc/id_insert(mob/user, obj/item/inserting_item, obj/item/target) + var/obj/item/card/id/card_to_insert = inserting_item + var/holder_item = FALSE + + if(!isidcard(card_to_insert)) + card_to_insert = inserting_item.RemoveID() + holder_item = TRUE + + if(!card_to_insert || !user.transferItemToLoc(card_to_insert, src)) + return FALSE + + if(target) + if(holder_item && inserting_item.InsertID(target)) + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + else + id_eject(user, target) + + user.visible_message("[user] inserts \the [card_to_insert] into \the [src].", + "You insert \the [card_to_insert] into \the [src].") + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + updateUsrDialog() + return TRUE + +/obj/machinery/computer/card/proc/id_eject(mob/user, obj/target) + if(!target) + to_chat(user, "That slot is empty!") + return FALSE + else + target.forceMove(drop_location()) + if(!issilicon(user) && Adjacent(user)) + user.put_in_hands(target) + user.visible_message("[user] gets \the [target] from \the [src].", \ + "You get \the [target] from \the [src].") + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + updateUsrDialog() + return TRUE + +/obj/machinery/computer/card/AltClick(mob/user) + . = ..() + if(!user.canUseTopic(src, !issilicon(user)) || !is_operational()) + return + if(inserted_modify_id) + if(id_eject(user, inserted_modify_id)) + inserted_modify_id = null + updateUsrDialog() + return TRUE + if(inserted_scan_id) + if(id_eject(user, inserted_scan_id)) + inserted_scan_id = null + updateUsrDialog() + return TRUE + +/obj/machinery/computer/card/ui_interact(mob/user) + . = ..() + var/list/dat = list() + if (mode == 1) // accessing crew manifest + dat += "Crew Manifest:
      Please use security record computer to modify entries.

      " + for(var/datum/data/record/t in sortRecord(GLOB.data_core.general)) + dat += {"[t.fields["name"]] - [t.fields["rank"]]
      "} + dat += "Print

      Access ID modification console.
      " + + else if(mode == 2) + // JOB MANAGEMENT + dat += {"Return + + "} + for(var/datum/job/job in SSjob.occupations) + dat += "" + if(job.title in blacklisted) + continue + dat += {" + + " + dat += "
      JobSlotsOpen jobClose jobPrioritize
      [job.title][job.current_positions]/[job.total_positions]"} + switch(can_open_job(job)) + if(JOB_ALLOWED) + if(authenticated == 2) + dat += "Open Position
      " + else + dat += "Open Position" + if(JOB_COOLDOWN) + var/time_to_wait = round(change_position_cooldown - ((world.time / 10) - GLOB.time_last_changed_position), 1) + var/mins = round(time_to_wait / 60) + var/seconds = time_to_wait - (60*mins) + dat += "Cooldown ongoing: [mins]:[(seconds < 10) ? "0[seconds]" : "[seconds]"]" + else + dat += "Denied" + dat += "
      " + switch(can_close_job(job)) + if(JOB_ALLOWED) + if(authenticated == 2) + dat += "Close Position" + else + dat += "Close Position" + if(JOB_COOLDOWN) + var/time_to_wait = round(change_position_cooldown - ((world.time / 10) - GLOB.time_last_changed_position), 1) + var/mins = round(time_to_wait / 60) + var/seconds = time_to_wait - (60*mins) + dat += "Cooldown ongoing: [mins]:[(seconds < 10) ? "0[seconds]" : "[seconds]"]" + else + dat += "Denied" + dat += "" + switch(job.total_positions) + if(0) + dat += "Denied" + else + if(authenticated == 2) + if(job in SSjob.prioritized_jobs) + dat += "Deprioritize" + else + if(SSjob.prioritized_jobs.len < 5) + dat += "Prioritize" + else + dat += "Denied" + else + dat += "Prioritize" + + dat += "
      " + else + var/list/header = list() + + var/scan_name = inserted_scan_id ? html_encode(inserted_scan_id.name) : "--------" + var/target_name = inserted_modify_id ? html_encode(inserted_modify_id.name) : "--------" + var/target_owner = (inserted_modify_id && inserted_modify_id.registered_name) ? html_encode(inserted_modify_id.registered_name) : "--------" + var/target_rank = (inserted_modify_id && inserted_modify_id.assignment) ? html_encode(inserted_modify_id.assignment) : "Unassigned" + + if(!authenticated) + header += {"
      Please insert the cards into the slots
      + Target: [target_name]
      + Confirm Identity: [scan_name]
      "} + else + header += {"

      + Target: Remove [target_name] || + Confirm Identity: Remove [scan_name]
      + Access Crew Manifest
      + [!target_dept ? "Job Management
      " : ""] + Log Out
      "} + + header += "
      " + + var/body + + if (authenticated && inserted_modify_id) + var/list/carddesc = list() + var/list/jobs = list() + if (authenticated == 2) + var/list/jobs_all = list() + for(var/job in (list("Unassigned") + get_jobs() + "Custom")) + jobs_all += "[replacetext(job, " ", " ")] " //make sure there isn't a line break in the middle of a job + carddesc += {""} + carddesc += {"
      + + + registered name: + +
      + Assignment: "} + + jobs += "[target_rank]" //CHECK THIS + + else + carddesc += "registered_name: [target_owner]" + jobs += "Assignment: [target_rank] (Demote)" + + var/list/accesses = list() + if(istype(src, /obj/machinery/computer/card/centcom)) // REE + accesses += "
      Central Command:
      " + for(var/A in get_all_centcom_access()) + if(A in inserted_modify_id.access) + accesses += "[replacetext(get_centcom_access_desc(A), " ", " ")] " + else + accesses += "[replacetext(get_centcom_access_desc(A), " ", " ")] " + else + accesses += {"
      Access
      + + "} + for(var/i = 1; i <= 7; i++) + if(authenticated == 1 && !(i in region_access)) + continue + accesses += "" + accesses += "" + for(var/i = 1; i <= 7; i++) + if(authenticated == 1 && !(i in region_access)) + continue + accesses += "" + accesses += "
      [get_region_accesses_name(i)]:
      " + for(var/A in get_region_accesses(i)) + if(A in inserted_modify_id.access) + accesses += "[replacetext(get_access_desc(A), " ", " ")] " + else + accesses += "[replacetext(get_access_desc(A), " ", " ")] " + accesses += "
      " + accesses += "
      " + body = "[carddesc.Join()]
      [jobs.Join()]

      [accesses.Join()]
      " //CHECK THIS + + else if (!authenticated) + body = {"Log In

      + Access Crew Manifest

      "} + if(!target_dept) + body += "Job Management
      " + + dat = list("", header.Join(), body, "
      ") + var/datum/browser/popup = new(user, "id_com", src.name, 900, 620) + popup.set_content(dat.Join()) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + +/obj/machinery/computer/card/Topic(href, href_list) + if(..()) + return + + if(!usr.canUseTopic(src, !issilicon(usr)) || !is_operational()) + usr.unset_machine() + usr << browse(null, "window=id_com") + return + + usr.set_machine(src) + switch(href_list["choice"]) + if ("inserted_modify_id") + if(inserted_modify_id && !usr.get_active_held_item()) + if(id_eject(usr, inserted_modify_id)) + inserted_modify_id = null + updateUsrDialog() + return + if(usr.get_id_in_hand()) + var/obj/item/held_item = usr.get_active_held_item() + var/obj/item/card/id/id_to_insert = held_item.GetID() + if(id_insert(usr, held_item, inserted_modify_id)) + inserted_modify_id = id_to_insert + updateUsrDialog() + if ("inserted_scan_id") + if(inserted_scan_id && !usr.get_active_held_item()) + if(id_eject(usr, inserted_scan_id)) + inserted_scan_id = null + updateUsrDialog() + return + if(usr.get_id_in_hand()) + var/obj/item/held_item = usr.get_active_held_item() + var/obj/item/card/id/id_to_insert = held_item.GetID() + if(id_insert(usr, held_item, inserted_scan_id)) + inserted_scan_id = id_to_insert + updateUsrDialog() + if ("auth") + if ((!( authenticated ) && (inserted_scan_id || issilicon(usr)) || mode)) + if (check_access(inserted_scan_id)) + region_access = list() + head_subordinates = list() + if(ACCESS_CHANGE_IDS in inserted_scan_id.access) + if(target_dept) + head_subordinates = get_all_jobs() + region_access |= target_dept + authenticated = 1 + else + authenticated = 2 + playsound(src, 'sound/machines/terminal_on.ogg', 50, FALSE) + + else + if((ACCESS_HOP in inserted_scan_id.access) && ((target_dept==1) || !target_dept)) + region_access |= 1 + get_subordinates("Head of Personnel") + if((ACCESS_HOS in inserted_scan_id.access) && ((target_dept==2) || !target_dept)) + region_access |= 2 + get_subordinates("Head of Security") + if((ACCESS_CMO in inserted_scan_id.access) && ((target_dept==3) || !target_dept)) + region_access |= 3 + get_subordinates("Chief Medical Officer") + if((ACCESS_RD in inserted_scan_id.access) && ((target_dept==4) || !target_dept)) + region_access |= 4 + get_subordinates("Research Director") + if((ACCESS_CE in inserted_scan_id.access) && ((target_dept==5) || !target_dept)) + region_access |= 5 + get_subordinates("Chief Engineer") + if((ACCESS_QM in inserted_scan_id.access) && ((target_dept==6) || !target_dept)) + region_access |= 6 + get_subordinates("Quartermaster") + if(region_access) + authenticated = 1 + else if ((!( authenticated ) && issilicon(usr)) && (!inserted_modify_id)) + to_chat(usr, "You can't modify an ID without an ID inserted to modify! Once one is in the modify slot on the computer, you can log in.") + if ("logout") + region_access = null + head_subordinates = null + authenticated = 0 + playsound(src, 'sound/machines/terminal_off.ogg', 50, FALSE) + + if("access") + if(href_list["allowed"]) + if(authenticated) + var/access_type = text2num(href_list["access_target"]) + var/access_allowed = text2num(href_list["allowed"]) + if(access_type in (istype(src, /obj/machinery/computer/card/centcom)?get_all_centcom_access() : get_all_accesses())) + inserted_modify_id.access -= access_type + if(access_allowed == 1) + inserted_modify_id.access += access_type + playsound(src, "terminal_type", 50, FALSE) + if ("assign") + if (authenticated == 2) + var/t1 = href_list["assign_target"] + if(t1 == "Custom") + var/newJob = reject_bad_text(input("Enter a custom job assignment.", "Assignment", inserted_modify_id ? inserted_modify_id.assignment : "Unassigned"), MAX_NAME_LEN) + if(newJob) + t1 = newJob + + else if(t1 == "Unassigned") + inserted_modify_id.access -= get_all_accesses() + + else + var/datum/job/jobdatum + for(var/jobtype in typesof(/datum/job)) + var/datum/job/J = new jobtype + if(ckey(J.title) == ckey(t1)) + jobdatum = J + updateUsrDialog() + break + if(!jobdatum) + to_chat(usr, "No log exists for this job.") + updateUsrDialog() + return + + inserted_modify_id.access = ( istype(src, /obj/machinery/computer/card/centcom) ? get_centcom_access(t1) : jobdatum.get_access() ) + if (inserted_modify_id) + inserted_modify_id.assignment = t1 + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) + if ("demote") + if(inserted_modify_id.assignment in head_subordinates || inserted_modify_id.assignment == "Assistant") + inserted_modify_id.assignment = "Unassigned" + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) + else + to_chat(usr, "You are not authorized to demote this position.") + if ("reg") + if (authenticated) + var/t2 = inserted_modify_id + if ((authenticated && inserted_modify_id == t2 && (in_range(src, usr) || issilicon(usr)) && isturf(loc))) + var/newName = reject_bad_name(href_list["reg"]) + if(newName) + inserted_modify_id.registered_name = newName + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) + else + to_chat(usr, "Invalid name entered.") + updateUsrDialog() + return + if ("mode") + mode = text2num(href_list["mode_target"]) + + if("return") + //DISPLAY MAIN MENU + mode = 3; + playsound(src, "terminal_type", 25, FALSE) + + if("make_job_available") + // MAKE ANOTHER JOB POSITION AVAILABLE FOR LATE JOINERS + if(authenticated && !target_dept) + var/edit_job_target = href_list["job"] + var/datum/job/j = SSjob.GetJob(edit_job_target) + if(!j) + updateUsrDialog() + return 0 + if(can_open_job(j) != 1) + updateUsrDialog() + return 0 + if(opened_positions[edit_job_target] >= 0) + GLOB.time_last_changed_position = world.time / 10 + j.total_positions++ + opened_positions[edit_job_target]++ + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) + + if("make_job_unavailable") + // MAKE JOB POSITION UNAVAILABLE FOR LATE JOINERS + if(authenticated && !target_dept) + var/edit_job_target = href_list["job"] + var/datum/job/j = SSjob.GetJob(edit_job_target) + if(!j) + updateUsrDialog() + return 0 + if(can_close_job(j) != 1) + updateUsrDialog() + return 0 + //Allow instant closing without cooldown if a position has been opened before + if(opened_positions[edit_job_target] <= 0) + GLOB.time_last_changed_position = world.time / 10 + j.total_positions-- + opened_positions[edit_job_target]-- + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE) + + if ("prioritize_job") + // TOGGLE WHETHER JOB APPEARS AS PRIORITIZED IN THE LOBBY + if(authenticated && !target_dept) + var/priority_target = href_list["job"] + var/datum/job/j = SSjob.GetJob(priority_target) + if(!j) + updateUsrDialog() + return 0 + var/priority = TRUE + if(j in SSjob.prioritized_jobs) + SSjob.prioritized_jobs -= j + priority = FALSE + else if(j.total_positions <= j.current_positions) + to_chat(usr, "[j.title] has had all positions filled. Open up more slots before prioritizing it.") + updateUsrDialog() + return + else + SSjob.prioritized_jobs += j + to_chat(usr, "[j.title] has been successfully [priority ? "prioritized" : "unprioritized"]. Potential employees will notice your request.") + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) + + if ("print") + if (!( printing )) + printing = 1 + sleep(50) + var/obj/item/paper/P = new /obj/item/paper( loc ) + var/t1 = "Crew Manifest:
      " + for(var/datum/data/record/t in sortRecord(GLOB.data_core.general)) + t1 += t.fields["name"] + " - " + t.fields["rank"] + "
      " + P.info = t1 + P.name = "paper- 'Crew Manifest'" + printing = null + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + if (inserted_modify_id) + inserted_modify_id.update_label() + updateUsrDialog() + +/obj/machinery/computer/card/proc/get_subordinates(rank) + for(var/datum/job/job in SSjob.occupations) + if(rank in job.department_head) + head_subordinates += job.title + +/obj/machinery/computer/card/centcom + name = "\improper CentCom identification console" + circuit = /obj/item/circuitboard/computer/card/centcom + req_access = list(ACCESS_CENT_CAPTAIN) + +/obj/machinery/computer/card/minor + name = "department management console" + desc = "You can use this to change ID's for specific departments." + icon_screen = "idminor" + circuit = /obj/item/circuitboard/computer/card/minor + +/obj/machinery/computer/card/minor/Initialize() + . = ..() + var/obj/item/circuitboard/computer/card/minor/typed_circuit = circuit + if(target_dept) + typed_circuit.target_dept = target_dept + else + target_dept = typed_circuit.target_dept + var/list/dept_list = list("civilian","security","medical","science","engineering","cargo") + name = "[dept_list[target_dept]] department console" + +/obj/machinery/computer/card/minor/hos + target_dept = 2 + icon_screen = "idhos" + + light_color = LIGHT_COLOR_RED + +/obj/machinery/computer/card/minor/cmo + target_dept = 3 + icon_screen = "idcmo" + +/obj/machinery/computer/card/minor/rd + target_dept = 4 + icon_screen = "idrd" + + light_color = LIGHT_COLOR_PINK + +/obj/machinery/computer/card/minor/ce + target_dept = 5 + icon_screen = "idce" + + light_color = LIGHT_COLOR_YELLOW + +/obj/machinery/computer/card/minor/qm + target_dept = 6 + icon_screen = "idqm" + + light_color = LIGHT_COLOR_ORANGE + +#undef JOB_ALLOWED +#undef JOB_COOLDOWN +#undef JOB_MAX_POSITIONS +#undef JOB_DENIED diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 43cfbdb33b..90969bf4a1 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -1,514 +1,514 @@ -#define AUTOCLONING_MINIMAL_LEVEL 4 - -/obj/machinery/computer/cloning - name = "cloning console" - desc = "Used to clone people and manage DNA." - icon_screen = "dna" - icon_keyboard = "med_key" - circuit = /obj/item/circuitboard/computer/cloning - req_access = list(ACCESS_HEADS) //ONLY USED FOR RECORD DELETION RIGHT NOW. - var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning. - var/list/pods //Linked cloning pods - var/temp = "Inactive" - var/scantemp_ckey - var/scantemp = "Ready to Scan" - var/menu = 1 //Which menu screen to display - var/datum/data/record/active_record = null - var/obj/item/disk/data/diskette = null //Mostly so the geneticist can steal everything. - var/loading = 0 // Nice loading text - var/autoprocess = 0 - var/list/records = list() - - light_color = LIGHT_COLOR_BLUE - -/obj/machinery/computer/cloning/Initialize() - . = ..() - updatemodules(TRUE) - var/obj/item/circuitboard/computer/cloning/board = circuit - records = board.records - - -/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 - - 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"], R.fields["quirks"])) - temp = "[R.fields["name"]] => Cloning cycle in progress..." - records -= R - -/obj/machinery/computer/cloning/proc/updatemodules(findfirstcloner) - src.scanner = findscanner() - if(findfirstcloner && !LAZYLEN(pods)) - findcloner() - if(!autoprocess) - STOP_PROCESSING(SSmachines, src) - else - START_PROCESSING(SSmachines, src) - -/obj/machinery/computer/cloning/proc/findscanner() - var/obj/machinery/dna_scannernew/scannerf = null - - // Loop through every direction - for(var/direction in GLOB.cardinals) - - // Try to find a scanner in that direction - scannerf = locate(/obj/machinery/dna_scannernew, get_step(src, direction)) - - // 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(var/direction in GLOB.cardinals) - - podf = locate(/obj/machinery/clonepod, get_step(src, direction)) - if (!isnull(podf) && podf.is_operational()) - AttachCloner(podf) - -/obj/machinery/computer/cloning/proc/AttachCloner(obj/machinery/clonepod/pod) - if(!pod.connected) - pod.connected = src - LAZYADD(pods, pod) - -/obj/machinery/computer/cloning/proc/DetachCloner(obj/machinery/clonepod/pod) - pod.connected = null - LAZYREMOVE(pods, pod) - -/obj/machinery/computer/cloning/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/disk/data)) //INSERT SOME DISKETTES - if (!src.diskette) - if (!user.transferItemToLoc(W,src)) - return - src.diskette = W - to_chat(user, "You insert [W].") - playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) - src.updateUsrDialog() - else if(istype(W, /obj/item/multitool)) - var/obj/item/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/ui_interact(mob/user) - . = ..() - - updatemodules(TRUE) - - var/dat = "" - dat += "Refresh" - - if(scanner && HasEfficientPod() && scanner.scan_level >= AUTOCLONING_MINIMAL_LEVEL) - if(!autoprocess) - dat += "Autoclone" - else - dat += "Stop autoclone" - else - dat += "Autoclone" - dat += "

      Cloning Pod Status

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

      Modules

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

      Scanner Functions

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

      Database Functions

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

      Current records

      " - dat += "<< Back

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

      [R.fields["name"]]

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

      Selected Record

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

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

      " - dat += "Scan ID [src.active_record.fields["id"]] Clone
      " - - var/obj/item/implant/health/H = locate(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") - if(scanner && HasEfficientPod() && scanner.scan_level >= AUTOCLONING_MINIMAL_LEVEL) - autoprocess = TRUE - START_PROCESSING(SSmachines, src) - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - if("stopautoprocess") - autoprocess = FALSE - STOP_PROCESSING(SSmachines, src) - 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...") - var/prev_locked = scanner.locked - scanner.locked = TRUE - spawn(20) - src.scan_occupant(scanner.occupant) - - loading = 0 - src.updateUsrDialog() - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - scanner.locked = prev_locked - - - //No locking an open scanner. - else if ((href_list["lock"]) && !isnull(scanner) && scanner.is_operational()) - if ((!scanner.locked) && (scanner.occupant)) - scanner.locked = TRUE - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else - scanner.locked = FALSE - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - else if(href_list["view_rec"]) - playsound(src, "terminal_type", 25, 0) - src.active_record = find_record("id", href_list["view_rec"], records) - if(active_record) - if(!active_record.fields["ckey"]) - records -= active_record - active_record = null - src.temp = "Record Corrupt" - else - src.menu = 3 - else - src.temp = "Record missing." - - else if (href_list["del_rec"]) - if ((!src.active_record) || (src.menu < 3)) - return - if (src.menu == 3) //If we are viewing a record, confirm deletion - src.temp = "Delete record?" - src.menu = 4 - playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) - - else if (src.menu == 4) - var/obj/item/card/id/C = usr.get_active_held_item() - if (istype(C)||istype(C, /obj/item/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 - var/obj/item/circuitboard/computer/cloning/board = circuit - board.records = records - 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." - var/obj/item/circuitboard/computer/cloning/board = circuit - board.records = records - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - if("eject") - if(src.diskette) - src.diskette.forceMove(drop_location()) - src.diskette = null - playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) - if("save") - if(!diskette || diskette.read_only || !active_record || !active_record.fields) - src.temp = "Save error." - src.updateUsrDialog() - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - - diskette.fields = active_record.fields.Copy() - diskette.name = "data disk - '[src.diskette.fields["name"]]'" - src.temp = "Save successful." - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - - else if (href_list["refresh"]) - src.updateUsrDialog() - playsound(src, "terminal_type", 25, 0) - - else if (href_list["clone"]) - var/datum/data/record/C = find_record("id", href_list["clone"], records) - //Look for that player! They better be dead! - if(C) - var/obj/machinery/clonepod/pod = GetAvailablePod() - //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs. - if(!LAZYLEN(pods)) - temp = "No Clonepods detected." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else if(!pod) - temp = "No Clonepods available." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else if(!CONFIG_GET(flag/revival_cloning)) - temp = "Unable to initiate cloning cycle." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else if(pod.occupant) - temp = "Cloning cycle already in progress." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["mrace"], C.fields["features"], C.fields["factions"], C.fields["quirks"])) - 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(ishuman(mob_occupant)) - var/mob/living/carbon/C = mob_occupant - dna = C.has_dna() - if(isbrain(mob_occupant)) - var/mob/living/brain/B = mob_occupant - dna = B.stored_dna - - if(!istype(dna)) - scantemp = "Unable to locate valid genetic data." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - if(mob_occupant.suiciding || mob_occupant.hellbound) - scantemp = "Subject's brain is not responding to scanning stimuli." - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - if((HAS_TRAIT(mob_occupant, TRAIT_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 - dna.delete_species = FALSE - R.fields["mrace"] = dna.species - else - var/datum/species/rando_race = pick(GLOB.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 - R.fields["quirks"] = list() - for(var/V in mob_occupant.roundstart_quirks) - var/datum/quirk/T = V - R.fields["quirks"][T.type] = T.clone_data() - - if (!isnull(mob_occupant.mind)) //Save that mind so traitors can continue traitoring after cloning. - R.fields["mind"] = "[REF(mob_occupant.mind)]" - - //Add an implant if needed - var/obj/item/implant/health/imp - for(var/obj/item/implant/health/HI in mob_occupant.implants) - imp = HI - break - if(!imp) - imp = new /obj/item/implant/health(mob_occupant) - imp.implant(mob_occupant) - R.fields["imp"] = "[REF(imp)]" - - src.records += R - var/obj/item/circuitboard/computer/cloning/board = circuit - board.records = records - scantemp = "Subject successfully scanned." - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) +#define AUTOCLONING_MINIMAL_LEVEL 4 + +/obj/machinery/computer/cloning + name = "cloning console" + desc = "Used to clone people and manage DNA." + icon_screen = "dna" + icon_keyboard = "med_key" + circuit = /obj/item/circuitboard/computer/cloning + req_access = list(ACCESS_HEADS) //ONLY USED FOR RECORD DELETION RIGHT NOW. + var/obj/machinery/dna_scannernew/scanner = null //Linked scanner. For scanning. + var/list/pods //Linked cloning pods + var/temp = "Inactive" + var/scantemp_ckey + var/scantemp = "Ready to Scan" + var/menu = 1 //Which menu screen to display + var/datum/data/record/active_record = null + var/obj/item/disk/data/diskette = null //Mostly so the geneticist can steal everything. + var/loading = 0 // Nice loading text + var/autoprocess = 0 + var/list/records = list() + + light_color = LIGHT_COLOR_BLUE + +/obj/machinery/computer/cloning/Initialize() + . = ..() + updatemodules(TRUE) + var/obj/item/circuitboard/computer/cloning/board = circuit + records = board.records + + +/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 + + 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"], R.fields["quirks"])) + temp = "[R.fields["name"]] => Cloning cycle in progress..." + records -= R + +/obj/machinery/computer/cloning/proc/updatemodules(findfirstcloner) + src.scanner = findscanner() + if(findfirstcloner && !LAZYLEN(pods)) + findcloner() + if(!autoprocess) + STOP_PROCESSING(SSmachines, src) + else + START_PROCESSING(SSmachines, src) + +/obj/machinery/computer/cloning/proc/findscanner() + var/obj/machinery/dna_scannernew/scannerf = null + + // Loop through every direction + for(var/direction in GLOB.cardinals) + + // Try to find a scanner in that direction + scannerf = locate(/obj/machinery/dna_scannernew, get_step(src, direction)) + + // 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(var/direction in GLOB.cardinals) + + podf = locate(/obj/machinery/clonepod, get_step(src, direction)) + if (!isnull(podf) && podf.is_operational()) + AttachCloner(podf) + +/obj/machinery/computer/cloning/proc/AttachCloner(obj/machinery/clonepod/pod) + if(!pod.connected) + pod.connected = src + LAZYADD(pods, pod) + +/obj/machinery/computer/cloning/proc/DetachCloner(obj/machinery/clonepod/pod) + pod.connected = null + LAZYREMOVE(pods, pod) + +/obj/machinery/computer/cloning/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/disk/data)) //INSERT SOME DISKETTES + if (!src.diskette) + if (!user.transferItemToLoc(W,src)) + return + src.diskette = W + to_chat(user, "You insert [W].") + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) + src.updateUsrDialog() + else if(istype(W, /obj/item/multitool)) + var/obj/item/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/ui_interact(mob/user) + . = ..() + + updatemodules(TRUE) + + var/dat = "" + dat += "Refresh" + + if(scanner && HasEfficientPod() && scanner.scan_level >= AUTOCLONING_MINIMAL_LEVEL) + if(!autoprocess) + dat += "Autoclone" + else + dat += "Stop autoclone" + else + dat += "Autoclone" + dat += "

      Cloning Pod Status

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

      Modules

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

      Scanner Functions

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

      Database Functions

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

      Current records

      " + dat += "<< Back

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

      [R.fields["name"]]

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

      Selected Record

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

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

      " + dat += "Scan ID [src.active_record.fields["id"]] Clone
      " + + var/obj/item/implant/health/H = locate(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") + if(scanner && HasEfficientPod() && scanner.scan_level >= AUTOCLONING_MINIMAL_LEVEL) + autoprocess = TRUE + START_PROCESSING(SSmachines, src) + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + if("stopautoprocess") + autoprocess = FALSE + STOP_PROCESSING(SSmachines, src) + 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...") + var/prev_locked = scanner.locked + scanner.locked = TRUE + spawn(20) + src.scan_occupant(scanner.occupant) + + loading = 0 + src.updateUsrDialog() + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + scanner.locked = prev_locked + + + //No locking an open scanner. + else if ((href_list["lock"]) && !isnull(scanner) && scanner.is_operational()) + if ((!scanner.locked) && (scanner.occupant)) + scanner.locked = TRUE + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else + scanner.locked = FALSE + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + + else if(href_list["view_rec"]) + playsound(src, "terminal_type", 25, 0) + src.active_record = find_record("id", href_list["view_rec"], records) + if(active_record) + if(!active_record.fields["ckey"]) + records -= active_record + active_record = null + src.temp = "Record Corrupt" + else + src.menu = 3 + else + src.temp = "Record missing." + + else if (href_list["del_rec"]) + if ((!src.active_record) || (src.menu < 3)) + return + if (src.menu == 3) //If we are viewing a record, confirm deletion + src.temp = "Delete record?" + src.menu = 4 + playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) + + else if (src.menu == 4) + var/obj/item/card/id/C = usr.get_active_held_item() + if (istype(C)||istype(C, /obj/item/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 + var/obj/item/circuitboard/computer/cloning/board = circuit + board.records = records + 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." + var/obj/item/circuitboard/computer/cloning/board = circuit + board.records = records + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + + if("eject") + if(src.diskette) + src.diskette.forceMove(drop_location()) + src.diskette = null + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0) + if("save") + if(!diskette || diskette.read_only || !active_record || !active_record.fields) + src.temp = "Save error." + src.updateUsrDialog() + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + + diskette.fields = active_record.fields.Copy() + diskette.name = "data disk - '[src.diskette.fields["name"]]'" + src.temp = "Save successful." + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + + else if (href_list["refresh"]) + src.updateUsrDialog() + playsound(src, "terminal_type", 25, 0) + + else if (href_list["clone"]) + var/datum/data/record/C = find_record("id", href_list["clone"], records) + //Look for that player! They better be dead! + if(C) + var/obj/machinery/clonepod/pod = GetAvailablePod() + //Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs. + if(!LAZYLEN(pods)) + temp = "No Clonepods detected." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(!pod) + temp = "No Clonepods available." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(!CONFIG_GET(flag/revival_cloning)) + temp = "Unable to initiate cloning cycle." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(pod.occupant) + temp = "Cloning cycle already in progress." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + else if(pod.growclone(C.fields["ckey"], C.fields["name"], C.fields["UI"], C.fields["SE"], C.fields["mind"], C.fields["mrace"], C.fields["features"], C.fields["factions"], C.fields["quirks"])) + 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(ishuman(mob_occupant)) + var/mob/living/carbon/C = mob_occupant + dna = C.has_dna() + if(isbrain(mob_occupant)) + var/mob/living/brain/B = mob_occupant + dna = B.stored_dna + + if(!istype(dna)) + scantemp = "Unable to locate valid genetic data." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if(mob_occupant.suiciding || mob_occupant.hellbound) + scantemp = "Subject's brain is not responding to scanning stimuli." + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + if((HAS_TRAIT(mob_occupant, TRAIT_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 + dna.delete_species = FALSE + R.fields["mrace"] = dna.species + else + var/datum/species/rando_race = pick(GLOB.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 + R.fields["quirks"] = list() + for(var/V in mob_occupant.roundstart_quirks) + var/datum/quirk/T = V + R.fields["quirks"][T.type] = T.clone_data() + + if (!isnull(mob_occupant.mind)) //Save that mind so traitors can continue traitoring after cloning. + R.fields["mind"] = "[REF(mob_occupant.mind)]" + + //Add an implant if needed + var/obj/item/implant/health/imp + for(var/obj/item/implant/health/HI in mob_occupant.implants) + imp = HI + break + if(!imp) + imp = new /obj/item/implant/health(mob_occupant) + imp.implant(mob_occupant) + R.fields["imp"] = "[REF(imp)]" + + src.records += R + var/obj/item/circuitboard/computer/cloning/board = circuit + board.records = records + scantemp = "Subject successfully scanned." + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 22a523c58b..1bc8a82147 100755 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -1,759 +1,759 @@ -// The communications computer -/obj/machinery/computer/communications - name = "communications console" - desc = "A console used for high-priority announcements and emergencies." - icon_screen = "comm" - icon_keyboard = "tech_key" - req_access = list(ACCESS_HEADS) - circuit = /obj/item/circuitboard/computer/communications - var/auth_id = "Unknown" //Who is currently logged in? - var/list/datum/comm_message/messages = list() - var/datum/comm_message/currmsg - var/datum/comm_message/aicurrmsg - var/state = STATE_DEFAULT - var/aistate = STATE_DEFAULT - var/message_cooldown = 0 - var/ai_message_cooldown = 0 - var/tmp_alertlevel = 0 - var/const/STATE_DEFAULT = 1 - var/const/STATE_CALLSHUTTLE = 2 - var/const/STATE_CANCELSHUTTLE = 3 - var/const/STATE_MESSAGELIST = 4 - var/const/STATE_VIEWMESSAGE = 5 - var/const/STATE_DELMESSAGE = 6 - var/const/STATE_STATUSDISPLAY = 7 - var/const/STATE_ALERT_LEVEL = 8 - var/const/STATE_CONFIRM_LEVEL = 9 - var/const/STATE_TOGGLE_EMERGENCY = 10 - var/const/STATE_PURCHASE = 11 - - var/stat_msg1 - var/stat_msg2 - - light_color = LIGHT_COLOR_BLUE - -/obj/machinery/computer/communications/proc/checkCCcooldown() - var/obj/item/circuitboard/computer/communications/CM = circuit - if(CM.lastTimeUsed + 600 > world.time) - return FALSE - return TRUE - -/obj/machinery/computer/communications/Initialize() - . = ..() - GLOB.shuttle_caller_list += src - -/obj/machinery/computer/communications/Topic(href, href_list) - if(..()) - return - if(!usr.canUseTopic(src)) - return - if(!is_station_level(z) && !is_reserved_level(z)) //Can only use in transit and on SS13 - to_chat(usr, "Unable to establish a connection: \black You're too far away from the station!") - return - usr.set_machine(src) - - - if(!href_list["operation"]) - return - var/obj/item/circuitboard/computer/communications/CM = circuit - switch(href_list["operation"]) - // main interface - if("main") - state = STATE_DEFAULT - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - if("login") - var/mob/M = usr - - var/obj/item/card/id/I = M.get_idcard(TRUE) - - if(I && istype(I)) - if(check_access(I)) - authenticated = 1 - auth_id = "[I.registered_name] ([I.assignment])" - if((ACCESS_CAPTAIN in I.access)) - authenticated = 2 - playsound(src, 'sound/machines/terminal_on.ogg', 50, 0) - if(obj_flags & EMAGGED) - authenticated = 2 - auth_id = "Unknown" - to_chat(M, "[src] lets out a quiet alarm as its login is overridden.") - playsound(src, 'sound/machines/terminal_on.ogg', 50, 0) - playsound(src, 'sound/machines/terminal_alert.ogg', 25, 0) - if(prob(25)) - for(var/mob/living/silicon/ai/AI in active_ais()) - SEND_SOUND(AI, sound('sound/machines/terminal_alert.ogg', volume = 10)) //Very quiet for balance reasons - if("logout") - authenticated = 0 - playsound(src, 'sound/machines/terminal_off.ogg', 50, 0) - - if("swipeidseclevel") - var/mob/M = usr - var/obj/item/card/id/I = M.get_active_held_item() - if (istype(I, /obj/item/pda)) - var/obj/item/pda/pda = I - I = pda.id - if (I && istype(I)) - if(ACCESS_CAPTAIN in I.access) - var/old_level = GLOB.security_level - if(!tmp_alertlevel) - tmp_alertlevel = SEC_LEVEL_GREEN - if(tmp_alertlevel < SEC_LEVEL_GREEN) - tmp_alertlevel = SEC_LEVEL_GREEN - if(tmp_alertlevel == SEC_LEVEL_BLUE) - tmp_alertlevel = SEC_LEVEL_BLUE - if(tmp_alertlevel > SEC_LEVEL_AMBER) - tmp_alertlevel = SEC_LEVEL_AMBER //Cannot engage delta with this - set_security_level(tmp_alertlevel) - if(GLOB.security_level != old_level) - to_chat(usr, "Authorization confirmed. Modifying security level.") - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - //Only notify people if an actual change happened - var/security_level = get_security_level() - log_game("[key_name(usr)] has changed the security level to [security_level] with [src] at [AREACOORD(usr)].") - message_admins("[ADMIN_LOOKUPFLW(usr)] has changed the security level to [security_level] with [src] at [AREACOORD(usr)].") - deadchat_broadcast("[usr.real_name] has changed the security level to [security_level] with [src] at [get_area_name(usr, TRUE)].", usr) - tmp_alertlevel = 0 - else - to_chat(usr, "You are not authorized to do this!") - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - tmp_alertlevel = 0 - state = STATE_DEFAULT - else - to_chat(usr, "You need to swipe your ID!") - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - - if("announce") - if(authenticated==2) - playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) - make_announcement(usr) - - if("crossserver") - if(authenticated==2) - if(!checkCCcooldown()) - to_chat(usr, "Arrays recycling. Please stand by.") - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - var/input = stripped_multiline_input(usr, "Please choose a message to transmit to allied stations. Please be aware that this process is very expensive, and abuse will lead to... termination.", "Send a message to an allied station.", "") - if(!input || !(usr in view(1,src)) || !checkCCcooldown()) - return - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - send2otherserver("[station_name()]", input,"Comms_Console") - minor_announce(input, title = "Outgoing message to allied station") - usr.log_talk(input, LOG_SAY, tag="message to the other server") - message_admins("[ADMIN_LOOKUPFLW(usr)] has sent a message to the other server.") - deadchat_broadcast("[usr.real_name] has sent an outgoing message to the other station(s).", usr) - CM.lastTimeUsed = world.time - - if("purchase_menu") - state = STATE_PURCHASE - - if("buyshuttle") - if(authenticated==2) - var/list/shuttles = flatten_list(SSmapping.shuttle_templates) - var/datum/map_template/shuttle/S = locate(href_list["chosen_shuttle"]) in shuttles - if(S && istype(S)) - if(SSshuttle.emergency.mode != SHUTTLE_RECALL && SSshuttle.emergency.mode != SHUTTLE_IDLE) - to_chat(usr, "It's a bit late to buy a new shuttle, don't you think?") - return - if(SSshuttle.shuttle_purchased) - to_chat(usr, "A replacement shuttle has already been purchased.") - else if(!S.prerequisites_met()) - to_chat(usr, "You have not met the requirements for purchasing this shuttle.") - else - if(SSshuttle.points >= S.credit_cost) - var/obj/machinery/shuttle_manipulator/M = locate() in GLOB.machines - if(M) - SSshuttle.shuttle_purchased = TRUE - SSshuttle.points -= S.credit_cost - minor_announce("[usr.real_name] has purchased [S.name] for [S.credit_cost] credits." , "Shuttle Purchase") - message_admins("[ADMIN_LOOKUPFLW(usr)] purchased [S.name].") - SSblackbox.record_feedback("text", "shuttle_purchase", 1, "[S.name]") - M.unload_preview() - M.load_template(S) - M.existing_shuttle = SSshuttle.emergency - M.action_load(S) - message_admins("[S.name] loaded, purchased by [usr]") - else - to_chat(usr, "Something went wrong! The shuttle exchange system seems to be down.") - else - to_chat(usr, "Not enough credits.") - - if("callshuttle") - state = STATE_DEFAULT - if(authenticated) - state = STATE_CALLSHUTTLE - if("callshuttle2") - if(authenticated) - SSshuttle.requestEvac(usr, href_list["call"]) - if(SSshuttle.emergency.timer) - post_status("shuttle") - state = STATE_DEFAULT - if("cancelshuttle") - state = STATE_DEFAULT - if(authenticated) - state = STATE_CANCELSHUTTLE - if("cancelshuttle2") - if(authenticated) - if((world.realtime - SSshuttle.realtimeofstart) > SSshuttle.auto_call) //Citadel Edit Removing auto_call caused recall. - say("Warning: Emergency shuttle recalls have been blocked by Central Command due to ongoing crew transfer procedures.") - else - SSshuttle.cancelEvac(usr) - state = STATE_DEFAULT - if("messagelist") - currmsg = 0 - state = STATE_MESSAGELIST - if("viewmessage") - state = STATE_VIEWMESSAGE - if (!currmsg) - if(href_list["message-num"]) - var/msgnum = text2num(href_list["message-num"]) - currmsg = messages[msgnum] - else - state = STATE_MESSAGELIST - if("delmessage") - state = currmsg ? STATE_DELMESSAGE : STATE_MESSAGELIST - if("delmessage2") - if(authenticated) - if(currmsg) - if(aicurrmsg == currmsg) - aicurrmsg = null - messages -= currmsg - currmsg = null - state = STATE_MESSAGELIST - else - state = STATE_VIEWMESSAGE - if("respond") - var/answer = text2num(href_list["answer"]) - if(!currmsg || !answer || currmsg.possible_answers.len < answer) - state = STATE_MESSAGELIST - else - if(!currmsg.answered) - currmsg.answered = answer - log_game("[key_name(usr)] answered [currmsg.title] comm message. Answer : [currmsg.answered]") - if(currmsg) - currmsg.answer_callback.InvokeAsync() - state = STATE_VIEWMESSAGE - updateDialog() - if("status") - state = STATE_STATUSDISPLAY - if("securitylevel") - tmp_alertlevel = text2num( href_list["newalertlevel"] ) - if(!tmp_alertlevel) - tmp_alertlevel = 0 - state = STATE_CONFIRM_LEVEL - if("changeseclevel") - state = STATE_ALERT_LEVEL - - if("emergencyaccess") - state = STATE_TOGGLE_EMERGENCY - if("enableemergency") - make_maint_all_access() - log_game("[key_name(usr)] enabled emergency maintenance access.") - message_admins("[ADMIN_LOOKUPFLW(usr)] enabled emergency maintenance access.") - deadchat_broadcast("[usr.real_name] enabled emergency maintenance access at [get_area_name(usr, TRUE)].", usr) - state = STATE_DEFAULT - if("disableemergency") - revoke_maint_all_access() - log_game("[key_name(usr)] disabled emergency maintenance access.") - message_admins("[ADMIN_LOOKUPFLW(usr)] disabled emergency maintenance access.") - deadchat_broadcast("[usr.real_name] disabled emergency maintenance access at [get_area_name(usr, TRUE)].", usr) - state = STATE_DEFAULT - - // Status display stuff - if("setstat") - playsound(src, "terminal_type", 50, 0) - switch(href_list["statdisp"]) - if("message") - post_status("message", stat_msg1, stat_msg2) - if("alert") - post_status("alert", href_list["alert"]) - else - post_status(href_list["statdisp"]) - - if("setmsg1") - stat_msg1 = reject_bad_text(input("Line 1", "Enter Message Text", stat_msg1) as text|null, 40) - updateDialog() - if("setmsg2") - stat_msg2 = reject_bad_text(input("Line 2", "Enter Message Text", stat_msg2) as text|null, 40) - updateDialog() - - // OMG CENTCOM LETTERHEAD - if("MessageCentCom") - if(authenticated) - if(!checkCCcooldown()) - to_chat(usr, "Arrays recycling. Please stand by.") - return - var/input = stripped_input(usr, "Please choose a message to transmit to CentCom via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "Send a message to CentCom.", "") - if(!input || !(usr in view(1,src)) || !checkCCcooldown()) - return - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - CentCom_announce(input, usr) - to_chat(usr, "Message transmitted to Central Command.") - usr.log_talk(input, LOG_SAY, tag="CentCom announcement") - deadchat_broadcast("[usr.real_name] has messaged CentCom, \"[input]\" at [get_area_name(usr, TRUE)].", usr) - CM.lastTimeUsed = world.time - - // OMG SYNDICATE ...LETTERHEAD - if("MessageSyndicate") - if((authenticated==2) && (obj_flags & EMAGGED)) - if(!checkCCcooldown()) - to_chat(usr, "Arrays recycling. Please stand by.") - playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) - return - var/input = stripped_input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING COORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "Send a message to /??????/.", "") - if(!input || !(usr in view(1,src)) || !checkCCcooldown()) - return - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - Syndicate_announce(input, usr) - to_chat(usr, "SYSERR @l(19833)of(transmit.dm): !@$ MESSAGE TRANSMITTED TO SYNDICATE COMMAND.") - usr.log_talk(input, LOG_SAY, tag="Syndicate announcement") - deadchat_broadcast("[usr.real_name] has messaged the Syndicate, \"[input]\" at [get_area_name(usr, TRUE)].", usr) - CM.lastTimeUsed = world.time - - if("RestoreBackup") - to_chat(usr, "Backup routing data restored!") - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - obj_flags &= ~EMAGGED - updateDialog() - - if("nukerequest") //When there's no other way - if(authenticated==2) - if(!checkCCcooldown()) - to_chat(usr, "Arrays recycling. Please stand by.") - return - var/input = stripped_input(usr, "Please enter the reason for requesting the nuclear self-destruct codes. Misuse of the nuclear request system will not be tolerated under any circumstances. Transmission does not guarantee a response.", "Self Destruct Code Request.","") - if(!input || !(usr in view(1,src)) || !checkCCcooldown()) - return - Nuke_request(input, usr) - to_chat(usr, "Request sent.") - usr.log_message("has requested the nuclear codes from CentCom", LOG_SAY) - priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested","commandreport") - CM.lastTimeUsed = world.time - - - // AI interface - if("ai-main") - aicurrmsg = null - aistate = STATE_DEFAULT - if("ai-callshuttle") - aistate = STATE_CALLSHUTTLE - if("ai-callshuttle2") - SSshuttle.requestEvac(usr, href_list["call"]) - aistate = STATE_DEFAULT - if("ai-messagelist") - aicurrmsg = null - aistate = STATE_MESSAGELIST - if("ai-viewmessage") - aistate = STATE_VIEWMESSAGE - if (!aicurrmsg) - if(href_list["message-num"]) - var/msgnum = text2num(href_list["message-num"]) - aicurrmsg = messages[msgnum] - else - aistate = STATE_MESSAGELIST - if("ai-delmessage") - aistate = aicurrmsg ? STATE_DELMESSAGE : STATE_MESSAGELIST - if("ai-delmessage2") - if(aicurrmsg) - if(currmsg == aicurrmsg) - currmsg = null - messages -= aicurrmsg - aicurrmsg = null - aistate = STATE_MESSAGELIST - if("ai-respond") - var/answer = text2num(href_list["answer"]) - if(!aicurrmsg || !answer || aicurrmsg.possible_answers.len < answer) - aistate = STATE_MESSAGELIST - else - if(!aicurrmsg.answered) - aicurrmsg.answered = answer - log_game("[key_name(usr)] answered [aicurrmsg.title] comm message. Answer : [aicurrmsg.answered]") - if(aicurrmsg.answer_callback) - aicurrmsg.answer_callback.InvokeAsync() - aistate = STATE_VIEWMESSAGE - if("ai-status") - aistate = STATE_STATUSDISPLAY - if("ai-announce") - make_announcement(usr, 1) - if("ai-securitylevel") - tmp_alertlevel = text2num( href_list["newalertlevel"] ) - if(!tmp_alertlevel) - tmp_alertlevel = 0 - var/old_level = GLOB.security_level - if(!tmp_alertlevel) - tmp_alertlevel = SEC_LEVEL_GREEN - if(tmp_alertlevel < SEC_LEVEL_GREEN) - tmp_alertlevel = SEC_LEVEL_GREEN - if(tmp_alertlevel == SEC_LEVEL_BLUE) - tmp_alertlevel = SEC_LEVEL_BLUE - if(tmp_alertlevel > SEC_LEVEL_AMBER) - tmp_alertlevel = SEC_LEVEL_AMBER //Cannot engage delta with this - set_security_level(tmp_alertlevel) - if(GLOB.security_level != old_level) - //Only notify people if an actual change happened - var/security_level = get_security_level() - log_game("[key_name(usr)] has changed the security level to [security_level] from [src] at [AREACOORD(usr)].") - message_admins("[ADMIN_LOOKUPFLW(usr)] has changed the security level to [security_level] from [src] at [AREACOORD(usr)].") - deadchat_broadcast("[usr.real_name] has changed the security level to [security_level] from [src] at [get_area_name(usr, TRUE)].", usr) - tmp_alertlevel = 0 - aistate = STATE_DEFAULT - if("ai-changeseclevel") - aistate = STATE_ALERT_LEVEL - if("ai-emergencyaccess") - aistate = STATE_TOGGLE_EMERGENCY - if("ai-enableemergency") - make_maint_all_access() - log_game("[key_name(usr)] enabled emergency maintenance access.") - message_admins("[ADMIN_LOOKUPFLW(usr)] enabled emergency maintenance access.") - deadchat_broadcast("[usr.real_name] enabled emergency maintenance access.", usr) - aistate = STATE_DEFAULT - if("ai-disableemergency") - revoke_maint_all_access() - log_game("[key_name(usr)] disabled emergency maintenance access.") - message_admins("[ADMIN_LOOKUPFLW(usr)] disabled emergency maintenance access.") - deadchat_broadcast("[usr.real_name] disabled emergency maintenance access.", usr) - aistate = STATE_DEFAULT - - updateUsrDialog() - -/obj/machinery/computer/communications/attackby(obj/I, mob/user, params) - if(istype(I, /obj/item/card/id)) - attack_hand(user) - else - return ..() - -/obj/machinery/computer/communications/emag_act(mob/user) - . = ..() - if(obj_flags & EMAGGED) - return - obj_flags |= EMAGGED - SSshuttle.shuttle_purchase_requirements_met |= "emagged" - if(authenticated == 1) - authenticated = 2 - to_chat(user, "You scramble the communication routing circuits!") - playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0) - return TRUE - -/obj/machinery/computer/communications/ui_interact(mob/user) - . = ..() - if (z > 6) - to_chat(user, "Unable to establish a connection: \black You're too far away from the station!") - return - - var/dat = "" - if(SSshuttle.emergency.mode == SHUTTLE_CALL) - var/timeleft = SSshuttle.emergency.timeLeft() - dat += "Emergency shuttle\n
      \nETA: [timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]" - - - var/datum/browser/popup = new(user, "communications", "Communications Console", 400, 500) - popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) - - if(issilicon(user)) - var/dat2 = interact_ai(user) // give the AI a different interact proc to limit its access - if(dat2) - dat += dat2 - popup.set_content(dat) - popup.open() - return - - switch(state) - if(STATE_DEFAULT) - if (authenticated) - if(SSshuttle.emergencyCallAmount) - if(SSshuttle.emergencyLastCallLoc) - dat += "Most recent shuttle call/recall traced to: [format_text(SSshuttle.emergencyLastCallLoc.name)]
      " - else - dat += "Unable to trace most recent shuttle call/recall signal.
      " - dat += "Logged in as: [auth_id]" - dat += "
      " - dat += "
      \[ Log Out \]
      " - dat += "
      General Functions" - dat += "
      \[ Message List \]" - switch(SSshuttle.emergency.mode) - if(SHUTTLE_IDLE, SHUTTLE_RECALL) - dat += "
      \[ Call Emergency Shuttle \]" - else - dat += "
      \[ Cancel Shuttle Call \]" - - dat += "
      \[ Set Status Display \]" - if (authenticated==2) - dat += "

      Captain Functions" - dat += "
      \[ Make a Captain's Announcement \]" - var/cross_servers_count = length(CONFIG_GET(keyed_list/cross_server)) - if(cross_servers_count) - dat += "
      \[ Send a message to [cross_servers_count == 1 ? "an " : ""]allied station[cross_servers_count > 1 ? "s" : ""] \]" - if(SSmapping.config.allow_custom_shuttles) - dat += "
      \[ Purchase Shuttle \]" - dat += "
      \[ Change Alert Level \]" - dat += "
      \[ Emergency Maintenance Access \]" - dat += "
      \[ Request Nuclear Authentication Codes \]" - if(!(obj_flags & EMAGGED)) - dat += "
      \[ Send Message to CentCom \]" - else - dat += "
      \[ Send Message to \[UNKNOWN\] \]" - dat += "
      \[ Restore Backup Routing Data \]" - else - dat += "
      \[ Log In \]" - if(STATE_CALLSHUTTLE) - dat += get_call_shuttle_form() - playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) - if(STATE_CANCELSHUTTLE) - dat += get_cancel_shuttle_form() - playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) - if(STATE_MESSAGELIST) - dat += "Messages:" - for(var/i in 1 to messages.len) - var/datum/comm_message/M = messages[i] - dat += "
      [M.title]" - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - if(STATE_VIEWMESSAGE) - if (currmsg) - dat += "[currmsg.title]

      [currmsg.content]" - if(!currmsg.answered && currmsg.possible_answers.len) - for(var/i in 1 to currmsg.possible_answers.len) - var/answer = currmsg.possible_answers[i] - dat += "
      \[ Answer : [answer] \]" - else if(currmsg.answered) - var/answered = currmsg.possible_answers[currmsg.answered] - dat += "
      Archived Answer : [answered]" - dat += "

      \[ Delete \]" - else - aistate = STATE_MESSAGELIST - attack_hand(user) - return - if(STATE_DELMESSAGE) - if (currmsg) - dat += "Are you sure you want to delete this message? \[ OK | Cancel \]" - else - state = STATE_MESSAGELIST - attack_hand(user) - return - if(STATE_STATUSDISPLAY) - dat += "Set Status Displays
      " - dat += "\[ Clear \]
      " - dat += "\[ Shuttle ETA \]
      " - dat += "\[ Message \]" - dat += "
      " - dat += "\[ Alert: None |" - dat += " Red Alert |" - dat += " Lockdown |" - dat += " Biohazard \]

      " - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) - if(STATE_ALERT_LEVEL) - dat += "Current alert level: [get_security_level()]
      " - if(GLOB.security_level == SEC_LEVEL_DELTA) - dat += "The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate." - else - dat += "Amber
      " - dat += "Blue
      " - dat += "Green" - if(STATE_CONFIRM_LEVEL) - dat += "Current alert level: [get_security_level()]
      " - dat += "Confirm the change to: [num2seclevel(tmp_alertlevel)]
      " - dat += "Swipe ID to confirm change.
      " - if(STATE_TOGGLE_EMERGENCY) - playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) - if(GLOB.emergency_access == 1) - dat += "Emergency Maintenance Access is currently ENABLED" - dat += "
      Restore maintenance access restrictions?
      \[ OK | Cancel \]" - else - dat += "Emergency Maintenance Access is currently DISABLED" - dat += "
      Lift access restrictions on maintenance and external airlocks?
      \[ OK | Cancel \]" - - if(STATE_PURCHASE) - dat += "Budget: [SSshuttle.points] Credits.
      " - dat += "
      " - dat += "Caution: Purchasing dangerous shuttles may lead to mutiny and/or death.
      " - dat += "
      " - for(var/shuttle_id in SSmapping.shuttle_templates) - var/datum/map_template/shuttle/S = SSmapping.shuttle_templates[shuttle_id] - if(S.can_be_bought && S.credit_cost < INFINITY) - dat += "[S.name] | [S.credit_cost] Credits
      " - dat += "[S.description]
      " - if(S.prerequisites) - dat += "Prerequisites: [S.prerequisites]
      " - dat += "(Purchase)

      " - - dat += "

      \[ [(state != STATE_DEFAULT) ? "Main Menu | " : ""]Close \]" - - popup.set_content(dat) - popup.open() - -/obj/machinery/computer/communications/proc/get_javascript_header(form_id) - var/dat = {""} - return dat - -/obj/machinery/computer/communications/proc/get_call_shuttle_form(ai_interface = 0) - var/form_id = "callshuttle" - var/dat = get_javascript_header(form_id) - dat += "
    30. ") - while(listlevel < count_w) - line = "
        " + line - listlevel++ - while(listlevel > count_w) - line = "
      " + line - listlevel-- - - else while(listlevel >= 0) - line = "" + line - listlevel-- - - tlist[i] = line - // end for - - t = tlist[1] - for(var/i = 2, i <= tlistlen, i++) - t += "\n" + tlist[i] - - while(listlevel >= 0) - t += "" - listlevel-- - - else - t = replacetext(t, "((", "") - t = replacetext(t, "))", "") - - // Parse headers - - t = replacetext(t, regex("^#(?!#) ?(.+)$", "gm"), "

      $1

      ") - t = replacetext(t, regex("^##(?!#) ?(.+)$", "gm"), "

      $1

      ") - t = replacetext(t, regex("^###(?!#) ?(.+)$", "gm"), "

      $1

      ") - t = replacetext(t, regex("^#### ?(.+)$", "gm"), "
      $1
      ") - - // Parse most rules - - t = replacetext(t, regex("\\*(\[^\\*\]*)\\*", "g"), "$1") - t = replacetext(t, regex("_(\[^_\]*)_", "g"), "$1") - t = replacetext(t, "", "!") - t = replacetext(t, "
      ", "!") - t = replacetext(t, regex("\\!(\[^\\!\]+)\\!", "g"), "$1") - t = replacetext(t, regex("\\^(\[^\\^\]+)\\^", "g"), "$1") - t = replacetext(t, regex("\\|(\[^\\|\]+)\\|", "g"), "
      $1
      ") - t = replacetext(t, "!", "
      ") - - return t - -/proc/parsemarkdown_basic_step2(t) - if(length(t) <= 0) - return - - // Restore the single characters used - - t = replacetext(t, "$a", "!") - - // Redo the escaping - - t = replacetext(t, "$1", "\\") - t = replacetext(t, "$2", "**") - t = replacetext(t, "$3", "*") - t = replacetext(t, "$4", "__") - t = replacetext(t, "$5", "_") - t = replacetext(t, "$6", "^") - t = replacetext(t, "$7", "((") - t = replacetext(t, "$8", "))") - t = replacetext(t, "$9", "|") - t = replacetext(t, "$0", "%") - t = replacetext(t, "$-", "$") - - return t - -/proc/parsemarkdown_basic(t, limited=FALSE) - t = parsemarkdown_basic_step1(t, limited) - t = parsemarkdown_basic_step2(t) - return t - -/proc/parsemarkdown(t, mob/user=null, limited=FALSE) - if(length(t) <= 0) - return - - // Premanage whitespace - - t = replacetext(t, regex("\[^\\S\\r\\n \]", "g"), " ") - - t = parsemarkdown_basic_step1(t) - - t = replacetext(t, regex("%s(?:ign)?(?=\\s|$)", "igm"), user ? "[user.real_name]" : "") - t = replacetext(t, regex("%f(?:ield)?(?=\\s|$)", "igm"), "") - - t = parsemarkdown_basic_step2(t) - - // Manage whitespace - - t = replacetext(t, regex("(?:\\r\\n?|\\n)", "g"), "
      ") - - t = replacetext(t, " ", "  ") - - // Done - - return t - -#define string2charlist(string) (splittext(string, regex("(.)")) - splittext(string, "")) - -/proc/rot13(text = "") - var/list/textlist = string2charlist(text) - var/list/result = list() - for(var/c in textlist) - var/ca = text2ascii(c) - if(ca >= text2ascii("a") && ca <= text2ascii("m")) - ca += 13 - else if(ca >= text2ascii("n") && ca <= text2ascii("z")) - ca -= 13 - else if(ca >= text2ascii("A") && ca <= text2ascii("M")) - ca += 13 - else if(ca >= text2ascii("N") && ca <= text2ascii("Z")) - ca -= 13 - result += ascii2text(ca) - return jointext(result, "") - -//Takes a list of values, sanitizes it down for readability and character count, -//then exports it as a json file at data/npc_saves/[filename].json. -//As far as SS13 is concerned this is write only data. You can't change something -//in the json file and have it be reflected in the in game item/mob it came from. -//(That's what things like savefiles are for) Note that this list is not shuffled. -/proc/twitterize(list/proposed, filename, cullshort = 1, storemax = 1000) - if(!islist(proposed) || !filename || !CONFIG_GET(flag/log_twitter)) - return - - //Regular expressions are, as usual, absolute magic - var/regex/all_invalid_symbols = new("\[^ -~]+") - - var/list/accepted = list() - for(var/string in proposed) - if(findtext(string,GLOB.is_website) || findtext(string,GLOB.is_email) || findtext(string,all_invalid_symbols) || !findtext(string,GLOB.is_alphanumeric)) - continue - var/buffer = "" - var/early_culling = TRUE - for(var/pos = 1, pos <= length(string), pos++) - var/let = copytext(string, pos, (pos + 1) % length(string)) - if(early_culling && !findtext(let,GLOB.is_alphanumeric)) - continue - early_culling = FALSE - buffer += let - if(!findtext(buffer,GLOB.is_alphanumeric)) - continue - var/punctbuffer = "" - var/cutoff = length(buffer) - for(var/pos = length(buffer), pos >= 0, pos--) - var/let = copytext(buffer, pos, (pos + 1) % length(buffer)) - if(findtext(let,GLOB.is_alphanumeric)) - break - if(findtext(let,GLOB.is_punctuation)) - punctbuffer = let + punctbuffer //Note this isn't the same thing as using += - cutoff = pos - if(punctbuffer) //We clip down excessive punctuation to get the letter count lower and reduce repeats. It's not perfect but it helps. - var/exclaim = FALSE - var/question = FALSE - var/periods = 0 - for(var/pos = length(punctbuffer), pos >= 0, pos--) - var/punct = copytext(punctbuffer, pos, (pos + 1) % length(punctbuffer)) - if(!exclaim && findtext(punct,"!")) - exclaim = TRUE - if(!question && findtext(punct,"?")) - question = TRUE - if(!exclaim && !question && findtext(punct,".")) - periods += 1 - if(exclaim) - if(question) - punctbuffer = "?!" - else - punctbuffer = "!" - else if(question) - punctbuffer = "?" - else if(periods) - if(periods > 1) - punctbuffer = "..." - else - punctbuffer = "" //Grammer nazis be damned - buffer = copytext(buffer, 1, cutoff) + punctbuffer - if(!findtext(buffer,GLOB.is_alphanumeric)) - continue - if(!buffer || length(buffer) > 280 || length(buffer) <= cullshort || buffer in accepted) - continue - - accepted += buffer - - var/log = file("data/npc_saves/[filename].json") //If this line ever shows up as changed in a PR be very careful you aren't being memed on - var/list/oldjson = list() - var/list/oldentries = list() - if(fexists(log)) - oldjson = json_decode(file2text(log)) - oldentries = oldjson["data"] - if(!isemptylist(oldentries)) - for(var/string in accepted) - for(var/old in oldentries) - if(string == old) - oldentries.Remove(old) //Line's position in line is "refreshed" until it falls off the in game radar - break - - var/list/finalized = list() - finalized = accepted.Copy() + oldentries.Copy() //we keep old and unreferenced phrases near the bottom for culling - listclearnulls(finalized) - if(!isemptylist(finalized) && length(finalized) > storemax) - finalized.Cut(storemax + 1) - fdel(log) - - var/list/tosend = list() - tosend["data"] = finalized - WRITE_FILE(log, json_encode(tosend)) - -//Used for applying byonds text macros to strings that are loaded at runtime -/proc/apply_text_macros(string) - var/next_backslash = findtext(string, "\\") - if(!next_backslash) - return string - - var/leng = length(string) - - var/next_space = findtext(string, " ", next_backslash + 1) - if(!next_space) - next_space = leng - next_backslash - - if(!next_space) //trailing bs - return string - - var/base = next_backslash == 1 ? "" : copytext(string, 1, next_backslash) - var/macro = lowertext(copytext(string, next_backslash + 1, next_space)) - var/rest = next_backslash > leng ? "" : copytext(string, next_space + 1) - - //See https://secure.byond.com/docs/ref/info.html#/DM/text/macros - switch(macro) - //prefixes/agnostic - if("the") - rest = text("\the []", rest) - if("a") - rest = text("\a []", rest) - if("an") - rest = text("\an []", rest) - if("proper") - rest = text("\proper []", rest) - if("improper") - rest = text("\improper []", rest) - if("roman") - rest = text("\roman []", rest) - //postfixes - if("th") - base = text("[]\th", rest) - if("s") - base = text("[]\s", rest) - if("he") - base = text("[]\he", rest) - if("she") - base = text("[]\she", rest) - if("his") - base = text("[]\his", rest) - if("himself") - base = text("[]\himself", rest) - if("herself") - base = text("[]\herself", rest) - if("hers") - base = text("[]\hers", rest) - - . = base - if(rest) - . += .(rest) - -//Replacement for the \th macro when you want the whole word output as text (first instead of 1st) -/proc/thtotext(number) - if(!isnum(number)) - return - switch(number) - if(1) - return "first" - if(2) - return "second" - if(3) - return "third" - if(4) - return "fourth" - if(5) - return "fifth" - if(6) - return "sixth" - if(7) - return "seventh" - if(8) - return "eighth" - if(9) - return "ninth" - if(10) - return "tenth" - if(11) - return "eleventh" - if(12) - return "twelfth" - else - return "[number]\th" - -/proc/unintelligize(message) - var/prefix=copytext(message,1,2) - if(prefix == ";") - message = copytext(message,2) - else if(prefix in list(":","#")) - prefix += copytext(message,2,3) - message = copytext(message,3) - else - prefix="" - - var/list/words = splittext(message," ") - var/list/rearranged = list() - for(var/i=1;i<=words.len;i++) - var/cword = pick(words) - words.Remove(cword) - var/suffix = copytext(cword,length(cword)-1,length(cword)) - while(length(cword)>0 && suffix in list(".",",",";","!",":","?")) - cword = copytext(cword,1 ,length(cword)-1) - suffix = copytext(cword,length(cword)-1,length(cword) ) - if(length(cword)) - rearranged += cword - message = "[prefix][jointext(rearranged," ")]" - . = message - -#define is_alpha(X) ((text2ascii(X) <= 122) && (text2ascii(X) >= 97)) +/* + * Holds procs designed to help with filtering text + * Contains groups: + * SQL sanitization/formating + * Text sanitization + * Text searches + * Text modification + * Misc + */ + + +/* + * SQL sanitization + */ + +// Run all strings to be used in an SQL query through this proc first to properly escape out injection attempts. +/proc/sanitizeSQL(t) + return SSdbcore.Quote("[t]") + +/proc/format_table_name(table as text) + return CONFIG_GET(string/feedback_tableprefix) + table + +/* + * Text sanitization + */ + +//Simply removes < and > and limits the length of the message +/proc/strip_html_simple(t,limit=MAX_MESSAGE_LEN) + var/list/strip_chars = list("<",">") + t = copytext(t,1,limit) + for(var/char in strip_chars) + var/index = findtext(t, char) + while(index) + t = copytext(t, 1, index) + copytext(t, index+1) + index = findtext(t, char) + return t + +//Removes a few problematic characters +/proc/sanitize_simple(t,list/repl_chars = list("\n"="#","\t"="#")) + for(var/char in repl_chars) + var/index = findtext(t, char) + while(index) + t = copytext(t, 1, index) + repl_chars[char] + copytext(t, index+1) + index = findtext(t, char, index+1) + return t + +/proc/sanitize_filename(t) + return sanitize_simple(t, list("\n"="", "\t"="", "/"="", "\\"="", "?"="", "%"="", "*"="", ":"="", "|"="", "\""="", "<"="", ">"="")) + +//Runs byond's sanitization proc along-side sanitize_simple +/proc/sanitize(t,list/repl_chars = null) + return html_encode(sanitize_simple(t,repl_chars)) + +//Runs sanitize and strip_html_simple +//I believe strip_html_simple() is required to run first to prevent '<' from displaying as '<' after sanitize() calls byond's html_encode() +/proc/strip_html(t,limit=MAX_MESSAGE_LEN) + return copytext((sanitize(strip_html_simple(t))),1,limit) + +//Runs byond's sanitization proc along-side strip_html_simple +//I believe strip_html_simple() is required to run first to prevent '<' from displaying as '<' that html_encode() would cause +/proc/adminscrub(t,limit=MAX_MESSAGE_LEN) + return copytext((html_encode(strip_html_simple(t))),1,limit) + + +//Returns null if there is any bad text in the string +/proc/reject_bad_text(text, max_length=512) + if(length(text) > max_length) + return //message too long + var/non_whitespace = 0 + for(var/i=1, i<=length(text), i++) + switch(text2ascii(text,i)) + if(62,60,92,47) + return //rejects the text if it contains these bad characters: <, >, \ or / + if(127 to 255) + return //rejects weird letters like � + if(0 to 31) + return //more weird stuff + if(32) + continue //whitespace + else + non_whitespace = 1 + if(non_whitespace) + return text //only accepts the text if it has some non-spaces + +// Used to get a properly sanitized input, of max_length +// no_trim is self explanatory but it prevents the input from being trimed if you intend to parse newlines or whitespace. +/proc/stripped_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE) + var/name = input(user, message, title, default) as text|null + if(no_trim) + return copytext(html_encode(name), 1, max_length) + else + return trim(html_encode(name), max_length) //trim is "outside" because html_encode can expand single symbols into multiple symbols (such as turning < into <) + +// Used to get a properly sanitized multiline input, of max_length +/proc/stripped_multiline_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE) + var/name = input(user, message, title, default) as message|null + if(isnull(name)) // Return null if canceled. + return null + if(no_trim) + return copytext(html_encode(name), 1, max_length) + else + return trim(html_encode(name), max_length) + +//Filters out undesirable characters from names +/proc/reject_bad_name(t_in, allow_numbers=0, max_length=MAX_NAME_LEN) + if(!t_in || length(t_in) > max_length) + return //Rejects the input if it is null or if it is longer then the max length allowed + + var/number_of_alphanumeric = 0 + var/last_char_group = 0 + var/t_out = "" + + for(var/i=1, i<=length(t_in), i++) + var/ascii_char = text2ascii(t_in,i) + switch(ascii_char) + // A .. Z + if(65 to 90) //Uppercase Letters + t_out += ascii2text(ascii_char) + number_of_alphanumeric++ + last_char_group = 4 + + // a .. z + if(97 to 122) //Lowercase Letters + if(last_char_group<2) + t_out += ascii2text(ascii_char-32) //Force uppercase first character + else + t_out += ascii2text(ascii_char) + number_of_alphanumeric++ + last_char_group = 4 + + // 0 .. 9 + if(48 to 57) //Numbers + if(!last_char_group) + continue //suppress at start of string + if(!allow_numbers) + continue + t_out += ascii2text(ascii_char) + number_of_alphanumeric++ + last_char_group = 3 + + // ' - . + if(39,45,46) //Common name punctuation + if(!last_char_group) + continue + t_out += ascii2text(ascii_char) + last_char_group = 2 + + // ~ | @ : # $ % & * + + if(126,124,64,58,35,36,37,38,42,43) //Other symbols that we'll allow (mainly for AI) + if(!last_char_group) + continue //suppress at start of string + if(!allow_numbers) + continue + t_out += ascii2text(ascii_char) + last_char_group = 2 + + //Space + if(32) + if(last_char_group <= 1) + continue //suppress double-spaces and spaces at start of string + t_out += ascii2text(ascii_char) + last_char_group = 1 + else + return + + if(number_of_alphanumeric < 2) + return //protects against tiny names like "A" and also names like "' ' ' ' ' ' ' '" + + if(last_char_group == 1) + t_out = copytext(t_out,1,length(t_out)) //removes the last character (in this case a space) + + for(var/bad_name in list("space","floor","wall","r-wall","monkey","unknown","inactive ai")) //prevents these common metagamey names + if(cmptext(t_out,bad_name)) + return //(not case sensitive) + + return t_out + +//html_encode helper proc that returns the smallest non null of two numbers +//or 0 if they're both null (needed because of findtext returning 0 when a value is not present) +/proc/non_zero_min(a, b) + if(!a) + return b + if(!b) + return a + return (a < b ? a : b) + +/* + * Text searches + */ + +//Checks the beginning of a string for a specified sub-string +//Returns the position of the substring or 0 if it was not found +/proc/dd_hasprefix(text, prefix) + var/start = 1 + var/end = length(prefix) + 1 + return findtext(text, prefix, start, end) + +//Checks the beginning of a string for a specified sub-string. This proc is case sensitive +//Returns the position of the substring or 0 if it was not found +/proc/dd_hasprefix_case(text, prefix) + var/start = 1 + var/end = length(prefix) + 1 + return findtextEx(text, prefix, start, end) + +//Checks the end of a string for a specified substring. +//Returns the position of the substring or 0 if it was not found +/proc/dd_hassuffix(text, suffix) + var/start = length(text) - length(suffix) + if(start) + return findtext(text, suffix, start, null) + return + +//Checks the end of a string for a specified substring. This proc is case sensitive +//Returns the position of the substring or 0 if it was not found +/proc/dd_hassuffix_case(text, suffix) + var/start = length(text) - length(suffix) + if(start) + return findtextEx(text, suffix, start, null) + +//Checks if any of a given list of needles is in the haystack +/proc/text_in_list(haystack, list/needle_list, start=1, end=0) + for(var/needle in needle_list) + if(findtext(haystack, needle, start, end)) + return 1 + return 0 + +//Like above, but case sensitive +/proc/text_in_list_case(haystack, list/needle_list, start=1, end=0) + for(var/needle in needle_list) + if(findtextEx(haystack, needle, start, end)) + return 1 + return 0 + +//Adds 'u' number of zeros ahead of the text 't' +/proc/add_zero(t, u) + while (length(t) < u) + t = "0[t]" + return t + +//Adds 'u' number of spaces ahead of the text 't' +/proc/add_lspace(t, u) + while(length(t) < u) + t = " [t]" + return t + +//Adds 'u' number of spaces behind the text 't' +/proc/add_tspace(t, u) + while(length(t) < u) + t = "[t] " + return t + +//Returns a string with reserved characters and spaces before the first letter removed +/proc/trim_left(text) + for (var/i = 1 to length(text)) + if (text2ascii(text, i) > 32) + return copytext(text, i) + return "" + +//Returns a string with reserved characters and spaces after the last letter removed +/proc/trim_right(text) + for (var/i = length(text), i > 0, i--) + if (text2ascii(text, i) > 32) + return copytext(text, 1, i + 1) + + return "" + +//Returns a string with reserved characters and spaces before the first word and after the last word removed. +/proc/trim(text, max_length) + if(max_length) + text = copytext(text, 1, max_length) + return trim_left(trim_right(text)) + +//Returns a string with the first element of the string capitalized. +/proc/capitalize(t as text) + return uppertext(copytext(t, 1, 2)) + copytext(t, 2) + +//Centers text by adding spaces to either side of the string. +/proc/dd_centertext(message, length) + var/new_message = message + var/size = length(message) + var/delta = length - size + if(size == length) + return new_message + if(size > length) + return copytext(new_message, 1, length + 1) + if(delta == 1) + return new_message + " " + if(delta % 2) + new_message = " " + new_message + delta-- + var/spaces = add_lspace("",delta/2-1) + return spaces + new_message + spaces + +//Limits the length of the text. Note: MAX_MESSAGE_LEN and MAX_NAME_LEN are widely used for this purpose +/proc/dd_limittext(message, length) + var/size = length(message) + if(size <= length) + return message + return copytext(message, 1, length + 1) + + +/proc/stringmerge(text,compare,replace = "*") +//This proc fills in all spaces with the "replace" var (* by default) with whatever +//is in the other string at the same spot (assuming it is not a replace char). +//This is used for fingerprints + var/newtext = text + if(length(text) != length(compare)) + return 0 + for(var/i = 1, i < length(text), i++) + var/a = copytext(text,i,i+1) + var/b = copytext(compare,i,i+1) +//if it isn't both the same letter, or if they are both the replacement character +//(no way to know what it was supposed to be) + if(a != b) + if(a == replace) //if A is the replacement char + newtext = copytext(newtext,1,i) + b + copytext(newtext, i+1) + else if(b == replace) //if B is the replacement char + newtext = copytext(newtext,1,i) + a + copytext(newtext, i+1) + else //The lists disagree, Uh-oh! + return 0 + return newtext + +/proc/stringpercent(text,character = "*") +//This proc returns the number of chars of the string that is the character +//This is used for detective work to determine fingerprint completion. + if(!text || !character) + return 0 + var/count = 0 + for(var/i = 1, i <= length(text), i++) + var/a = copytext(text,i,i+1) + if(a == character) + count++ + return count + +/proc/reverse_text(text = "") + var/new_text = "" + for(var/i = length(text); i > 0; i--) + new_text += copytext(text, i, i+1) + return new_text + +GLOBAL_LIST_INIT(zero_character_only, list("0")) +GLOBAL_LIST_INIT(hex_characters, list("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f")) +GLOBAL_LIST_INIT(alphabet, list("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")) +GLOBAL_LIST_INIT(binary, list("0","1")) +/proc/random_string(length, list/characters) + . = "" + for(var/i=1, i<=length, i++) + . += pick(characters) + +/proc/repeat_string(times, string="") + . = "" + for(var/i=1, i<=times, i++) + . += string + +/proc/random_short_color() + return random_string(3, GLOB.hex_characters) + +/proc/random_color() + return random_string(6, GLOB.hex_characters) + +/proc/add_zero2(t, u) + var/temp1 + while (length(t) < u) + t = "0[t]" + temp1 = t + if (length(t) > u) + temp1 = copytext(t,2,u+1) + return temp1 + +//merges non-null characters (3rd argument) from "from" into "into". Returns result +//e.g. into = "Hello World" +// from = "Seeya______" +// returns"Seeya World" +//The returned text is always the same length as into +//This was coded to handle DNA gene-splicing. +/proc/merge_text(into, from, null_char="_") + . = "" + if(!istext(into)) + into = "" + if(!istext(from)) + from = "" + var/null_ascii = istext(null_char) ? text2ascii(null_char,1) : null_char + + var/previous = 0 + var/start = 1 + var/end = length(into) + 1 + + for(var/i=1, i") + t = replacetext(t, "))", "") + t = replacetext(t, regex("(-){3,}", "gm"), "
      ") + t = replacetext(t, regex("^\\((-){3,}\\)$", "gm"), "$1") + + // Parse lists + + var/list/tlist = splittext(t, "\n") + var/tlistlen = tlist.len + var/listlevel = -1 + var/singlespace = -1 // if 0, double spaces are used before asterisks, if 1, single are + for(var/i = 1, i <= tlistlen, i++) + var/line = tlist[i] + var/count_asterisk = length(replacetext(line, regex("\[^\\*\]+", "g"), "")) + if(count_asterisk % 2 == 1 && findtext(line, regex("^\\s*\\*", "g"))) // there is an extra asterisk in the beggining + + var/count_w = length(replacetext(line, regex("^( *)\\*.*$", "g"), "$1")) // whitespace before asterisk + line = replacetext(line, regex("^ *(\\*.*)$", "g"), "$1") + + if(singlespace == -1 && count_w == 2) + if(listlevel == 0) + singlespace = 0 + else + singlespace = 1 + + if(singlespace == 0) + count_w = count_w % 2 ? round(count_w / 2 + 0.25) : count_w / 2 + + line = replacetext(line, regex("\\*", ""), "
    31. " - dat += "" - dat += "" - dat += "Nature of emergency:
      " - dat += "
      Are you sure you want to call the shuttle? \[ Call \]" - return dat - -/obj/machinery/computer/communications/proc/get_cancel_shuttle_form() - var/form_id = "cancelshuttle" - var/dat = get_javascript_header(form_id) - dat += "" - dat += "" - dat += "" - - dat += "
      Are you sure you want to cancel the shuttle? \[ Cancel \]" - return dat - -/obj/machinery/computer/communications/proc/interact_ai(mob/living/silicon/ai/user) - var/dat = "" - switch(aistate) - if(STATE_DEFAULT) - if(SSshuttle.emergencyCallAmount) - if(SSshuttle.emergencyLastCallLoc) - dat += "Latest emergency signal trace attempt successful.
      Last signal origin: [format_text(SSshuttle.emergencyLastCallLoc.name)].
      " - else - dat += "Latest emergency signal trace attempt failed.
      " - if(authenticated) - dat += "Current login: [auth_id]" - else - dat += "Current login: None" - dat += "

      General Functions" - dat += "
      \[ Message List \]" - if(SSshuttle.emergency.mode == SHUTTLE_IDLE) - dat += "
      \[ Call Emergency Shuttle \]" - dat += "
      \[ Set Status Display \]" - dat += "

      Special Functions" - dat += "
      \[ Make an Announcement \]" - dat += "
      \[ Change Alert Level \]" - dat += "
      \[ Emergency Maintenance Access \]" - if(STATE_CALLSHUTTLE) - dat += get_call_shuttle_form(1) - if(STATE_MESSAGELIST) - dat += "Messages:" - for(var/i in 1 to messages.len) - var/datum/comm_message/M = messages[i] - dat += "
      [M.title]" - if(STATE_VIEWMESSAGE) - if (aicurrmsg) - dat += "[aicurrmsg.title]

      [aicurrmsg.content]" - if(!aicurrmsg.answered && aicurrmsg.possible_answers.len) - for(var/i in 1 to aicurrmsg.possible_answers.len) - var/answer = aicurrmsg.possible_answers[i] - dat += "
      \[ Answer : [answer] \]" - else if(aicurrmsg.answered) - var/answered = aicurrmsg.possible_answers[aicurrmsg.answered] - dat += "
      Archived Answer : [answered]" - dat += "

      \[ Delete \]" - else - aistate = STATE_MESSAGELIST - attack_hand(user) - return null - if(STATE_DELMESSAGE) - if(aicurrmsg) - dat += "Are you sure you want to delete this message? \[ OK | Cancel \]" - else - aistate = STATE_MESSAGELIST - attack_hand(user) - return - - if(STATE_STATUSDISPLAY) - dat += "Set Status Displays
      " - dat += "\[ Clear \]
      " - dat += "\[ Shuttle ETA \]
      " - dat += "\[ Message \]" - dat += "
      " - dat += "\[ Alert: None |" - dat += " Red Alert |" - dat += " Lockdown |" - dat += " Biohazard \]

      " - - if(STATE_ALERT_LEVEL) - dat += "Current alert level: [get_security_level()]
      " - if(GLOB.security_level == SEC_LEVEL_DELTA) - dat += "The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate." - else - dat += "Amber
      " - dat += "Blue
      " - dat += "Green" - - if(STATE_TOGGLE_EMERGENCY) - if(GLOB.emergency_access == 1) - dat += "Emergency Maintenance Access is currently ENABLED" - dat += "
      Restore maintenance access restrictions?
      \[ OK | Cancel \]" - else - dat += "Emergency Maintenance Access is currently DISABLED" - dat += "
      Lift access restrictions on maintenance and external airlocks?
      \[ OK | Cancel \]" - - dat += "

      \[ [(aistate != STATE_DEFAULT) ? "Main Menu | " : ""]Close \]" - return dat - -/obj/machinery/computer/communications/proc/make_announcement(mob/living/user, is_silicon) - if(!SScommunications.can_announce(user, is_silicon)) - to_chat(user, "Intercomms recharging. Please stand by.") - return - var/input = stripped_input(user, "Please choose a message to announce to the station crew.", "What?") - if(!input || !user.canUseTopic(src)) - return - SScommunications.make_announcement(user, is_silicon, input) - deadchat_broadcast("[user.real_name] made an priority announcement from [get_area_name(usr, TRUE)].", user) - -/obj/machinery/computer/communications/proc/post_status(command, data1, data2) - - var/datum/radio_frequency/frequency = SSradio.return_frequency(FREQ_STATUS_DISPLAYS) - - if(!frequency) - return - - var/datum/signal/status_signal = new(list("command" = command)) - switch(command) - if("message") - status_signal.data["msg1"] = data1 - status_signal.data["msg2"] = data2 - if("alert") - status_signal.data["picture_state"] = data1 - - frequency.post_signal(src, status_signal) - - -/obj/machinery/computer/communications/Destroy() - GLOB.shuttle_caller_list -= src - SSshuttle.autoEvac() - return ..() - -/obj/machinery/computer/communications/proc/overrideCooldown() - var/obj/item/circuitboard/computer/communications/CM = circuit - CM.lastTimeUsed = 0 - -/obj/machinery/computer/communications/proc/add_message(datum/comm_message/new_message) - messages += new_message - -/datum/comm_message - var/title - var/content - var/list/possible_answers = list() - var/answered - var/datum/callback/answer_callback - -/datum/comm_message/New(new_title,new_content,new_possible_answers) - ..() - if(new_title) - title = new_title - if(new_content) - content = new_content - if(new_possible_answers) - possible_answers = new_possible_answers +// The communications computer +/obj/machinery/computer/communications + name = "communications console" + desc = "A console used for high-priority announcements and emergencies." + icon_screen = "comm" + icon_keyboard = "tech_key" + req_access = list(ACCESS_HEADS) + circuit = /obj/item/circuitboard/computer/communications + var/auth_id = "Unknown" //Who is currently logged in? + var/list/datum/comm_message/messages = list() + var/datum/comm_message/currmsg + var/datum/comm_message/aicurrmsg + var/state = STATE_DEFAULT + var/aistate = STATE_DEFAULT + var/message_cooldown = 0 + var/ai_message_cooldown = 0 + var/tmp_alertlevel = 0 + var/const/STATE_DEFAULT = 1 + var/const/STATE_CALLSHUTTLE = 2 + var/const/STATE_CANCELSHUTTLE = 3 + var/const/STATE_MESSAGELIST = 4 + var/const/STATE_VIEWMESSAGE = 5 + var/const/STATE_DELMESSAGE = 6 + var/const/STATE_STATUSDISPLAY = 7 + var/const/STATE_ALERT_LEVEL = 8 + var/const/STATE_CONFIRM_LEVEL = 9 + var/const/STATE_TOGGLE_EMERGENCY = 10 + var/const/STATE_PURCHASE = 11 + + var/stat_msg1 + var/stat_msg2 + + light_color = LIGHT_COLOR_BLUE + +/obj/machinery/computer/communications/proc/checkCCcooldown() + var/obj/item/circuitboard/computer/communications/CM = circuit + if(CM.lastTimeUsed + 600 > world.time) + return FALSE + return TRUE + +/obj/machinery/computer/communications/Initialize() + . = ..() + GLOB.shuttle_caller_list += src + +/obj/machinery/computer/communications/Topic(href, href_list) + if(..()) + return + if(!usr.canUseTopic(src)) + return + if(!is_station_level(z) && !is_reserved_level(z)) //Can only use in transit and on SS13 + to_chat(usr, "Unable to establish a connection: \black You're too far away from the station!") + return + usr.set_machine(src) + + + if(!href_list["operation"]) + return + var/obj/item/circuitboard/computer/communications/CM = circuit + switch(href_list["operation"]) + // main interface + if("main") + state = STATE_DEFAULT + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + if("login") + var/mob/M = usr + + var/obj/item/card/id/I = M.get_idcard(TRUE) + + if(I && istype(I)) + if(check_access(I)) + authenticated = 1 + auth_id = "[I.registered_name] ([I.assignment])" + if((ACCESS_CAPTAIN in I.access)) + authenticated = 2 + playsound(src, 'sound/machines/terminal_on.ogg', 50, 0) + if(obj_flags & EMAGGED) + authenticated = 2 + auth_id = "Unknown" + to_chat(M, "[src] lets out a quiet alarm as its login is overridden.") + playsound(src, 'sound/machines/terminal_on.ogg', 50, 0) + playsound(src, 'sound/machines/terminal_alert.ogg', 25, 0) + if(prob(25)) + for(var/mob/living/silicon/ai/AI in active_ais()) + SEND_SOUND(AI, sound('sound/machines/terminal_alert.ogg', volume = 10)) //Very quiet for balance reasons + if("logout") + authenticated = 0 + playsound(src, 'sound/machines/terminal_off.ogg', 50, 0) + + if("swipeidseclevel") + var/mob/M = usr + var/obj/item/card/id/I = M.get_active_held_item() + if (istype(I, /obj/item/pda)) + var/obj/item/pda/pda = I + I = pda.id + if (I && istype(I)) + if(ACCESS_CAPTAIN in I.access) + var/old_level = GLOB.security_level + if(!tmp_alertlevel) + tmp_alertlevel = SEC_LEVEL_GREEN + if(tmp_alertlevel < SEC_LEVEL_GREEN) + tmp_alertlevel = SEC_LEVEL_GREEN + if(tmp_alertlevel == SEC_LEVEL_BLUE) + tmp_alertlevel = SEC_LEVEL_BLUE + if(tmp_alertlevel > SEC_LEVEL_AMBER) + tmp_alertlevel = SEC_LEVEL_AMBER //Cannot engage delta with this + set_security_level(tmp_alertlevel) + if(GLOB.security_level != old_level) + to_chat(usr, "Authorization confirmed. Modifying security level.") + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + //Only notify people if an actual change happened + var/security_level = get_security_level() + log_game("[key_name(usr)] has changed the security level to [security_level] with [src] at [AREACOORD(usr)].") + message_admins("[ADMIN_LOOKUPFLW(usr)] has changed the security level to [security_level] with [src] at [AREACOORD(usr)].") + deadchat_broadcast("[usr.real_name] has changed the security level to [security_level] with [src] at [get_area_name(usr, TRUE)].", usr) + tmp_alertlevel = 0 + else + to_chat(usr, "You are not authorized to do this!") + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + tmp_alertlevel = 0 + state = STATE_DEFAULT + else + to_chat(usr, "You need to swipe your ID!") + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + + if("announce") + if(authenticated==2) + playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) + make_announcement(usr) + + if("crossserver") + if(authenticated==2) + if(!checkCCcooldown()) + to_chat(usr, "Arrays recycling. Please stand by.") + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + var/input = stripped_multiline_input(usr, "Please choose a message to transmit to allied stations. Please be aware that this process is very expensive, and abuse will lead to... termination.", "Send a message to an allied station.", "") + if(!input || !(usr in view(1,src)) || !checkCCcooldown()) + return + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + send2otherserver("[station_name()]", input,"Comms_Console") + minor_announce(input, title = "Outgoing message to allied station") + usr.log_talk(input, LOG_SAY, tag="message to the other server") + message_admins("[ADMIN_LOOKUPFLW(usr)] has sent a message to the other server.") + deadchat_broadcast("[usr.real_name] has sent an outgoing message to the other station(s).", usr) + CM.lastTimeUsed = world.time + + if("purchase_menu") + state = STATE_PURCHASE + + if("buyshuttle") + if(authenticated==2) + var/list/shuttles = flatten_list(SSmapping.shuttle_templates) + var/datum/map_template/shuttle/S = locate(href_list["chosen_shuttle"]) in shuttles + if(S && istype(S)) + if(SSshuttle.emergency.mode != SHUTTLE_RECALL && SSshuttle.emergency.mode != SHUTTLE_IDLE) + to_chat(usr, "It's a bit late to buy a new shuttle, don't you think?") + return + if(SSshuttle.shuttle_purchased) + to_chat(usr, "A replacement shuttle has already been purchased.") + else if(!S.prerequisites_met()) + to_chat(usr, "You have not met the requirements for purchasing this shuttle.") + else + if(SSshuttle.points >= S.credit_cost) + var/obj/machinery/shuttle_manipulator/M = locate() in GLOB.machines + if(M) + SSshuttle.shuttle_purchased = TRUE + SSshuttle.points -= S.credit_cost + minor_announce("[usr.real_name] has purchased [S.name] for [S.credit_cost] credits." , "Shuttle Purchase") + message_admins("[ADMIN_LOOKUPFLW(usr)] purchased [S.name].") + SSblackbox.record_feedback("text", "shuttle_purchase", 1, "[S.name]") + M.unload_preview() + M.load_template(S) + M.existing_shuttle = SSshuttle.emergency + M.action_load(S) + message_admins("[S.name] loaded, purchased by [usr]") + else + to_chat(usr, "Something went wrong! The shuttle exchange system seems to be down.") + else + to_chat(usr, "Not enough credits.") + + if("callshuttle") + state = STATE_DEFAULT + if(authenticated) + state = STATE_CALLSHUTTLE + if("callshuttle2") + if(authenticated) + SSshuttle.requestEvac(usr, href_list["call"]) + if(SSshuttle.emergency.timer) + post_status("shuttle") + state = STATE_DEFAULT + if("cancelshuttle") + state = STATE_DEFAULT + if(authenticated) + state = STATE_CANCELSHUTTLE + if("cancelshuttle2") + if(authenticated) + if((world.realtime - SSshuttle.realtimeofstart) > SSshuttle.auto_call) //Citadel Edit Removing auto_call caused recall. + say("Warning: Emergency shuttle recalls have been blocked by Central Command due to ongoing crew transfer procedures.") + else + SSshuttle.cancelEvac(usr) + state = STATE_DEFAULT + if("messagelist") + currmsg = 0 + state = STATE_MESSAGELIST + if("viewmessage") + state = STATE_VIEWMESSAGE + if (!currmsg) + if(href_list["message-num"]) + var/msgnum = text2num(href_list["message-num"]) + currmsg = messages[msgnum] + else + state = STATE_MESSAGELIST + if("delmessage") + state = currmsg ? STATE_DELMESSAGE : STATE_MESSAGELIST + if("delmessage2") + if(authenticated) + if(currmsg) + if(aicurrmsg == currmsg) + aicurrmsg = null + messages -= currmsg + currmsg = null + state = STATE_MESSAGELIST + else + state = STATE_VIEWMESSAGE + if("respond") + var/answer = text2num(href_list["answer"]) + if(!currmsg || !answer || currmsg.possible_answers.len < answer) + state = STATE_MESSAGELIST + else + if(!currmsg.answered) + currmsg.answered = answer + log_game("[key_name(usr)] answered [currmsg.title] comm message. Answer : [currmsg.answered]") + if(currmsg) + currmsg.answer_callback.InvokeAsync() + state = STATE_VIEWMESSAGE + updateDialog() + if("status") + state = STATE_STATUSDISPLAY + if("securitylevel") + tmp_alertlevel = text2num( href_list["newalertlevel"] ) + if(!tmp_alertlevel) + tmp_alertlevel = 0 + state = STATE_CONFIRM_LEVEL + if("changeseclevel") + state = STATE_ALERT_LEVEL + + if("emergencyaccess") + state = STATE_TOGGLE_EMERGENCY + if("enableemergency") + make_maint_all_access() + log_game("[key_name(usr)] enabled emergency maintenance access.") + message_admins("[ADMIN_LOOKUPFLW(usr)] enabled emergency maintenance access.") + deadchat_broadcast("[usr.real_name] enabled emergency maintenance access at [get_area_name(usr, TRUE)].", usr) + state = STATE_DEFAULT + if("disableemergency") + revoke_maint_all_access() + log_game("[key_name(usr)] disabled emergency maintenance access.") + message_admins("[ADMIN_LOOKUPFLW(usr)] disabled emergency maintenance access.") + deadchat_broadcast("[usr.real_name] disabled emergency maintenance access at [get_area_name(usr, TRUE)].", usr) + state = STATE_DEFAULT + + // Status display stuff + if("setstat") + playsound(src, "terminal_type", 50, 0) + switch(href_list["statdisp"]) + if("message") + post_status("message", stat_msg1, stat_msg2) + if("alert") + post_status("alert", href_list["alert"]) + else + post_status(href_list["statdisp"]) + + if("setmsg1") + stat_msg1 = reject_bad_text(input("Line 1", "Enter Message Text", stat_msg1) as text|null, 40) + updateDialog() + if("setmsg2") + stat_msg2 = reject_bad_text(input("Line 2", "Enter Message Text", stat_msg2) as text|null, 40) + updateDialog() + + // OMG CENTCOM LETTERHEAD + if("MessageCentCom") + if(authenticated) + if(!checkCCcooldown()) + to_chat(usr, "Arrays recycling. Please stand by.") + return + var/input = stripped_input(usr, "Please choose a message to transmit to CentCom via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "Send a message to CentCom.", "") + if(!input || !(usr in view(1,src)) || !checkCCcooldown()) + return + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + CentCom_announce(input, usr) + to_chat(usr, "Message transmitted to Central Command.") + usr.log_talk(input, LOG_SAY, tag="CentCom announcement") + deadchat_broadcast("[usr.real_name] has messaged CentCom, \"[input]\" at [get_area_name(usr, TRUE)].", usr) + CM.lastTimeUsed = world.time + + // OMG SYNDICATE ...LETTERHEAD + if("MessageSyndicate") + if((authenticated==2) && (obj_flags & EMAGGED)) + if(!checkCCcooldown()) + to_chat(usr, "Arrays recycling. Please stand by.") + playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0) + return + var/input = stripped_input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING COORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "Send a message to /??????/.", "") + if(!input || !(usr in view(1,src)) || !checkCCcooldown()) + return + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + Syndicate_announce(input, usr) + to_chat(usr, "SYSERR @l(19833)of(transmit.dm): !@$ MESSAGE TRANSMITTED TO SYNDICATE COMMAND.") + usr.log_talk(input, LOG_SAY, tag="Syndicate announcement") + deadchat_broadcast("[usr.real_name] has messaged the Syndicate, \"[input]\" at [get_area_name(usr, TRUE)].", usr) + CM.lastTimeUsed = world.time + + if("RestoreBackup") + to_chat(usr, "Backup routing data restored!") + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + obj_flags &= ~EMAGGED + updateDialog() + + if("nukerequest") //When there's no other way + if(authenticated==2) + if(!checkCCcooldown()) + to_chat(usr, "Arrays recycling. Please stand by.") + return + var/input = stripped_input(usr, "Please enter the reason for requesting the nuclear self-destruct codes. Misuse of the nuclear request system will not be tolerated under any circumstances. Transmission does not guarantee a response.", "Self Destruct Code Request.","") + if(!input || !(usr in view(1,src)) || !checkCCcooldown()) + return + Nuke_request(input, usr) + to_chat(usr, "Request sent.") + usr.log_message("has requested the nuclear codes from CentCom", LOG_SAY) + priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested","commandreport") + CM.lastTimeUsed = world.time + + + // AI interface + if("ai-main") + aicurrmsg = null + aistate = STATE_DEFAULT + if("ai-callshuttle") + aistate = STATE_CALLSHUTTLE + if("ai-callshuttle2") + SSshuttle.requestEvac(usr, href_list["call"]) + aistate = STATE_DEFAULT + if("ai-messagelist") + aicurrmsg = null + aistate = STATE_MESSAGELIST + if("ai-viewmessage") + aistate = STATE_VIEWMESSAGE + if (!aicurrmsg) + if(href_list["message-num"]) + var/msgnum = text2num(href_list["message-num"]) + aicurrmsg = messages[msgnum] + else + aistate = STATE_MESSAGELIST + if("ai-delmessage") + aistate = aicurrmsg ? STATE_DELMESSAGE : STATE_MESSAGELIST + if("ai-delmessage2") + if(aicurrmsg) + if(currmsg == aicurrmsg) + currmsg = null + messages -= aicurrmsg + aicurrmsg = null + aistate = STATE_MESSAGELIST + if("ai-respond") + var/answer = text2num(href_list["answer"]) + if(!aicurrmsg || !answer || aicurrmsg.possible_answers.len < answer) + aistate = STATE_MESSAGELIST + else + if(!aicurrmsg.answered) + aicurrmsg.answered = answer + log_game("[key_name(usr)] answered [aicurrmsg.title] comm message. Answer : [aicurrmsg.answered]") + if(aicurrmsg.answer_callback) + aicurrmsg.answer_callback.InvokeAsync() + aistate = STATE_VIEWMESSAGE + if("ai-status") + aistate = STATE_STATUSDISPLAY + if("ai-announce") + make_announcement(usr, 1) + if("ai-securitylevel") + tmp_alertlevel = text2num( href_list["newalertlevel"] ) + if(!tmp_alertlevel) + tmp_alertlevel = 0 + var/old_level = GLOB.security_level + if(!tmp_alertlevel) + tmp_alertlevel = SEC_LEVEL_GREEN + if(tmp_alertlevel < SEC_LEVEL_GREEN) + tmp_alertlevel = SEC_LEVEL_GREEN + if(tmp_alertlevel == SEC_LEVEL_BLUE) + tmp_alertlevel = SEC_LEVEL_BLUE + if(tmp_alertlevel > SEC_LEVEL_AMBER) + tmp_alertlevel = SEC_LEVEL_AMBER //Cannot engage delta with this + set_security_level(tmp_alertlevel) + if(GLOB.security_level != old_level) + //Only notify people if an actual change happened + var/security_level = get_security_level() + log_game("[key_name(usr)] has changed the security level to [security_level] from [src] at [AREACOORD(usr)].") + message_admins("[ADMIN_LOOKUPFLW(usr)] has changed the security level to [security_level] from [src] at [AREACOORD(usr)].") + deadchat_broadcast("[usr.real_name] has changed the security level to [security_level] from [src] at [get_area_name(usr, TRUE)].", usr) + tmp_alertlevel = 0 + aistate = STATE_DEFAULT + if("ai-changeseclevel") + aistate = STATE_ALERT_LEVEL + if("ai-emergencyaccess") + aistate = STATE_TOGGLE_EMERGENCY + if("ai-enableemergency") + make_maint_all_access() + log_game("[key_name(usr)] enabled emergency maintenance access.") + message_admins("[ADMIN_LOOKUPFLW(usr)] enabled emergency maintenance access.") + deadchat_broadcast("[usr.real_name] enabled emergency maintenance access.", usr) + aistate = STATE_DEFAULT + if("ai-disableemergency") + revoke_maint_all_access() + log_game("[key_name(usr)] disabled emergency maintenance access.") + message_admins("[ADMIN_LOOKUPFLW(usr)] disabled emergency maintenance access.") + deadchat_broadcast("[usr.real_name] disabled emergency maintenance access.", usr) + aistate = STATE_DEFAULT + + updateUsrDialog() + +/obj/machinery/computer/communications/attackby(obj/I, mob/user, params) + if(istype(I, /obj/item/card/id)) + attack_hand(user) + else + return ..() + +/obj/machinery/computer/communications/emag_act(mob/user) + . = ..() + if(obj_flags & EMAGGED) + return + obj_flags |= EMAGGED + SSshuttle.shuttle_purchase_requirements_met |= "emagged" + if(authenticated == 1) + authenticated = 2 + to_chat(user, "You scramble the communication routing circuits!") + playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0) + return TRUE + +/obj/machinery/computer/communications/ui_interact(mob/user) + . = ..() + if (z > 6) + to_chat(user, "Unable to establish a connection: \black You're too far away from the station!") + return + + var/dat = "" + if(SSshuttle.emergency.mode == SHUTTLE_CALL) + var/timeleft = SSshuttle.emergency.timeLeft() + dat += "Emergency shuttle\n
      \nETA: [timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]" + + + var/datum/browser/popup = new(user, "communications", "Communications Console", 400, 500) + popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) + + if(issilicon(user)) + var/dat2 = interact_ai(user) // give the AI a different interact proc to limit its access + if(dat2) + dat += dat2 + popup.set_content(dat) + popup.open() + return + + switch(state) + if(STATE_DEFAULT) + if (authenticated) + if(SSshuttle.emergencyCallAmount) + if(SSshuttle.emergencyLastCallLoc) + dat += "Most recent shuttle call/recall traced to: [format_text(SSshuttle.emergencyLastCallLoc.name)]
      " + else + dat += "Unable to trace most recent shuttle call/recall signal.
      " + dat += "Logged in as: [auth_id]" + dat += "
      " + dat += "
      \[ Log Out \]
      " + dat += "
      General Functions" + dat += "
      \[ Message List \]" + switch(SSshuttle.emergency.mode) + if(SHUTTLE_IDLE, SHUTTLE_RECALL) + dat += "
      \[ Call Emergency Shuttle \]" + else + dat += "
      \[ Cancel Shuttle Call \]" + + dat += "
      \[ Set Status Display \]" + if (authenticated==2) + dat += "

      Captain Functions" + dat += "
      \[ Make a Captain's Announcement \]" + var/cross_servers_count = length(CONFIG_GET(keyed_list/cross_server)) + if(cross_servers_count) + dat += "
      \[ Send a message to [cross_servers_count == 1 ? "an " : ""]allied station[cross_servers_count > 1 ? "s" : ""] \]" + if(SSmapping.config.allow_custom_shuttles) + dat += "
      \[ Purchase Shuttle \]" + dat += "
      \[ Change Alert Level \]" + dat += "
      \[ Emergency Maintenance Access \]" + dat += "
      \[ Request Nuclear Authentication Codes \]" + if(!(obj_flags & EMAGGED)) + dat += "
      \[ Send Message to CentCom \]" + else + dat += "
      \[ Send Message to \[UNKNOWN\] \]" + dat += "
      \[ Restore Backup Routing Data \]" + else + dat += "
      \[ Log In \]" + if(STATE_CALLSHUTTLE) + dat += get_call_shuttle_form() + playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) + if(STATE_CANCELSHUTTLE) + dat += get_cancel_shuttle_form() + playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) + if(STATE_MESSAGELIST) + dat += "Messages:" + for(var/i in 1 to messages.len) + var/datum/comm_message/M = messages[i] + dat += "
      [M.title]" + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + if(STATE_VIEWMESSAGE) + if (currmsg) + dat += "[currmsg.title]

      [currmsg.content]" + if(!currmsg.answered && currmsg.possible_answers.len) + for(var/i in 1 to currmsg.possible_answers.len) + var/answer = currmsg.possible_answers[i] + dat += "
      \[ Answer : [answer] \]" + else if(currmsg.answered) + var/answered = currmsg.possible_answers[currmsg.answered] + dat += "
      Archived Answer : [answered]" + dat += "

      \[ Delete \]" + else + aistate = STATE_MESSAGELIST + attack_hand(user) + return + if(STATE_DELMESSAGE) + if (currmsg) + dat += "Are you sure you want to delete this message? \[ OK | Cancel \]" + else + state = STATE_MESSAGELIST + attack_hand(user) + return + if(STATE_STATUSDISPLAY) + dat += "Set Status Displays
      " + dat += "\[ Clear \]
      " + dat += "\[ Shuttle ETA \]
      " + dat += "\[ Message \]" + dat += "
      " + dat += "\[ Alert: None |" + dat += " Red Alert |" + dat += " Lockdown |" + dat += " Biohazard \]

      " + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) + if(STATE_ALERT_LEVEL) + dat += "Current alert level: [get_security_level()]
      " + if(GLOB.security_level == SEC_LEVEL_DELTA) + dat += "The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate." + else + dat += "Amber
      " + dat += "Blue
      " + dat += "Green" + if(STATE_CONFIRM_LEVEL) + dat += "Current alert level: [get_security_level()]
      " + dat += "Confirm the change to: [num2seclevel(tmp_alertlevel)]
      " + dat += "Swipe ID to confirm change.
      " + if(STATE_TOGGLE_EMERGENCY) + playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) + if(GLOB.emergency_access == 1) + dat += "Emergency Maintenance Access is currently ENABLED" + dat += "
      Restore maintenance access restrictions?
      \[ OK | Cancel \]" + else + dat += "Emergency Maintenance Access is currently DISABLED" + dat += "
      Lift access restrictions on maintenance and external airlocks?
      \[ OK | Cancel \]" + + if(STATE_PURCHASE) + dat += "Budget: [SSshuttle.points] Credits.
      " + dat += "
      " + dat += "Caution: Purchasing dangerous shuttles may lead to mutiny and/or death.
      " + dat += "
      " + for(var/shuttle_id in SSmapping.shuttle_templates) + var/datum/map_template/shuttle/S = SSmapping.shuttle_templates[shuttle_id] + if(S.can_be_bought && S.credit_cost < INFINITY) + dat += "[S.name] | [S.credit_cost] Credits
      " + dat += "[S.description]
      " + if(S.prerequisites) + dat += "Prerequisites: [S.prerequisites]
      " + dat += "(Purchase)

      " + + dat += "

      \[ [(state != STATE_DEFAULT) ? "Main Menu | " : ""]Close \]" + + popup.set_content(dat) + popup.open() + +/obj/machinery/computer/communications/proc/get_javascript_header(form_id) + var/dat = {""} + return dat + +/obj/machinery/computer/communications/proc/get_call_shuttle_form(ai_interface = 0) + var/form_id = "callshuttle" + var/dat = get_javascript_header(form_id) + dat += "" + dat += "" + dat += "" + dat += "Nature of emergency:
      " + dat += "
      Are you sure you want to call the shuttle? \[ Call \]" + return dat + +/obj/machinery/computer/communications/proc/get_cancel_shuttle_form() + var/form_id = "cancelshuttle" + var/dat = get_javascript_header(form_id) + dat += "" + dat += "" + dat += "" + + dat += "
      Are you sure you want to cancel the shuttle? \[ Cancel \]" + return dat + +/obj/machinery/computer/communications/proc/interact_ai(mob/living/silicon/ai/user) + var/dat = "" + switch(aistate) + if(STATE_DEFAULT) + if(SSshuttle.emergencyCallAmount) + if(SSshuttle.emergencyLastCallLoc) + dat += "Latest emergency signal trace attempt successful.
      Last signal origin: [format_text(SSshuttle.emergencyLastCallLoc.name)].
      " + else + dat += "Latest emergency signal trace attempt failed.
      " + if(authenticated) + dat += "Current login: [auth_id]" + else + dat += "Current login: None" + dat += "

      General Functions" + dat += "
      \[ Message List \]" + if(SSshuttle.emergency.mode == SHUTTLE_IDLE) + dat += "
      \[ Call Emergency Shuttle \]" + dat += "
      \[ Set Status Display \]" + dat += "

      Special Functions" + dat += "
      \[ Make an Announcement \]" + dat += "
      \[ Change Alert Level \]" + dat += "
      \[ Emergency Maintenance Access \]" + if(STATE_CALLSHUTTLE) + dat += get_call_shuttle_form(1) + if(STATE_MESSAGELIST) + dat += "Messages:" + for(var/i in 1 to messages.len) + var/datum/comm_message/M = messages[i] + dat += "
      [M.title]" + if(STATE_VIEWMESSAGE) + if (aicurrmsg) + dat += "[aicurrmsg.title]

      [aicurrmsg.content]" + if(!aicurrmsg.answered && aicurrmsg.possible_answers.len) + for(var/i in 1 to aicurrmsg.possible_answers.len) + var/answer = aicurrmsg.possible_answers[i] + dat += "
      \[ Answer : [answer] \]" + else if(aicurrmsg.answered) + var/answered = aicurrmsg.possible_answers[aicurrmsg.answered] + dat += "
      Archived Answer : [answered]" + dat += "

      \[ Delete \]" + else + aistate = STATE_MESSAGELIST + attack_hand(user) + return null + if(STATE_DELMESSAGE) + if(aicurrmsg) + dat += "Are you sure you want to delete this message? \[ OK | Cancel \]" + else + aistate = STATE_MESSAGELIST + attack_hand(user) + return + + if(STATE_STATUSDISPLAY) + dat += "Set Status Displays
      " + dat += "\[ Clear \]
      " + dat += "\[ Shuttle ETA \]
      " + dat += "\[ Message \]" + dat += "
      " + dat += "\[ Alert: None |" + dat += " Red Alert |" + dat += " Lockdown |" + dat += " Biohazard \]

      " + + if(STATE_ALERT_LEVEL) + dat += "Current alert level: [get_security_level()]
      " + if(GLOB.security_level == SEC_LEVEL_DELTA) + dat += "The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate." + else + dat += "Amber
      " + dat += "Blue
      " + dat += "Green" + + if(STATE_TOGGLE_EMERGENCY) + if(GLOB.emergency_access == 1) + dat += "Emergency Maintenance Access is currently ENABLED" + dat += "
      Restore maintenance access restrictions?
      \[ OK | Cancel \]" + else + dat += "Emergency Maintenance Access is currently DISABLED" + dat += "
      Lift access restrictions on maintenance and external airlocks?
      \[ OK | Cancel \]" + + dat += "

      \[ [(aistate != STATE_DEFAULT) ? "Main Menu | " : ""]Close \]" + return dat + +/obj/machinery/computer/communications/proc/make_announcement(mob/living/user, is_silicon) + if(!SScommunications.can_announce(user, is_silicon)) + to_chat(user, "Intercomms recharging. Please stand by.") + return + var/input = stripped_input(user, "Please choose a message to announce to the station crew.", "What?") + if(!input || !user.canUseTopic(src)) + return + SScommunications.make_announcement(user, is_silicon, input) + deadchat_broadcast("[user.real_name] made an priority announcement from [get_area_name(usr, TRUE)].", user) + +/obj/machinery/computer/communications/proc/post_status(command, data1, data2) + + var/datum/radio_frequency/frequency = SSradio.return_frequency(FREQ_STATUS_DISPLAYS) + + if(!frequency) + return + + var/datum/signal/status_signal = new(list("command" = command)) + switch(command) + if("message") + status_signal.data["msg1"] = data1 + status_signal.data["msg2"] = data2 + if("alert") + status_signal.data["picture_state"] = data1 + + frequency.post_signal(src, status_signal) + + +/obj/machinery/computer/communications/Destroy() + GLOB.shuttle_caller_list -= src + SSshuttle.autoEvac() + return ..() + +/obj/machinery/computer/communications/proc/overrideCooldown() + var/obj/item/circuitboard/computer/communications/CM = circuit + CM.lastTimeUsed = 0 + +/obj/machinery/computer/communications/proc/add_message(datum/comm_message/new_message) + messages += new_message + +/datum/comm_message + var/title + var/content + var/list/possible_answers = list() + var/answered + var/datum/callback/answer_callback + +/datum/comm_message/New(new_title,new_content,new_possible_answers) + ..() + if(new_title) + title = new_title + if(new_content) + content = new_content + if(new_possible_answers) + possible_answers = new_possible_answers diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index c11f7d9edc..f6d0fcfc0d 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -1,210 +1,210 @@ -#define SENSORS_UPDATE_PERIOD 100 //How often the sensor data updates. - -/obj/machinery/computer/crew - name = "crew monitoring console" - desc = "Used to monitor active health sensors built into most of the crew's uniforms." - icon_screen = "crew" - icon_keyboard = "med_key" - use_power = IDLE_POWER_USE - idle_power_usage = 250 - active_power_usage = 500 - circuit = /obj/item/circuitboard/computer/crew - - light_color = LIGHT_COLOR_BLUE - -/obj/machinery/computer/crew/syndie - icon_keyboard = "syndie_key" - -/obj/machinery/computer/crew/interact(mob/user) - GLOB.crewmonitor.show(user,src) - -GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) - -/datum/crewmonitor - var/list/ui_sources = list() //List of user -> ui source - var/list/jobs - var/list/data_by_z = list() - var/list/last_update = list() - -/datum/crewmonitor/New() - . = ..() - - var/list/jobs = new/list() - jobs["Captain"] = 00 - jobs["Head of Security"] = 10 - jobs["Warden"] = 11 - jobs["Security Officer"] = 12 - jobs["Detective"] = 13 - jobs["Chief Medical Officer"] = 20 - jobs["Chemist"] = 21 - jobs["Geneticist"] = 22 - jobs["Virologist"] = 23 - jobs["Medical Doctor"] = 24 - jobs["Research Director"] = 30 - jobs["Scientist"] = 31 - jobs["Roboticist"] = 32 - jobs["Chief Engineer"] = 40 - jobs["Station Engineer"] = 41 - jobs["Atmospheric Technician"] = 42 - jobs["Quartermaster"] = 50 - jobs["Shaft Miner"] = 51 - jobs["Cargo Technician"] = 52 - jobs["Head of Personnel"] = 60 - jobs["Bartender"] = 61 - jobs["Cook"] = 62 - jobs["Botanist"] = 63 - jobs["Curator"] = 64 - jobs["Chaplain"] = 65 - jobs["Clown"] = 66 - jobs["Mime"] = 67 - jobs["Janitor"] = 68 - jobs["Lawyer"] = 69 - jobs["Admiral"] = 200 - jobs["CentCom Commander"] = 210 - jobs["Custodian"] = 211 - jobs["Medical Officer"] = 212 - jobs["Research Officer"] = 213 - jobs["Emergency Response Team Commander"] = 220 - jobs["Security Response Officer"] = 221 - jobs["Engineer Response Officer"] = 222 - jobs["Medical Response Officer"] = 223 - jobs["Assistant"] = 999 //Unknowns/custom jobs should appear after civilians, and before assistants - - src.jobs = jobs - -/datum/crewmonitor/Destroy() - return ..() - -/datum/crewmonitor/ui_interact(mob/user, ui_key = "crew", 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, "crew", "crew monitor", 800, 600 , master_ui, state) - ui.open() - -/datum/crewmonitor/proc/show(mob/M, source) - ui_sources[M] = source - ui_interact(M) - -/datum/crewmonitor/ui_host(mob/user) - return ui_sources[user] - -/datum/crewmonitor/ui_data(mob/user) - var/z = user.z - if(!z) - var/turf/T = get_turf(user) - z = T.z - var/list/zdata = update_data(z) - . = list() - .["sensors"] = zdata - .["link_allowed"] = isAI(user) - -/datum/crewmonitor/proc/update_data(z) - if(data_by_z["[z]"] && last_update["[z]"] && world.time <= last_update["[z]"] + SENSORS_UPDATE_PERIOD) - return data_by_z["[z]"] - - var/list/results_damaged = list() - var/list/results_undamaged = list() - - var/obj/item/clothing/under/U - var/obj/item/card/id/I - var/turf/pos - var/ijob - var/name - var/assignment - var/oxydam - var/toxdam - var/burndam - var/brutedam - var/totaldam - var/area - var/pos_x - var/pos_y - var/life_status - - for(var/mob/living/carbon/human/H in GLOB.carbon_list) - var/nanite_sensors = FALSE - if(H in SSnanites.nanite_monitored_mobs) - nanite_sensors = TRUE - // Check if their z-level is correct and if they are wearing a uniform. - // Accept H.z==0 as well in case the mob is inside an object. - if ((H.z == 0 || H.z == z) && istype(H.w_uniform, /obj/item/clothing/under) || nanite_sensors) - U = H.w_uniform - - // Are the suit sensors on? - if (nanite_sensors || ((U.has_sensor > 0) && U.sensor_mode)) - pos = H.z == 0 || (nanite_sensors || U.sensor_mode == SENSOR_COORDS) ? get_turf(H) : null - - // Special case: If the mob is inside an object confirm the z-level on turf level. - if (H.z == 0 && (!pos || pos.z != z)) - continue - - I = H.wear_id ? H.wear_id.GetID() : null - - if (I) - name = I.registered_name - assignment = I.assignment - ijob = jobs[I.assignment] - else - name = "Unknown" - assignment = "" - ijob = 80 - - if (nanite_sensors || U.sensor_mode >= SENSOR_LIVING) - life_status = (!H.stat ? TRUE : FALSE) - else - life_status = null - - if (nanite_sensors || U.sensor_mode >= SENSOR_VITALS) - oxydam = round(H.getOxyLoss(),1) - toxdam = round(H.getToxLoss(),1) - burndam = round(H.getFireLoss(),1) - brutedam = round(H.getBruteLoss(),1) - totaldam = oxydam + toxdam + burndam + brutedam - else - oxydam = null - toxdam = null - burndam = null - brutedam = null - totaldam = 0 - - if (nanite_sensors || U.sensor_mode >= SENSOR_COORDS) - if (!pos) - pos = get_turf(H) - area = get_area_name(H, TRUE) - pos_x = pos.x - pos_y = pos.y - else - area = null - pos_x = null - pos_y = null - - var/total_list = list("name" = name, "assignment" = assignment, "ijob" = ijob, "life_status" = life_status, "oxydam" = oxydam, "toxdam" = toxdam, "burndam" = burndam, "brutedam" = brutedam, "totaldam" = totaldam, "area" = area, "pos_x" = pos_x, "pos_y" = pos_y, "can_track" = H.can_track(null)) - - if(totaldam) - results_damaged[++results_damaged.len] = total_list - else - results_undamaged[++results_undamaged.len] = total_list - - var/list/returning = sortTim(results_damaged,/proc/damage_compare) + sortTim(results_undamaged,/proc/ijob_compare) - - data_by_z["[z]"] = returning - last_update["[z]"] = world.time - - return returning - -/proc/ijob_compare(list/a,list/b) - return a["ijob"] - b["ijob"] - -/proc/damage_compare(list/a,list/b) - return b["totaldam"] - a["totaldam"] - -/datum/crewmonitor/ui_act(action,params) - var/mob/living/silicon/ai/AI = usr - if(!istype(AI)) - return - switch (action) - if ("select_person") - AI.ai_camera_track(params["name"]) - +#define SENSORS_UPDATE_PERIOD 100 //How often the sensor data updates. + +/obj/machinery/computer/crew + name = "crew monitoring console" + desc = "Used to monitor active health sensors built into most of the crew's uniforms." + icon_screen = "crew" + icon_keyboard = "med_key" + use_power = IDLE_POWER_USE + idle_power_usage = 250 + active_power_usage = 500 + circuit = /obj/item/circuitboard/computer/crew + + light_color = LIGHT_COLOR_BLUE + +/obj/machinery/computer/crew/syndie + icon_keyboard = "syndie_key" + +/obj/machinery/computer/crew/interact(mob/user) + GLOB.crewmonitor.show(user,src) + +GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) + +/datum/crewmonitor + var/list/ui_sources = list() //List of user -> ui source + var/list/jobs + var/list/data_by_z = list() + var/list/last_update = list() + +/datum/crewmonitor/New() + . = ..() + + var/list/jobs = new/list() + jobs["Captain"] = 00 + jobs["Head of Security"] = 10 + jobs["Warden"] = 11 + jobs["Security Officer"] = 12 + jobs["Detective"] = 13 + jobs["Chief Medical Officer"] = 20 + jobs["Chemist"] = 21 + jobs["Geneticist"] = 22 + jobs["Virologist"] = 23 + jobs["Medical Doctor"] = 24 + jobs["Research Director"] = 30 + jobs["Scientist"] = 31 + jobs["Roboticist"] = 32 + jobs["Chief Engineer"] = 40 + jobs["Station Engineer"] = 41 + jobs["Atmospheric Technician"] = 42 + jobs["Quartermaster"] = 50 + jobs["Shaft Miner"] = 51 + jobs["Cargo Technician"] = 52 + jobs["Head of Personnel"] = 60 + jobs["Bartender"] = 61 + jobs["Cook"] = 62 + jobs["Botanist"] = 63 + jobs["Curator"] = 64 + jobs["Chaplain"] = 65 + jobs["Clown"] = 66 + jobs["Mime"] = 67 + jobs["Janitor"] = 68 + jobs["Lawyer"] = 69 + jobs["Admiral"] = 200 + jobs["CentCom Commander"] = 210 + jobs["Custodian"] = 211 + jobs["Medical Officer"] = 212 + jobs["Research Officer"] = 213 + jobs["Emergency Response Team Commander"] = 220 + jobs["Security Response Officer"] = 221 + jobs["Engineer Response Officer"] = 222 + jobs["Medical Response Officer"] = 223 + jobs["Assistant"] = 999 //Unknowns/custom jobs should appear after civilians, and before assistants + + src.jobs = jobs + +/datum/crewmonitor/Destroy() + return ..() + +/datum/crewmonitor/ui_interact(mob/user, ui_key = "crew", 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, "crew", "crew monitor", 800, 600 , master_ui, state) + ui.open() + +/datum/crewmonitor/proc/show(mob/M, source) + ui_sources[M] = source + ui_interact(M) + +/datum/crewmonitor/ui_host(mob/user) + return ui_sources[user] + +/datum/crewmonitor/ui_data(mob/user) + var/z = user.z + if(!z) + var/turf/T = get_turf(user) + z = T.z + var/list/zdata = update_data(z) + . = list() + .["sensors"] = zdata + .["link_allowed"] = isAI(user) + +/datum/crewmonitor/proc/update_data(z) + if(data_by_z["[z]"] && last_update["[z]"] && world.time <= last_update["[z]"] + SENSORS_UPDATE_PERIOD) + return data_by_z["[z]"] + + var/list/results_damaged = list() + var/list/results_undamaged = list() + + var/obj/item/clothing/under/U + var/obj/item/card/id/I + var/turf/pos + var/ijob + var/name + var/assignment + var/oxydam + var/toxdam + var/burndam + var/brutedam + var/totaldam + var/area + var/pos_x + var/pos_y + var/life_status + + for(var/mob/living/carbon/human/H in GLOB.carbon_list) + var/nanite_sensors = FALSE + if(H in SSnanites.nanite_monitored_mobs) + nanite_sensors = TRUE + // Check if their z-level is correct and if they are wearing a uniform. + // Accept H.z==0 as well in case the mob is inside an object. + if ((H.z == 0 || H.z == z) && istype(H.w_uniform, /obj/item/clothing/under) || nanite_sensors) + U = H.w_uniform + + // Are the suit sensors on? + if (nanite_sensors || ((U.has_sensor > 0) && U.sensor_mode)) + pos = H.z == 0 || (nanite_sensors || U.sensor_mode == SENSOR_COORDS) ? get_turf(H) : null + + // Special case: If the mob is inside an object confirm the z-level on turf level. + if (H.z == 0 && (!pos || pos.z != z)) + continue + + I = H.wear_id ? H.wear_id.GetID() : null + + if (I) + name = I.registered_name + assignment = I.assignment + ijob = jobs[I.assignment] + else + name = "Unknown" + assignment = "" + ijob = 80 + + if (nanite_sensors || U.sensor_mode >= SENSOR_LIVING) + life_status = (!H.stat ? TRUE : FALSE) + else + life_status = null + + if (nanite_sensors || U.sensor_mode >= SENSOR_VITALS) + oxydam = round(H.getOxyLoss(),1) + toxdam = round(H.getToxLoss(),1) + burndam = round(H.getFireLoss(),1) + brutedam = round(H.getBruteLoss(),1) + totaldam = oxydam + toxdam + burndam + brutedam + else + oxydam = null + toxdam = null + burndam = null + brutedam = null + totaldam = 0 + + if (nanite_sensors || U.sensor_mode >= SENSOR_COORDS) + if (!pos) + pos = get_turf(H) + area = get_area_name(H, TRUE) + pos_x = pos.x + pos_y = pos.y + else + area = null + pos_x = null + pos_y = null + + var/total_list = list("name" = name, "assignment" = assignment, "ijob" = ijob, "life_status" = life_status, "oxydam" = oxydam, "toxdam" = toxdam, "burndam" = burndam, "brutedam" = brutedam, "totaldam" = totaldam, "area" = area, "pos_x" = pos_x, "pos_y" = pos_y, "can_track" = H.can_track(null)) + + if(totaldam) + results_damaged[++results_damaged.len] = total_list + else + results_undamaged[++results_undamaged.len] = total_list + + var/list/returning = sortTim(results_damaged,/proc/damage_compare) + sortTim(results_undamaged,/proc/ijob_compare) + + data_by_z["[z]"] = returning + last_update["[z]"] = world.time + + return returning + +/proc/ijob_compare(list/a,list/b) + return a["ijob"] - b["ijob"] + +/proc/damage_compare(list/a,list/b) + return b["totaldam"] - a["totaldam"] + +/datum/crewmonitor/ui_act(action,params) + var/mob/living/silicon/ai/AI = usr + if(!istype(AI)) + return + switch (action) + if ("select_person") + AI.ai_camera_track(params["name"]) + #undef SENSORS_UPDATE_PERIOD \ No newline at end of file diff --git a/code/game/machinery/computer/law.dm b/code/game/machinery/computer/law.dm index 25b82ac143..fa6d4327a4 100644 --- a/code/game/machinery/computer/law.dm +++ b/code/game/machinery/computer/law.dm @@ -1,72 +1,72 @@ - - -/obj/machinery/computer/upload - var/mob/living/silicon/current = null //The target of future law uploads - icon_screen = "command" - -/obj/machinery/computer/upload/attackby(obj/item/O, mob/user, params) - if(istype(O, /obj/item/aiModule)) - var/obj/item/aiModule/M = O - if(src.stat & (NOPOWER|BROKEN|MAINT)) - return - if(!current) - to_chat(user, "You haven't selected anything to transmit laws to!") - return - if(!can_upload_to(current)) - to_chat(user, "Upload failed! Check to make sure [current.name] is functioning properly.") - current = null - return - var/turf/currentloc = get_turf(current) - if(currentloc && user.z != currentloc.z) - to_chat(user, "Upload failed! Unable to establish a connection to [current.name]. You're too far away!") - current = null - return - M.install(current.laws, user) - else - return ..() - -/obj/machinery/computer/upload/proc/can_upload_to(mob/living/silicon/S) - if(S.stat == DEAD) - return 0 - return 1 - -/obj/machinery/computer/upload/ai - name = "\improper AI upload console" - desc = "Used to upload laws to the AI." - circuit = /obj/item/circuitboard/computer/aiupload - -/obj/machinery/computer/upload/ai/interact(mob/user) - src.current = select_active_ai(user) - - if (!src.current) - to_chat(user, "No active AIs detected!") - else - to_chat(user, "[src.current.name] selected for law changes.") - -/obj/machinery/computer/upload/ai/can_upload_to(mob/living/silicon/ai/A) - if(!A || !isAI(A)) - return 0 - if(A.control_disabled) - return 0 - return ..() - - -/obj/machinery/computer/upload/borg - name = "cyborg upload console" - desc = "Used to upload laws to Cyborgs." - circuit = /obj/item/circuitboard/computer/borgupload - -/obj/machinery/computer/upload/borg/interact(mob/user) - src.current = select_active_free_borg(user) - - if(!src.current) - to_chat(user, "No active unslaved cyborgs detected!") - else - to_chat(user, "[src.current.name] selected for law changes.") - -/obj/machinery/computer/upload/borg/can_upload_to(mob/living/silicon/robot/B) - if(!B || !iscyborg(B)) - return 0 - if(B.scrambledcodes || B.emagged) - return 0 + + +/obj/machinery/computer/upload + var/mob/living/silicon/current = null //The target of future law uploads + icon_screen = "command" + +/obj/machinery/computer/upload/attackby(obj/item/O, mob/user, params) + if(istype(O, /obj/item/aiModule)) + var/obj/item/aiModule/M = O + if(src.stat & (NOPOWER|BROKEN|MAINT)) + return + if(!current) + to_chat(user, "You haven't selected anything to transmit laws to!") + return + if(!can_upload_to(current)) + to_chat(user, "Upload failed! Check to make sure [current.name] is functioning properly.") + current = null + return + var/turf/currentloc = get_turf(current) + if(currentloc && user.z != currentloc.z) + to_chat(user, "Upload failed! Unable to establish a connection to [current.name]. You're too far away!") + current = null + return + M.install(current.laws, user) + else + return ..() + +/obj/machinery/computer/upload/proc/can_upload_to(mob/living/silicon/S) + if(S.stat == DEAD) + return 0 + return 1 + +/obj/machinery/computer/upload/ai + name = "\improper AI upload console" + desc = "Used to upload laws to the AI." + circuit = /obj/item/circuitboard/computer/aiupload + +/obj/machinery/computer/upload/ai/interact(mob/user) + src.current = select_active_ai(user) + + if (!src.current) + to_chat(user, "No active AIs detected!") + else + to_chat(user, "[src.current.name] selected for law changes.") + +/obj/machinery/computer/upload/ai/can_upload_to(mob/living/silicon/ai/A) + if(!A || !isAI(A)) + return 0 + if(A.control_disabled) + return 0 + return ..() + + +/obj/machinery/computer/upload/borg + name = "cyborg upload console" + desc = "Used to upload laws to Cyborgs." + circuit = /obj/item/circuitboard/computer/borgupload + +/obj/machinery/computer/upload/borg/interact(mob/user) + src.current = select_active_free_borg(user) + + if(!src.current) + to_chat(user, "No active unslaved cyborgs detected!") + else + to_chat(user, "[src.current.name] selected for law changes.") + +/obj/machinery/computer/upload/borg/can_upload_to(mob/living/silicon/robot/B) + if(!B || !iscyborg(B)) + return 0 + if(B.scrambledcodes || B.emagged) + return 0 return ..() \ No newline at end of file diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 33de8bfce2..29055e87c3 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -1,585 +1,585 @@ - - -/obj/machinery/computer/med_data//TODO:SANITY - name = "medical records console" - desc = "This can be used to check medical records." - icon_screen = "medcomp" - icon_keyboard = "med_key" - req_one_access = list(ACCESS_MEDICAL, ACCESS_FORENSICS_LOCKERS) - circuit = /obj/item/circuitboard/computer/med_data - var/rank = null - var/screen = null - var/datum/data/record/active1 - var/datum/data/record/active2 - var/temp = null - var/printing = null - //Sorting Variables - var/sortBy = "name" - var/order = 1 // -1 = Descending - 1 = Ascending - - light_color = LIGHT_COLOR_BLUE - -/obj/machinery/computer/med_data/syndie - icon_keyboard = "syndie_key" - -/obj/machinery/computer/med_data/ui_interact(mob/user) - . = ..() - if(isliving(user)) - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) - var/dat - if(temp) - dat = text("[temp]

      Clear Screen") - else - if(authenticated) - switch(screen) - if(1) - dat += {" -Search Records -
      List Records -
      -
      Virus Database -
      Medbot Tracking -
      -
      Record Maintenance -
      {Log Out}
      -"} - if(2) - dat += {" -

      - - - - -
      Records:
      - - - - - - - - -"} - - - if(!isnull(GLOB.data_core.general)) - for(var/datum/data/record/R in sortRecord(GLOB.data_core.general, sortBy, order)) - var/blood_type = "" - var/b_dna = "" - for(var/datum/data/record/E in GLOB.data_core.medical) - if((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"])) - blood_type = E.fields["blood_type"] - b_dna = E.fields["b_dna"] - var/background - - if(R.fields["m_stat"] == "*Insane*" || R.fields["p_stat"] == "*Deceased*") - background = "'background-color:#990000;'" - else if(R.fields["p_stat"] == "*Unconscious*" || R.fields["m_stat"] == "*Unstable*") - background = "'background-color:#CD6500;'" - else if(R.fields["p_stat"] == "Physically Unfit" || R.fields["m_stat"] == "*Watch*") - background = "'background-color:#3BB9FF;'" - else - background = "'background-color:#4F7529;'" - - dat += text("", background, R.fields["id"], R.fields["name"]) - dat += text("", R.fields["id"]) - dat += text("", R.fields["fingerprint"], b_dna) - dat += text("", blood_type) - dat += text("", R.fields["p_stat"]) - dat += text("", R.fields["m_stat"]) - dat += "
      NameIDFingerprints (F) | DNA (D)Blood TypePhysical StatusMental Status
      [][]F: []
      D: []
      [][][]

      " - dat += "
      Back" - if(3) - dat += "Records Maintenance
      \nBackup To Disk
      \nUpload From Disk
      \nDelete All Records
      \n
      \nBack" - if(4) - - dat += "" - if(active1 in GLOB.data_core.general) - if(istype(active1.fields["photo_front"], /obj/item/photo)) - var/obj/item/photo/P1 = active1.fields["photo_front"] - user << browse_rsc(P1.picture.picture_image, "photo_front") - if(istype(active1.fields["photo_side"], /obj/item/photo)) - var/obj/item/photo/P2 = active1.fields["photo_side"] - user << browse_rsc(P2.picture.picture_image, "photo_side") - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - else - dat += "" - - dat += "" - if(active2 in GLOB.data_core.medical) - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" //(per disease info placed in log/comment section) - dat += "" - dat += "" - - dat += "" - var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - dat += "" - counter++ - dat += "" - - dat += "" - else - dat += "" - dat += "" - dat += "" - dat += "" - dat += "
      Medical Record
      Name:[active1.fields["name"]]
      ID:[active1.fields["id"]]
      Gender: [active1.fields["gender"]] 
      Age: [active1.fields["age"]] 
      Species: [active1.fields["species"]] 
      Fingerprint: [active1.fields["fingerprint"]] 
      Physical Status: [active1.fields["p_stat"]] 
      Mental Status: [active1.fields["m_stat"]] 
      General Record Lost!

      Medical Data
      Blood Type: [active2.fields["blood_type"]] 
      DNA: [active2.fields["b_dna"]] 

      Minor Disabilities:

       [active2.fields["mi_dis"]] 
      Details: [active2.fields["mi_dis_d"]] 

      Major Disabilities:

       [active2.fields["ma_dis"]] 
      Details: [active2.fields["ma_dis_d"]] 

      Allergies:

       [active2.fields["alg"]] 
      Details: [active2.fields["alg_d"]] 

      Current Diseases:

       [active2.fields["cdi"]] 
      Details: [active2.fields["cdi_d"]] 

      Important Notes:

       [active2.fields["notes"]] 

      Comments/Log
      [active2.fields[text("com_[]", counter)]]
      Delete Entry
      Add Entry

      Delete Record (Medical Only)
      Medical Record Lost!

      New Record
      Print Record
      Back
      " - if(5) - dat += "
      Virus Database
      " - for(var/Dt in typesof(/datum/disease/)) - var/datum/disease/Dis = new Dt(0) - if(istype(Dis, /datum/disease/advance)) - continue // TODO (tm): Add advance diseases to the virus database which no one uses. - if(!Dis.desc) - continue - dat += "
      [Dis.name]" - dat += "
      Back" - if(6) - dat += "
      Medical Robot Monitor
      " - dat += "Back" - dat += "
      Medical Robots:" - var/bdat = null - for(var/mob/living/simple_animal/bot/medbot/M in GLOB.alive_mob_list) - if(M.z != z) - continue //only find medibots on the same z-level as the computer - var/turf/bl = get_turf(M) - if(bl) //if it can't find a turf for the medibot, then it probably shouldn't be showing up - bdat += "[M.name] - \[[bl.x],[bl.y]\] - [M.on ? "Online" : "Offline"]
      " - if((!isnull(M.reagent_glass)) && M.use_beaker) - bdat += "Reservoir: \[[M.reagent_glass.reagents.total_volume]/[M.reagent_glass.reagents.maximum_volume]\]
      " - else - bdat += "Using Internal Synthesizer.
      " - - if(!bdat) - dat += "
      None detected
      " - else - dat += "
      [bdat]" - - else - else - dat += "{Log In}" - var/datum/browser/popup = new(user, "med_rec", "Medical Records Console", 600, 400) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) - popup.open() - -/obj/machinery/computer/med_data/Topic(href, href_list) - . = ..() - if(.) - return . - if(!(active1 in GLOB.data_core.general)) - active1 = null - if(!(active2 in GLOB.data_core.medical)) - active2 = null - - if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr) || IsAdminGhost(usr)) - usr.set_machine(src) - if(href_list["temp"]) - temp = null - else if(href_list["logout"]) - authenticated = null - screen = null - active1 = null - active2 = null - playsound(src, 'sound/machines/terminal_off.ogg', 50, FALSE) - else if(href_list["choice"]) - // SORTING! - if(href_list["choice"] == "Sorting") - // Reverse the order if clicked twice - if(sortBy == href_list["sort"]) - if(order == 1) - order = -1 - else - order = 1 - else - // New sorting order! - sortBy = href_list["sort"] - order = initial(order) - else if(href_list["login"]) - var/mob/M = usr - var/obj/item/card/id/I = M.get_idcard(TRUE) - if(issilicon(M)) - active1 = null - active2 = null - authenticated = 1 - rank = "AI" - screen = 1 - else if(IsAdminGhost(M)) - active1 = null - active2 = null - authenticated = 1 - rank = "Central Command" - screen = 1 - else if(istype(I) && check_access(I)) - active1 = null - active2 = null - authenticated = I.registered_name - rank = I.assignment - screen = 1 - else - to_chat(usr, "Unauthorized access.") - playsound(src, 'sound/machines/terminal_on.ogg', 50, FALSE) - if(authenticated) - if(href_list["screen"]) - screen = text2num(href_list["screen"]) - if(screen < 1) - screen = 1 - - active1 = null - active2 = null - - else if(href_list["vir"]) - var/type = href_list["vir"] - var/datum/disease/Dis = new type(0) - var/AfS = "" - for(var/mob/M in Dis.viable_mobtypes) - AfS += " [initial(M.name)];" - temp = {"Name: [Dis.name] -
      Number of stages: [Dis.max_stages] -
      Spread: [Dis.spread_text] Transmission -
      Possible Cure: [(Dis.cure_text||"none")] -
      Affected Lifeforms:[AfS] -
      -
      Notes: [Dis.desc] -
      -
      Severity: [Dis.severity]"} - - else if(href_list["del_all"]) - temp = "Are you sure you wish to delete all records?
      \n\tYes
      \n\tNo
      " - - else if(href_list["del_all2"]) - investigate_log("[key_name(usr)] has deleted all medical records.", INVESTIGATE_RECORDS) - GLOB.data_core.medical.Cut() - temp = "All records deleted." - - else if(href_list["field"]) - var/a1 = active1 - var/a2 = active2 - switch(href_list["field"]) - if("fingerprint") - if(active1) - var/t1 = stripped_input("Please input fingerprint hash:", "Med. records", active1.fields["fingerprint"], null) - if(!canUseMedicalRecordsConsole(usr, t1, a1)) - return - active1.fields["fingerprint"] = t1 - if("gender") - if(active1) - if(active1.fields["gender"] == "Male") - active1.fields["gender"] = "Female" - else if(active1.fields["gender"] == "Female") - active1.fields["gender"] = "Other" - else - active1.fields["gender"] = "Male" - if("age") - if(active1) - var/t1 = input("Please input age:", "Med. records", active1.fields["age"], null) as num - if(!canUseMedicalRecordsConsole(usr, t1, a1)) - return - active1.fields["age"] = t1 - if("species") - if(active1) - var/t1 = stripped_input("Please input species name", "Med. records", active1.fields["species"], null) - if(!canUseMedicalRecordsConsole(usr, t1, a1)) - return - active1.fields["species"] = t1 - if("mi_dis") - if(active2) - var/t1 = stripped_input("Please input minor disabilities list:", "Med. records", active2.fields["mi_dis"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["mi_dis"] = t1 - if("mi_dis_d") - if(active2) - var/t1 = stripped_input("Please summarize minor dis.:", "Med. records", active2.fields["mi_dis_d"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["mi_dis_d"] = t1 - if("ma_dis") - if(active2) - var/t1 = stripped_input("Please input major disabilities list:", "Med. records", active2.fields["ma_dis"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["ma_dis"] = t1 - if("ma_dis_d") - if(active2) - var/t1 = stripped_input("Please summarize major dis.:", "Med. records", active2.fields["ma_dis_d"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["ma_dis_d"] = t1 - if("alg") - if(active2) - var/t1 = stripped_input("Please state allergies:", "Med. records", active2.fields["alg"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["alg"] = t1 - if("alg_d") - if(active2) - var/t1 = stripped_input("Please summarize allergies:", "Med. records", active2.fields["alg_d"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["alg_d"] = t1 - if("cdi") - if(active2) - var/t1 = stripped_input("Please state diseases:", "Med. records", active2.fields["cdi"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["cdi"] = t1 - if("cdi_d") - if(active2) - var/t1 = stripped_input("Please summarize diseases:", "Med. records", active2.fields["cdi_d"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["cdi_d"] = t1 - if("notes") - if(active2) - var/t1 = stripped_input("Please summarize notes:", "Med. records", active2.fields["notes"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["notes"] = t1 - if("p_stat") - if(active1) - temp = "Physical Condition:
      \n\t*Deceased*
      \n\t*Unconscious*
      \n\tActive
      \n\tPhysically Unfit
      " - if("m_stat") - if(active1) - temp = "Mental Condition:
      \n\t*Insane*
      \n\t*Unstable*
      \n\t*Watch*
      \n\tStable
      " - if("blood_type") - if(active2) - temp = "Blood Type:
      \n\tA- A+
      \n\tB- B+
      \n\tAB- AB+
      \n\tO- O+
      " - if("b_dna") - if(active2) - var/t1 = stripped_input("Please input DNA hash:", "Med. records", active2.fields["b_dna"], null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - active2.fields["b_dna"] = t1 - if("show_photo_front") - if(active1) - if(active1.fields["photo_front"]) - if(istype(active1.fields["photo_front"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_front"] - P.show(usr) - if("show_photo_side") - if(active1) - if(active1.fields["photo_side"]) - if(istype(active1.fields["photo_side"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_side"] - P.show(usr) - else - - else if(href_list["p_stat"]) - if(active1) - switch(href_list["p_stat"]) - if("deceased") - active1.fields["p_stat"] = "*Deceased*" - if("unconscious") - active1.fields["p_stat"] = "*Unconscious*" - if("active") - active1.fields["p_stat"] = "Active" - if("unfit") - active1.fields["p_stat"] = "Physically Unfit" - - else if(href_list["m_stat"]) - if(active1) - switch(href_list["m_stat"]) - if("insane") - active1.fields["m_stat"] = "*Insane*" - if("unstable") - active1.fields["m_stat"] = "*Unstable*" - if("watch") - active1.fields["m_stat"] = "*Watch*" - if("stable") - active1.fields["m_stat"] = "Stable" - - - else if(href_list["blood_type"]) - if(active2) - switch(href_list["blood_type"]) - if("an") - active2.fields["blood_type"] = "A-" - if("bn") - active2.fields["blood_type"] = "B-" - if("abn") - active2.fields["blood_type"] = "AB-" - if("on") - active2.fields["blood_type"] = "O-" - if("ap") - active2.fields["blood_type"] = "A+" - if("bp") - active2.fields["blood_type"] = "B+" - if("abp") - active2.fields["blood_type"] = "AB+" - if("op") - active2.fields["blood_type"] = "O+" - - - else if(href_list["del_r"]) - if(active2) - temp = "Are you sure you wish to delete the record (Medical Portion Only)?
      \n\tYes
      \n\tNo
      " - - else if(href_list["del_r2"]) - investigate_log("[key_name(usr)] has deleted the medical records for [active1.fields["name"]].", INVESTIGATE_RECORDS) - if(active2) - qdel(active2) - active2 = null - - else if(href_list["d_rec"]) - active1 = find_record("id", href_list["d_rec"], GLOB.data_core.general) - if(active1) - active2 = find_record("id", href_list["d_rec"], GLOB.data_core.medical) - if(!active2) - active1 = null - screen = 4 - - else if(href_list["new"]) - if((istype(active1, /datum/data/record) && !( istype(active2, /datum/data/record) ))) - var/datum/data/record/R = new /datum/data/record( ) - R.fields["name"] = active1.fields["name"] - R.fields["id"] = active1.fields["id"] - R.name = text("Medical Record #[]", R.fields["id"]) - R.fields["blood_type"] = "Unknown" - R.fields["b_dna"] = "Unknown" - R.fields["mi_dis"] = "None" - R.fields["mi_dis_d"] = "No minor disabilities have been diagnosed." - R.fields["ma_dis"] = "None" - R.fields["ma_dis_d"] = "No major disabilities have been diagnosed." - R.fields["alg"] = "None" - R.fields["alg_d"] = "No allergies have been detected in this patient." - R.fields["cdi"] = "None" - R.fields["cdi_d"] = "No diseases have been diagnosed at the moment." - R.fields["notes"] = "No notes." - GLOB.data_core.medical += R - active2 = R - screen = 4 - - else if(href_list["add_c"]) - if(!(active2 in GLOB.data_core.medical)) - return - var/a2 = active2 - var/t1 = stripped_multiline_input("Add Comment:", "Med. records", null, null) - if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) - return - var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - counter++ - active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []
      []", authenticated, rank, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1) - - else if(href_list["del_c"]) - if((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])])) - active2.fields[text("com_[]", href_list["del_c"])] = "Deleted" - - else if(href_list["search"]) - var/t1 = stripped_input(usr, "Search String: (Name, DNA, or ID)", "Med. records") - if(!canUseMedicalRecordsConsole(usr, t1)) - return - active1 = null - active2 = null - t1 = lowertext(t1) - for(var/datum/data/record/R in GLOB.data_core.medical) - if((lowertext(R.fields["name"]) == t1 || t1 == lowertext(R.fields["id"]) || t1 == lowertext(R.fields["b_dna"]))) - active2 = R - else - //Foreach continue //goto(3229) - if(!( active2 )) - temp = text("Could not locate record [].", sanitize(t1)) - else - for(var/datum/data/record/E in GLOB.data_core.general) - if((E.fields["name"] == active2.fields["name"] || E.fields["id"] == active2.fields["id"])) - active1 = E - else - //Foreach continue //goto(3334) - screen = 4 - - else if(href_list["print_p"]) - if(!( printing )) - printing = 1 - GLOB.data_core.medicalPrintCount++ - playsound(loc, 'sound/items/poster_being_created.ogg', 100, 1) - sleep(30) - var/obj/item/paper/P = new /obj/item/paper( loc ) - P.info = "
      Medical Record - (MR-[GLOB.data_core.medicalPrintCount])

      " - if(active1 in GLOB.data_core.general) - P.info += text("Name: [] ID: []
      \nGender: []
      \nAge: []
      ", active1.fields["name"], active1.fields["id"], active1.fields["gender"], active1.fields["age"]) - P.info += "\nSpecies: [active1.fields["species"]]
      " - P.info += text("\nFingerprint: []
      \nPhysical Status: []
      \nMental Status: []
      ", active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"]) - else - P.info += "General Record Lost!
      " - if(active2 in GLOB.data_core.medical) - P.info += text("
      \n
      Medical Data

      \nBlood Type: []
      \nDNA: []
      \n
      \nMinor Disabilities: []
      \nDetails: []
      \n
      \nMajor Disabilities: []
      \nDetails: []
      \n
      \nAllergies: []
      \nDetails: []
      \n
      \nCurrent Diseases: [] (per disease info placed in log/comment section)
      \nDetails: []
      \n
      \nImportant Notes:
      \n\t[]
      \n
      \n
      Comments/Log

      ", active2.fields["blood_type"], active2.fields["b_dna"], active2.fields["mi_dis"], active2.fields["mi_dis_d"], active2.fields["ma_dis"], active2.fields["ma_dis_d"], active2.fields["alg"], active2.fields["alg_d"], active2.fields["cdi"], active2.fields["cdi_d"], active2.fields["notes"]) - var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - P.info += text("[]
      ", active2.fields[text("com_[]", counter)]) - counter++ - P.name = text("MR-[] '[]'", GLOB.data_core.medicalPrintCount, active1.fields["name"]) - else - P.info += "Medical Record Lost!
      " - P.name = text("MR-[] '[]'", GLOB.data_core.medicalPrintCount, "Record Lost") - P.info += "
      " - P.update_icon() - printing = null - - add_fingerprint(usr) - updateUsrDialog() - return - -/obj/machinery/computer/med_data/emp_act(severity) - . = ..() - if(!(stat & (BROKEN|NOPOWER)) && !(. & EMP_PROTECT_SELF)) - for(var/datum/data/record/R in GLOB.data_core.medical) - if(prob(10/severity)) - switch(rand(1,6)) - if(1) - if(prob(10)) - R.fields["name"] = random_unique_lizard_name(R.fields["gender"],1) - else - R.fields["name"] = random_unique_name(R.fields["gender"],1) - if(2) - R.fields["gender"] = pick("Male", "Female", "Other") - if(3) - R.fields["age"] = rand(AGE_MIN, AGE_MAX) - if(4) - R.fields["blood_type"] = random_blood_type() - if(5) - R.fields["p_stat"] = pick("*Unconscious*", "Active", "Physically Unfit") - if(6) - R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable") - continue - - else if(prob(1)) - qdel(R) - continue - -/obj/machinery/computer/med_data/proc/canUseMedicalRecordsConsole(mob/user, message = 1, record1, record2) - if(user) - if(message) - if(authenticated) - if(user.canUseTopic(src, !issilicon(user))) - if(!record1 || record1 == active1) - if(!record2 || record2 == active2) - return 1 - return 0 - -/obj/machinery/computer/med_data/laptop - name = "medical laptop" - desc = "A cheap Nanotrasen medical laptop, it functions as a medical records computer. It's bolted to the table." - icon_state = "laptop" - icon_screen = "medlaptop" - icon_keyboard = "laptop_key" - clockwork = TRUE //it'd look weird - pass_flags = PASSTABLE + + +/obj/machinery/computer/med_data//TODO:SANITY + name = "medical records console" + desc = "This can be used to check medical records." + icon_screen = "medcomp" + icon_keyboard = "med_key" + req_one_access = list(ACCESS_MEDICAL, ACCESS_FORENSICS_LOCKERS) + circuit = /obj/item/circuitboard/computer/med_data + var/rank = null + var/screen = null + var/datum/data/record/active1 + var/datum/data/record/active2 + var/temp = null + var/printing = null + //Sorting Variables + var/sortBy = "name" + var/order = 1 // -1 = Descending - 1 = Ascending + + light_color = LIGHT_COLOR_BLUE + +/obj/machinery/computer/med_data/syndie + icon_keyboard = "syndie_key" + +/obj/machinery/computer/med_data/ui_interact(mob/user) + . = ..() + if(isliving(user)) + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) + var/dat + if(temp) + dat = text("[temp]

      Clear Screen") + else + if(authenticated) + switch(screen) + if(1) + dat += {" +Search Records +
      List Records +
      +
      Virus Database +
      Medbot Tracking +
      +
      Record Maintenance +
      {Log Out}
      +"} + if(2) + dat += {" +

      + + + + +
      Records:
      + + + + + + + + +"} + + + if(!isnull(GLOB.data_core.general)) + for(var/datum/data/record/R in sortRecord(GLOB.data_core.general, sortBy, order)) + var/blood_type = "" + var/b_dna = "" + for(var/datum/data/record/E in GLOB.data_core.medical) + if((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"])) + blood_type = E.fields["blood_type"] + b_dna = E.fields["b_dna"] + var/background + + if(R.fields["m_stat"] == "*Insane*" || R.fields["p_stat"] == "*Deceased*") + background = "'background-color:#990000;'" + else if(R.fields["p_stat"] == "*Unconscious*" || R.fields["m_stat"] == "*Unstable*") + background = "'background-color:#CD6500;'" + else if(R.fields["p_stat"] == "Physically Unfit" || R.fields["m_stat"] == "*Watch*") + background = "'background-color:#3BB9FF;'" + else + background = "'background-color:#4F7529;'" + + dat += text("", background, R.fields["id"], R.fields["name"]) + dat += text("", R.fields["id"]) + dat += text("", R.fields["fingerprint"], b_dna) + dat += text("", blood_type) + dat += text("", R.fields["p_stat"]) + dat += text("", R.fields["m_stat"]) + dat += "
      NameIDFingerprints (F) | DNA (D)Blood TypePhysical StatusMental Status
      [][]F: []
      D: []
      [][][]

      " + dat += "
      Back" + if(3) + dat += "Records Maintenance
      \nBackup To Disk
      \nUpload From Disk
      \nDelete All Records
      \n
      \nBack" + if(4) + + dat += "" + if(active1 in GLOB.data_core.general) + if(istype(active1.fields["photo_front"], /obj/item/photo)) + var/obj/item/photo/P1 = active1.fields["photo_front"] + user << browse_rsc(P1.picture.picture_image, "photo_front") + if(istype(active1.fields["photo_side"], /obj/item/photo)) + var/obj/item/photo/P2 = active1.fields["photo_side"] + user << browse_rsc(P2.picture.picture_image, "photo_side") + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + else + dat += "" + + dat += "" + if(active2 in GLOB.data_core.medical) + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" //(per disease info placed in log/comment section) + dat += "" + dat += "" + + dat += "" + var/counter = 1 + while(active2.fields[text("com_[]", counter)]) + dat += "" + counter++ + dat += "" + + dat += "" + else + dat += "" + dat += "" + dat += "" + dat += "" + dat += "
      Medical Record
      Name:[active1.fields["name"]]
      ID:[active1.fields["id"]]
      Gender: [active1.fields["gender"]] 
      Age: [active1.fields["age"]] 
      Species: [active1.fields["species"]] 
      Fingerprint: [active1.fields["fingerprint"]] 
      Physical Status: [active1.fields["p_stat"]] 
      Mental Status: [active1.fields["m_stat"]] 
      General Record Lost!

      Medical Data
      Blood Type: [active2.fields["blood_type"]] 
      DNA: [active2.fields["b_dna"]] 

      Minor Disabilities:

       [active2.fields["mi_dis"]] 
      Details: [active2.fields["mi_dis_d"]] 

      Major Disabilities:

       [active2.fields["ma_dis"]] 
      Details: [active2.fields["ma_dis_d"]] 

      Allergies:

       [active2.fields["alg"]] 
      Details: [active2.fields["alg_d"]] 

      Current Diseases:

       [active2.fields["cdi"]] 
      Details: [active2.fields["cdi_d"]] 

      Important Notes:

       [active2.fields["notes"]] 

      Comments/Log
      [active2.fields[text("com_[]", counter)]]
      Delete Entry
      Add Entry

      Delete Record (Medical Only)
      Medical Record Lost!

      New Record
      Print Record
      Back
      " + if(5) + dat += "
      Virus Database
      " + for(var/Dt in typesof(/datum/disease/)) + var/datum/disease/Dis = new Dt(0) + if(istype(Dis, /datum/disease/advance)) + continue // TODO (tm): Add advance diseases to the virus database which no one uses. + if(!Dis.desc) + continue + dat += "
      [Dis.name]" + dat += "
      Back" + if(6) + dat += "
      Medical Robot Monitor
      " + dat += "Back" + dat += "
      Medical Robots:" + var/bdat = null + for(var/mob/living/simple_animal/bot/medbot/M in GLOB.alive_mob_list) + if(M.z != z) + continue //only find medibots on the same z-level as the computer + var/turf/bl = get_turf(M) + if(bl) //if it can't find a turf for the medibot, then it probably shouldn't be showing up + bdat += "[M.name] - \[[bl.x],[bl.y]\] - [M.on ? "Online" : "Offline"]
      " + if((!isnull(M.reagent_glass)) && M.use_beaker) + bdat += "Reservoir: \[[M.reagent_glass.reagents.total_volume]/[M.reagent_glass.reagents.maximum_volume]\]
      " + else + bdat += "Using Internal Synthesizer.
      " + + if(!bdat) + dat += "
      None detected
      " + else + dat += "
      [bdat]" + + else + else + dat += "{Log In}" + var/datum/browser/popup = new(user, "med_rec", "Medical Records Console", 600, 400) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) + popup.open() + +/obj/machinery/computer/med_data/Topic(href, href_list) + . = ..() + if(.) + return . + if(!(active1 in GLOB.data_core.general)) + active1 = null + if(!(active2 in GLOB.data_core.medical)) + active2 = null + + if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr) || IsAdminGhost(usr)) + usr.set_machine(src) + if(href_list["temp"]) + temp = null + else if(href_list["logout"]) + authenticated = null + screen = null + active1 = null + active2 = null + playsound(src, 'sound/machines/terminal_off.ogg', 50, FALSE) + else if(href_list["choice"]) + // SORTING! + if(href_list["choice"] == "Sorting") + // Reverse the order if clicked twice + if(sortBy == href_list["sort"]) + if(order == 1) + order = -1 + else + order = 1 + else + // New sorting order! + sortBy = href_list["sort"] + order = initial(order) + else if(href_list["login"]) + var/mob/M = usr + var/obj/item/card/id/I = M.get_idcard(TRUE) + if(issilicon(M)) + active1 = null + active2 = null + authenticated = 1 + rank = "AI" + screen = 1 + else if(IsAdminGhost(M)) + active1 = null + active2 = null + authenticated = 1 + rank = "Central Command" + screen = 1 + else if(istype(I) && check_access(I)) + active1 = null + active2 = null + authenticated = I.registered_name + rank = I.assignment + screen = 1 + else + to_chat(usr, "Unauthorized access.") + playsound(src, 'sound/machines/terminal_on.ogg', 50, FALSE) + if(authenticated) + if(href_list["screen"]) + screen = text2num(href_list["screen"]) + if(screen < 1) + screen = 1 + + active1 = null + active2 = null + + else if(href_list["vir"]) + var/type = href_list["vir"] + var/datum/disease/Dis = new type(0) + var/AfS = "" + for(var/mob/M in Dis.viable_mobtypes) + AfS += " [initial(M.name)];" + temp = {"Name: [Dis.name] +
      Number of stages: [Dis.max_stages] +
      Spread: [Dis.spread_text] Transmission +
      Possible Cure: [(Dis.cure_text||"none")] +
      Affected Lifeforms:[AfS] +
      +
      Notes: [Dis.desc] +
      +
      Severity: [Dis.severity]"} + + else if(href_list["del_all"]) + temp = "Are you sure you wish to delete all records?
      \n\tYes
      \n\tNo
      " + + else if(href_list["del_all2"]) + investigate_log("[key_name(usr)] has deleted all medical records.", INVESTIGATE_RECORDS) + GLOB.data_core.medical.Cut() + temp = "All records deleted." + + else if(href_list["field"]) + var/a1 = active1 + var/a2 = active2 + switch(href_list["field"]) + if("fingerprint") + if(active1) + var/t1 = stripped_input("Please input fingerprint hash:", "Med. records", active1.fields["fingerprint"], null) + if(!canUseMedicalRecordsConsole(usr, t1, a1)) + return + active1.fields["fingerprint"] = t1 + if("gender") + if(active1) + if(active1.fields["gender"] == "Male") + active1.fields["gender"] = "Female" + else if(active1.fields["gender"] == "Female") + active1.fields["gender"] = "Other" + else + active1.fields["gender"] = "Male" + if("age") + if(active1) + var/t1 = input("Please input age:", "Med. records", active1.fields["age"], null) as num + if(!canUseMedicalRecordsConsole(usr, t1, a1)) + return + active1.fields["age"] = t1 + if("species") + if(active1) + var/t1 = stripped_input("Please input species name", "Med. records", active1.fields["species"], null) + if(!canUseMedicalRecordsConsole(usr, t1, a1)) + return + active1.fields["species"] = t1 + if("mi_dis") + if(active2) + var/t1 = stripped_input("Please input minor disabilities list:", "Med. records", active2.fields["mi_dis"], null) + if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) + return + active2.fields["mi_dis"] = t1 + if("mi_dis_d") + if(active2) + var/t1 = stripped_input("Please summarize minor dis.:", "Med. records", active2.fields["mi_dis_d"], null) + if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) + return + active2.fields["mi_dis_d"] = t1 + if("ma_dis") + if(active2) + var/t1 = stripped_input("Please input major disabilities list:", "Med. records", active2.fields["ma_dis"], null) + if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) + return + active2.fields["ma_dis"] = t1 + if("ma_dis_d") + if(active2) + var/t1 = stripped_input("Please summarize major dis.:", "Med. records", active2.fields["ma_dis_d"], null) + if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) + return + active2.fields["ma_dis_d"] = t1 + if("alg") + if(active2) + var/t1 = stripped_input("Please state allergies:", "Med. records", active2.fields["alg"], null) + if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) + return + active2.fields["alg"] = t1 + if("alg_d") + if(active2) + var/t1 = stripped_input("Please summarize allergies:", "Med. records", active2.fields["alg_d"], null) + if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) + return + active2.fields["alg_d"] = t1 + if("cdi") + if(active2) + var/t1 = stripped_input("Please state diseases:", "Med. records", active2.fields["cdi"], null) + if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) + return + active2.fields["cdi"] = t1 + if("cdi_d") + if(active2) + var/t1 = stripped_input("Please summarize diseases:", "Med. records", active2.fields["cdi_d"], null) + if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) + return + active2.fields["cdi_d"] = t1 + if("notes") + if(active2) + var/t1 = stripped_input("Please summarize notes:", "Med. records", active2.fields["notes"], null) + if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) + return + active2.fields["notes"] = t1 + if("p_stat") + if(active1) + temp = "Physical Condition:
      \n\t*Deceased*
      \n\t*Unconscious*
      \n\tActive
      \n\tPhysically Unfit
      " + if("m_stat") + if(active1) + temp = "Mental Condition:
      \n\t*Insane*
      \n\t*Unstable*
      \n\t*Watch*
      \n\tStable
      " + if("blood_type") + if(active2) + temp = "Blood Type:
      \n\tA- A+
      \n\tB- B+
      \n\tAB- AB+
      \n\tO- O+
      " + if("b_dna") + if(active2) + var/t1 = stripped_input("Please input DNA hash:", "Med. records", active2.fields["b_dna"], null) + if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) + return + active2.fields["b_dna"] = t1 + if("show_photo_front") + if(active1) + if(active1.fields["photo_front"]) + if(istype(active1.fields["photo_front"], /obj/item/photo)) + var/obj/item/photo/P = active1.fields["photo_front"] + P.show(usr) + if("show_photo_side") + if(active1) + if(active1.fields["photo_side"]) + if(istype(active1.fields["photo_side"], /obj/item/photo)) + var/obj/item/photo/P = active1.fields["photo_side"] + P.show(usr) + else + + else if(href_list["p_stat"]) + if(active1) + switch(href_list["p_stat"]) + if("deceased") + active1.fields["p_stat"] = "*Deceased*" + if("unconscious") + active1.fields["p_stat"] = "*Unconscious*" + if("active") + active1.fields["p_stat"] = "Active" + if("unfit") + active1.fields["p_stat"] = "Physically Unfit" + + else if(href_list["m_stat"]) + if(active1) + switch(href_list["m_stat"]) + if("insane") + active1.fields["m_stat"] = "*Insane*" + if("unstable") + active1.fields["m_stat"] = "*Unstable*" + if("watch") + active1.fields["m_stat"] = "*Watch*" + if("stable") + active1.fields["m_stat"] = "Stable" + + + else if(href_list["blood_type"]) + if(active2) + switch(href_list["blood_type"]) + if("an") + active2.fields["blood_type"] = "A-" + if("bn") + active2.fields["blood_type"] = "B-" + if("abn") + active2.fields["blood_type"] = "AB-" + if("on") + active2.fields["blood_type"] = "O-" + if("ap") + active2.fields["blood_type"] = "A+" + if("bp") + active2.fields["blood_type"] = "B+" + if("abp") + active2.fields["blood_type"] = "AB+" + if("op") + active2.fields["blood_type"] = "O+" + + + else if(href_list["del_r"]) + if(active2) + temp = "Are you sure you wish to delete the record (Medical Portion Only)?
      \n\tYes
      \n\tNo
      " + + else if(href_list["del_r2"]) + investigate_log("[key_name(usr)] has deleted the medical records for [active1.fields["name"]].", INVESTIGATE_RECORDS) + if(active2) + qdel(active2) + active2 = null + + else if(href_list["d_rec"]) + active1 = find_record("id", href_list["d_rec"], GLOB.data_core.general) + if(active1) + active2 = find_record("id", href_list["d_rec"], GLOB.data_core.medical) + if(!active2) + active1 = null + screen = 4 + + else if(href_list["new"]) + if((istype(active1, /datum/data/record) && !( istype(active2, /datum/data/record) ))) + var/datum/data/record/R = new /datum/data/record( ) + R.fields["name"] = active1.fields["name"] + R.fields["id"] = active1.fields["id"] + R.name = text("Medical Record #[]", R.fields["id"]) + R.fields["blood_type"] = "Unknown" + R.fields["b_dna"] = "Unknown" + R.fields["mi_dis"] = "None" + R.fields["mi_dis_d"] = "No minor disabilities have been diagnosed." + R.fields["ma_dis"] = "None" + R.fields["ma_dis_d"] = "No major disabilities have been diagnosed." + R.fields["alg"] = "None" + R.fields["alg_d"] = "No allergies have been detected in this patient." + R.fields["cdi"] = "None" + R.fields["cdi_d"] = "No diseases have been diagnosed at the moment." + R.fields["notes"] = "No notes." + GLOB.data_core.medical += R + active2 = R + screen = 4 + + else if(href_list["add_c"]) + if(!(active2 in GLOB.data_core.medical)) + return + var/a2 = active2 + var/t1 = stripped_multiline_input("Add Comment:", "Med. records", null, null) + if(!canUseMedicalRecordsConsole(usr, t1, null, a2)) + return + var/counter = 1 + while(active2.fields[text("com_[]", counter)]) + counter++ + active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []
      []", authenticated, rank, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1) + + else if(href_list["del_c"]) + if((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])])) + active2.fields[text("com_[]", href_list["del_c"])] = "Deleted" + + else if(href_list["search"]) + var/t1 = stripped_input(usr, "Search String: (Name, DNA, or ID)", "Med. records") + if(!canUseMedicalRecordsConsole(usr, t1)) + return + active1 = null + active2 = null + t1 = lowertext(t1) + for(var/datum/data/record/R in GLOB.data_core.medical) + if((lowertext(R.fields["name"]) == t1 || t1 == lowertext(R.fields["id"]) || t1 == lowertext(R.fields["b_dna"]))) + active2 = R + else + //Foreach continue //goto(3229) + if(!( active2 )) + temp = text("Could not locate record [].", sanitize(t1)) + else + for(var/datum/data/record/E in GLOB.data_core.general) + if((E.fields["name"] == active2.fields["name"] || E.fields["id"] == active2.fields["id"])) + active1 = E + else + //Foreach continue //goto(3334) + screen = 4 + + else if(href_list["print_p"]) + if(!( printing )) + printing = 1 + GLOB.data_core.medicalPrintCount++ + playsound(loc, 'sound/items/poster_being_created.ogg', 100, 1) + sleep(30) + var/obj/item/paper/P = new /obj/item/paper( loc ) + P.info = "
      Medical Record - (MR-[GLOB.data_core.medicalPrintCount])

      " + if(active1 in GLOB.data_core.general) + P.info += text("Name: [] ID: []
      \nGender: []
      \nAge: []
      ", active1.fields["name"], active1.fields["id"], active1.fields["gender"], active1.fields["age"]) + P.info += "\nSpecies: [active1.fields["species"]]
      " + P.info += text("\nFingerprint: []
      \nPhysical Status: []
      \nMental Status: []
      ", active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"]) + else + P.info += "General Record Lost!
      " + if(active2 in GLOB.data_core.medical) + P.info += text("
      \n
      Medical Data

      \nBlood Type: []
      \nDNA: []
      \n
      \nMinor Disabilities: []
      \nDetails: []
      \n
      \nMajor Disabilities: []
      \nDetails: []
      \n
      \nAllergies: []
      \nDetails: []
      \n
      \nCurrent Diseases: [] (per disease info placed in log/comment section)
      \nDetails: []
      \n
      \nImportant Notes:
      \n\t[]
      \n
      \n
      Comments/Log

      ", active2.fields["blood_type"], active2.fields["b_dna"], active2.fields["mi_dis"], active2.fields["mi_dis_d"], active2.fields["ma_dis"], active2.fields["ma_dis_d"], active2.fields["alg"], active2.fields["alg_d"], active2.fields["cdi"], active2.fields["cdi_d"], active2.fields["notes"]) + var/counter = 1 + while(active2.fields[text("com_[]", counter)]) + P.info += text("[]
      ", active2.fields[text("com_[]", counter)]) + counter++ + P.name = text("MR-[] '[]'", GLOB.data_core.medicalPrintCount, active1.fields["name"]) + else + P.info += "Medical Record Lost!
      " + P.name = text("MR-[] '[]'", GLOB.data_core.medicalPrintCount, "Record Lost") + P.info += "
      " + P.update_icon() + printing = null + + add_fingerprint(usr) + updateUsrDialog() + return + +/obj/machinery/computer/med_data/emp_act(severity) + . = ..() + if(!(stat & (BROKEN|NOPOWER)) && !(. & EMP_PROTECT_SELF)) + for(var/datum/data/record/R in GLOB.data_core.medical) + if(prob(10/severity)) + switch(rand(1,6)) + if(1) + if(prob(10)) + R.fields["name"] = random_unique_lizard_name(R.fields["gender"],1) + else + R.fields["name"] = random_unique_name(R.fields["gender"],1) + if(2) + R.fields["gender"] = pick("Male", "Female", "Other") + if(3) + R.fields["age"] = rand(AGE_MIN, AGE_MAX) + if(4) + R.fields["blood_type"] = random_blood_type() + if(5) + R.fields["p_stat"] = pick("*Unconscious*", "Active", "Physically Unfit") + if(6) + R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable") + continue + + else if(prob(1)) + qdel(R) + continue + +/obj/machinery/computer/med_data/proc/canUseMedicalRecordsConsole(mob/user, message = 1, record1, record2) + if(user) + if(message) + if(authenticated) + if(user.canUseTopic(src, !issilicon(user))) + if(!record1 || record1 == active1) + if(!record2 || record2 == active2) + return 1 + return 0 + +/obj/machinery/computer/med_data/laptop + name = "medical laptop" + desc = "A cheap Nanotrasen medical laptop, it functions as a medical records computer. It's bolted to the table." + icon_state = "laptop" + icon_screen = "medlaptop" + icon_keyboard = "laptop_key" + clockwork = TRUE //it'd look weird + pass_flags = PASSTABLE diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm index b71f572e68..1388e3c8de 100644 --- a/code/game/machinery/computer/pod.dm +++ b/code/game/machinery/computer/pod.dm @@ -1,133 +1,133 @@ -/obj/machinery/computer/pod - name = "mass driver launch control" - desc = "A combined blastdoor and mass driver control unit." - var/obj/machinery/mass_driver/connected = null - var/title = "Mass Driver Controls" - var/id = 1 - var/timing = 0 - var/time = 30 - var/range = 4 - - -/obj/machinery/computer/pod/Initialize() - . = ..() - for(var/obj/machinery/mass_driver/M in range(range, src)) - if(M.id == id) - connected = M - - -/obj/machinery/computer/pod/proc/alarm() - if(stat & (NOPOWER|BROKEN)) - return - - if(!connected) - say("Cannot locate mass driver connector. Cancelling firing sequence!") - return - - for(var/obj/machinery/door/poddoor/M in range(range, src)) - if(M.id == id) - M.open() - - sleep(20) - for(var/obj/machinery/mass_driver/M in range(range, src)) - if(M.id == id) - M.power = connected.power - M.drive() - - sleep(50) - for(var/obj/machinery/door/poddoor/M in range(range, src)) - if(M.id == id) - M.close() - -/obj/machinery/computer/pod/ui_interact(mob/user) - . = ..() - if(!allowed(user)) - to_chat(user, "Access denied.") - return - - var/dat = "" - if(connected) - var/d2 - if(timing) //door controls do not need timers. - d2 = "Stop Time Launch" - else - d2 = "Initiate Time Launch" - dat += "
      \nTimer System: [d2]\nTime Left: [DisplayTimeText(time)] - - + +" - var/temp = "" - var/list/L = list( 0.25, 0.5, 1, 2, 4, 8, 16 ) - for(var/t in L) - if(t == connected.power) - temp += "[t] " - else - temp += "[t] " - dat += "
      \nPower Level: [temp]
      \nFiring Sequence
      \nTest Fire Driver
      \nToggle Outer Door
      " - else - dat += "
      \nToggle Outer Door
      " - dat += "

      Close" - add_fingerprint(usr) - var/datum/browser/popup = new(user, "computer", title, 400, 500) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) - popup.open() - -/obj/machinery/computer/pod/process() - if(!..()) - return - if(timing) - if(time > 0) - time = round(time) - 1 - else - alarm() - time = 0 - timing = 0 - updateDialog() - - -/obj/machinery/computer/pod/Topic(href, href_list) - if(..()) - return - if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr)) - usr.set_machine(src) - if(href_list["power"]) - var/t = text2num(href_list["power"]) - t = min(max(0.25, t), 16) - if(connected) - connected.power = t - if(href_list["alarm"]) - alarm() - if(href_list["time"]) - timing = text2num(href_list["time"]) - if(href_list["tp"]) - var/tp = text2num(href_list["tp"]) - time += tp - time = min(max(round(time), 0), 120) - if(href_list["door"]) - for(var/obj/machinery/door/poddoor/M in range(range, src)) - if(M.id == id) - if(M.density) - M.open() - else - M.close() - if(href_list["drive"]) - for(var/obj/machinery/mass_driver/M in range(range, src)) - if(M.id == id) - M.power = connected.power - M.drive() - updateUsrDialog() - -/obj/machinery/computer/pod/old - name = "\improper DoorMex control console" - title = "Door Controls" - icon_state = "oldcomp" - icon_screen = "library" - icon_keyboard = null - -/obj/machinery/computer/pod/old/syndicate - name = "\improper ProComp Executive IIc" - desc = "The Syndicate operate on a tight budget. Operates external airlocks." - title = "External Airlock Controls" - req_access = list(ACCESS_SYNDICATE) - -/obj/machinery/computer/pod/old/swf - name = "\improper Magix System IV" - desc = "An arcane artifact that holds much magic. Running E-Knock 2.2: Sorcerer's Edition." +/obj/machinery/computer/pod + name = "mass driver launch control" + desc = "A combined blastdoor and mass driver control unit." + var/obj/machinery/mass_driver/connected = null + var/title = "Mass Driver Controls" + var/id = 1 + var/timing = 0 + var/time = 30 + var/range = 4 + + +/obj/machinery/computer/pod/Initialize() + . = ..() + for(var/obj/machinery/mass_driver/M in range(range, src)) + if(M.id == id) + connected = M + + +/obj/machinery/computer/pod/proc/alarm() + if(stat & (NOPOWER|BROKEN)) + return + + if(!connected) + say("Cannot locate mass driver connector. Cancelling firing sequence!") + return + + for(var/obj/machinery/door/poddoor/M in range(range, src)) + if(M.id == id) + M.open() + + sleep(20) + for(var/obj/machinery/mass_driver/M in range(range, src)) + if(M.id == id) + M.power = connected.power + M.drive() + + sleep(50) + for(var/obj/machinery/door/poddoor/M in range(range, src)) + if(M.id == id) + M.close() + +/obj/machinery/computer/pod/ui_interact(mob/user) + . = ..() + if(!allowed(user)) + to_chat(user, "Access denied.") + return + + var/dat = "" + if(connected) + var/d2 + if(timing) //door controls do not need timers. + d2 = "Stop Time Launch" + else + d2 = "Initiate Time Launch" + dat += "
      \nTimer System: [d2]\nTime Left: [DisplayTimeText(time)] - - + +" + var/temp = "" + var/list/L = list( 0.25, 0.5, 1, 2, 4, 8, 16 ) + for(var/t in L) + if(t == connected.power) + temp += "[t] " + else + temp += "[t] " + dat += "
      \nPower Level: [temp]
      \nFiring Sequence
      \nTest Fire Driver
      \nToggle Outer Door
      " + else + dat += "
      \nToggle Outer Door
      " + dat += "

      Close" + add_fingerprint(usr) + var/datum/browser/popup = new(user, "computer", title, 400, 500) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) + popup.open() + +/obj/machinery/computer/pod/process() + if(!..()) + return + if(timing) + if(time > 0) + time = round(time) - 1 + else + alarm() + time = 0 + timing = 0 + updateDialog() + + +/obj/machinery/computer/pod/Topic(href, href_list) + if(..()) + return + if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr)) + usr.set_machine(src) + if(href_list["power"]) + var/t = text2num(href_list["power"]) + t = min(max(0.25, t), 16) + if(connected) + connected.power = t + if(href_list["alarm"]) + alarm() + if(href_list["time"]) + timing = text2num(href_list["time"]) + if(href_list["tp"]) + var/tp = text2num(href_list["tp"]) + time += tp + time = min(max(round(time), 0), 120) + if(href_list["door"]) + for(var/obj/machinery/door/poddoor/M in range(range, src)) + if(M.id == id) + if(M.density) + M.open() + else + M.close() + if(href_list["drive"]) + for(var/obj/machinery/mass_driver/M in range(range, src)) + if(M.id == id) + M.power = connected.power + M.drive() + updateUsrDialog() + +/obj/machinery/computer/pod/old + name = "\improper DoorMex control console" + title = "Door Controls" + icon_state = "oldcomp" + icon_screen = "library" + icon_keyboard = null + +/obj/machinery/computer/pod/old/syndicate + name = "\improper ProComp Executive IIc" + desc = "The Syndicate operate on a tight budget. Operates external airlocks." + title = "External Airlock Controls" + req_access = list(ACCESS_SYNDICATE) + +/obj/machinery/computer/pod/old/swf + name = "\improper Magix System IV" + desc = "An arcane artifact that holds much magic. Running E-Knock 2.2: Sorcerer's Edition." diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index 5c8d189a7f..5573c56386 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -1,165 +1,165 @@ -/obj/machinery/computer/robotics - name = "robotics control console" - desc = "Used to remotely lockdown or detonate linked Cyborgs and Drones." - icon_screen = "robot" - icon_keyboard = "rd_key" - req_access = list(ACCESS_ROBOTICS) - circuit = /obj/item/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/ui_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.silicon_mobs) - 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) && user != R) - var/mob/living/silicon/S = user - if(is_servant_of_ratvar(S)) - dat += "(Convert) " - else if(S.hack_software && !R.emagged) - dat += "(Hack) " - else if(IsAdminGhost(user) && !R.emagged) - 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.drones_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) && !..()) - var/turf/T = get_turf(R) - message_admins("[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(R, R.client)] at [ADMIN_VERBOSEJMP(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"]) - var/mob/living/silicon/S = usr - if((istype(S) && S.hack_software) || IsAdminGhost(usr)) - var/mob/living/silicon/robot/R = locate(href_list["magbot"]) in GLOB.silicon_mobs - if(istype(R) && !R.emagged && (R.connected_ai == usr || IsAdminGhost(usr)) && !R.scrambledcodes && can_control(usr, R)) - log_game("[key_name(usr)] emagged [key_name(R)] using robotic console!") - message_admins("[ADMIN_LOOKUPFLW(usr)] emagged cyborg [key_name_admin(R)] using robotic console!") - R.SetEmagged(1) - - else if(href_list["convert"]) - if(isAI(usr) && is_servant_of_ratvar(usr)) - var/mob/living/silicon/robot/R = locate(href_list["convert"]) in GLOB.silicon_mobs - if(istype(R) && !is_servant_of_ratvar(R) && R.connected_ai == usr) - log_game("[key_name(usr)] converted [key_name(R)] using robotic console!") - message_admins("[ADMIN_LOOKUPFLW(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"]) in GLOB.mob_list - if(D.hacked) - to_chat(usr, "ERROR: [D] is not responding to external commands.") - else - var/turf/T = get_turf(D) - message_admins("[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(D)] at [ADMIN_VERBOSEJMP(T)]!") - log_game("[key_name(usr)] detonated [key_name(D)]!") - 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 and Drones." + icon_screen = "robot" + icon_keyboard = "rd_key" + req_access = list(ACCESS_ROBOTICS) + circuit = /obj/item/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/ui_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.silicon_mobs) + 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) && user != R) + var/mob/living/silicon/S = user + if(is_servant_of_ratvar(S)) + dat += "(Convert) " + else if(S.hack_software && !R.emagged) + dat += "(Hack) " + else if(IsAdminGhost(user) && !R.emagged) + 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.drones_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) && !..()) + var/turf/T = get_turf(R) + message_admins("[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(R, R.client)] at [ADMIN_VERBOSEJMP(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"]) + var/mob/living/silicon/S = usr + if((istype(S) && S.hack_software) || IsAdminGhost(usr)) + var/mob/living/silicon/robot/R = locate(href_list["magbot"]) in GLOB.silicon_mobs + if(istype(R) && !R.emagged && (R.connected_ai == usr || IsAdminGhost(usr)) && !R.scrambledcodes && can_control(usr, R)) + log_game("[key_name(usr)] emagged [key_name(R)] using robotic console!") + message_admins("[ADMIN_LOOKUPFLW(usr)] emagged cyborg [key_name_admin(R)] using robotic console!") + R.SetEmagged(1) + + else if(href_list["convert"]) + if(isAI(usr) && is_servant_of_ratvar(usr)) + var/mob/living/silicon/robot/R = locate(href_list["convert"]) in GLOB.silicon_mobs + if(istype(R) && !is_servant_of_ratvar(R) && R.connected_ai == usr) + log_game("[key_name(usr)] converted [key_name(R)] using robotic console!") + message_admins("[ADMIN_LOOKUPFLW(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"]) in GLOB.mob_list + if(D.hacked) + to_chat(usr, "ERROR: [D] is not responding to external commands.") + else + var/turf/T = get_turf(D) + message_admins("[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(D)] at [ADMIN_VERBOSEJMP(T)]!") + log_game("[key_name(usr)] detonated [key_name(D)]!") + 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/computer/security.dm b/code/game/machinery/computer/security.dm index c9f2f28ab1..aabb1fe408 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -1,812 +1,812 @@ -/obj/machinery/computer/secure_data//TODO:SANITY - name = "security records console" - desc = "Used to view and edit personnel's security records." - icon_screen = "security" - icon_keyboard = "security_key" - req_one_access = list(ACCESS_SECURITY, ACCESS_FORENSICS_LOCKERS) - circuit = /obj/item/circuitboard/computer/secure_data - var/rank = null - var/screen = null - var/datum/data/record/active1 = null - var/datum/data/record/active2 = null - var/temp = null - var/printing = null - var/can_change_id = 0 - var/list/Perp - var/tempname = null - //Sorting Variables - var/sortBy = "name" - var/order = 1 // -1 = Descending - 1 = Ascending - - light_color = LIGHT_COLOR_RED - -/obj/machinery/computer/secure_data/syndie - icon_keyboard = "syndie_key" - -/obj/machinery/computer/secure_data/laptop - name = "security laptop" - desc = "A cheap Nanotrasen security laptop, it functions as a security records console. It's bolted to the table." - icon_state = "laptop" - icon_screen = "seclaptop" - icon_keyboard = "laptop_key" - clockwork = TRUE //it'd look weird - pass_flags = PASSTABLE - -//Someone needs to break down the dat += into chunks instead of long ass lines. -/obj/machinery/computer/secure_data/ui_interact(mob/user) - . = ..() - if(isliving(user)) - playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) - if(src.z > 6) - to_chat(user, "Unable to establish a connection: \black You're too far away from the station!") - return - var/dat - - if(temp) - dat = "[temp]

      Clear Screen" - else - dat = "" - if(authenticated) - switch(screen) - if(1) - - //body tag start + onload and onkeypress (onkeyup) javascript event calls - dat += "" - //search bar javascript - dat += {" - - - - - - - - "} - dat += {" -

      "} - dat += "New Record
      " - //search bar - dat += {" - - - - -
      - Search: -
      - "} - dat += {" -

      - - - - -
      Records:
      - - - - - - - - - -"} - if(!isnull(GLOB.data_core.general)) - for(var/datum/data/record/R in sortRecord(GLOB.data_core.general, sortBy, order)) - var/crimstat = "" - for(var/datum/data/record/E in GLOB.data_core.security) - if((E.fields["name"] == R.fields["name"]) && (E.fields["id"] == R.fields["id"])) - crimstat = E.fields["criminal"] - var/background - switch(crimstat) - if("*Arrest*") - background = "'background-color:#990000;'" - if("Incarcerated") - background = "'background-color:#CD6500;'" - if("Paroled") - background = "'background-color:#CD6500;'" - if("Discharged") - background = "'background-color:#006699;'" - if("None") - background = "'background-color:#4F7529;'" - if("") - background = "''" //"'background-color:#FFFFFF;'" - crimstat = "No Record." - dat += "" - dat += text("", R.fields["name"], R.fields["id"], R.fields["rank"], R.fields["fingerprint"], R.fields["name"]) - dat += text("", R.fields["id"]) - dat += text("", R.fields["rank"]) - dat += text("", R.fields["fingerprint"]) - dat += text("", crimstat) - dat += {" -
      NameIDRankFingerprintsCriminal Status
      [][][][][]
      - -
      "} - dat += "Record Maintenance

      " - dat += "{Log Out}" - if(2) - dat += "Records Maintenance
      " - dat += "
      Delete All Records

      Back" - if(3) - dat += "Security Record
      " - if(istype(active1, /datum/data/record) && GLOB.data_core.general.Find(active1)) - if(istype(active1.fields["photo_front"], /obj/item/photo)) - var/obj/item/photo/P1 = active1.fields["photo_front"] - user << browse_rsc(P1.picture.picture_image, "photo_front") - if(istype(active1.fields["photo_side"], /obj/item/photo)) - var/obj/item/photo/P2 = active1.fields["photo_side"] - user << browse_rsc(P2.picture.picture_image, "photo_side") - dat += {" -
      - - - - "} - dat += "" - dat += {" - - - -
      Name: [active1.fields["name"]] 
      ID: [active1.fields["id"]] 
      Gender: [active1.fields["gender"]] 
      Age: [active1.fields["age"]] 
      Species: [active1.fields["species"]] 
      Rank: [active1.fields["rank"]] 
      Fingerprint: [active1.fields["fingerprint"]] 
      Physical Status: [active1.fields["p_stat"]] 
      Mental Status: [active1.fields["m_stat"]] 
      -

      - Print photo
      - Update front photo

      - Print photo
      - Update side photo
      -
      "} - else - dat += "
      General Record Lost!
      " - if((istype(active2, /datum/data/record) && GLOB.data_core.security.Find(active2))) - dat += "Security Data" - dat += "
      Criminal Status: [active2.fields["criminal"]]" - dat += "

      Minor Crimes: Add New" - - - dat +={" - - - - - - - "} - for(var/datum/data/crime/c in active2.fields["mi_crim"]) - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "
      CrimeDetailsAuthorTime AddedDel
      [c.crimeName][c.crimeDetails][c.author][c.time]\[X\]
      " - - - dat += "
      Major Crimes: Add New" - - dat +={" - - - - - - - "} - for(var/datum/data/crime/c in active2.fields["ma_crim"]) - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "" - dat += "
      CrimeDetailsAuthorTime AddedDel
      [c.crimeName][c.crimeDetails][c.author][c.time]\[X\]
      " - - dat += "
      \nImportant Notes:
      \n\t [active2.fields["notes"]] " - dat += "

      Comments/Log
      " - var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - dat += (active2.fields[text("com_[]", counter)] + "
      ") - if(active2.fields[text("com_[]", counter)] != "Deleted") - dat += text("Delete Entry

      ", counter) - counter++ - dat += "Add Entry

      " - dat += "Delete Record (Security Only)
      " - else - dat += "Security Record Lost!
      " - dat += "New Security Record

      " - dat += "Delete Record (ALL)
      Print Record
      Print Wanted Poster
      Back

      " - dat += "{Log Out}" - else - else - dat += "{Log In}" - var/datum/browser/popup = new(user, "secure_rec", "Security Records Console", 600, 400) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - return - -/*Revised /N -I can't be bothered to look more of the actual code outside of switch but that probably needs revising too. -What a mess.*/ -/obj/machinery/computer/secure_data/Topic(href, href_list) - . = ..() - if(.) - return . - if(!( GLOB.data_core.general.Find(active1) )) - active1 = null - if(!( GLOB.data_core.security.Find(active2) )) - active2 = null - if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr) || IsAdminGhost(usr)) - usr.set_machine(src) - switch(href_list["choice"]) -// SORTING! - if("Sorting") - // Reverse the order if clicked twice - if(sortBy == href_list["sort"]) - if(order == 1) - order = -1 - else - order = 1 - else - // New sorting order! - sortBy = href_list["sort"] - order = initial(order) -//BASIC FUNCTIONS - if("Clear Screen") - temp = null - - if("Return") - screen = 1 - active1 = null - active2 = null - - if("Log Out") - authenticated = null - screen = null - active1 = null - active2 = null - playsound(src, 'sound/machines/terminal_off.ogg', 50, FALSE) - - if("Log In") - var/mob/M = usr - var/obj/item/card/id/I = M.get_idcard(TRUE) - if(issilicon(M)) - var/mob/living/silicon/borg = M - active1 = null - active2 = null - authenticated = borg.name - rank = "AI" - screen = 1 - else if(IsAdminGhost(M)) - active1 = null - active2 = null - authenticated = M.client.holder.admin_signature - rank = "Central Command" - screen = 1 - else if(I && check_access(I)) - active1 = null - active2 = null - authenticated = I.registered_name - rank = I.assignment - screen = 1 - else - to_chat(usr, "Unauthorized Access.") - playsound(src, 'sound/machines/terminal_on.ogg', 50, FALSE) - -//RECORD FUNCTIONS - if("Record Maintenance") - screen = 2 - active1 = null - active2 = null - - if("Browse Record") - var/datum/data/record/R = locate(href_list["d_rec"]) in GLOB.data_core.general - if(!R) - temp = "Record Not Found!" - else - active1 = active2 = R - for(var/datum/data/record/E in GLOB.data_core.security) - if((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - active2 = E - screen = 3 - - - if("Print Record") - if(!( printing )) - printing = 1 - GLOB.data_core.securityPrintCount++ - playsound(loc, 'sound/items/poster_being_created.ogg', 100, 1) - sleep(30) - var/obj/item/paper/P = new /obj/item/paper( loc ) - P.info = "
      Security Record - (SR-[GLOB.data_core.securityPrintCount])

      " - if((istype(active1, /datum/data/record) && GLOB.data_core.general.Find(active1))) - P.info += text("Name: [] ID: []
      \nGender: []
      \nAge: []
      ", active1.fields["name"], active1.fields["id"], active1.fields["gender"], active1.fields["age"]) - P.info += "\nSpecies: [active1.fields["species"]]
      " - P.info += text("\nFingerprint: []
      \nPhysical Status: []
      \nMental Status: []
      ", active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"]) - else - P.info += "General Record Lost!
      " - if((istype(active2, /datum/data/record) && GLOB.data_core.security.Find(active2))) - P.info += text("
      \n
      Security Data

      \nCriminal Status: []", active2.fields["criminal"]) - - P.info += "
      \n
      \nMinor Crimes:
      \n" - P.info +={" - - - - - -"} - for(var/datum/data/crime/c in active2.fields["mi_crim"]) - P.info += "" - P.info += "" - P.info += "" - P.info += "" - P.info += "" - P.info += "
      CrimeDetailsAuthorTime Added
      [c.crimeName][c.crimeDetails][c.author][c.time]
      " - - P.info += "
      \nMajor Crimes:
      \n" - P.info +={" - - - - - -"} - for(var/datum/data/crime/c in active2.fields["ma_crim"]) - P.info += "" - P.info += "" - P.info += "" - P.info += "" - P.info += "" - P.info += "
      CrimeDetailsAuthorTime Added
      [c.crimeName][c.crimeDetails][c.author][c.time]
      " - - - P.info += text("
      \nImportant Notes:
      \n\t[]
      \n
      \n
      Comments/Log

      ", active2.fields["notes"]) - var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - P.info += text("[]
      ", active2.fields[text("com_[]", counter)]) - counter++ - P.name = text("SR-[] '[]'", GLOB.data_core.securityPrintCount, active1.fields["name"]) - else - P.info += "Security Record Lost!
      " - P.name = text("SR-[] '[]'", GLOB.data_core.securityPrintCount, "Record Lost") - P.info += "
      " - P.update_icon() - printing = null - if("Print Poster") - if(!( printing )) - var/wanted_name = stripped_input(usr, "Please enter an alias for the criminal:", "Print Wanted Poster", active1.fields["name"]) - if(wanted_name) - var/default_description = "A poster declaring [wanted_name] to be a dangerous individual, wanted by Nanotrasen. Report any sightings to security immediately." - var/list/major_crimes = active2.fields["ma_crim"] - var/list/minor_crimes = active2.fields["mi_crim"] - if(major_crimes.len + minor_crimes.len) - default_description += "\n[wanted_name] is wanted for the following crimes:\n" - if(minor_crimes.len) - default_description += "\nMinor Crimes:" - for(var/datum/data/crime/c in active2.fields["mi_crim"]) - default_description += "\n[c.crimeName]\n" - default_description += "[c.crimeDetails]\n" - if(major_crimes.len) - default_description += "\nMajor Crimes:" - for(var/datum/data/crime/c in active2.fields["ma_crim"]) - default_description += "\n[c.crimeName]\n" - default_description += "[c.crimeDetails]\n" - - var/info = stripped_multiline_input(usr, "Please input a description for the poster:", "Print Wanted Poster", default_description, null) - if(info) - playsound(loc, 'sound/items/poster_being_created.ogg', 100, 1) - printing = 1 - sleep(30) - if((istype(active1, /datum/data/record) && GLOB.data_core.general.Find(active1)))//make sure the record still exists. - var/obj/item/photo/photo = active1.fields["photo_front"] - new /obj/item/poster/wanted(loc, photo.picture.picture_image, wanted_name, info) - printing = 0 - -//RECORD DELETE - if("Delete All Records") - temp = "" - temp += "Are you sure you wish to delete all Security records?
      " - temp += "Yes
      " - temp += "No" - - if("Purge All Records") - investigate_log("[key_name(usr)] has purged all the security records.", INVESTIGATE_RECORDS) - for(var/datum/data/record/R in GLOB.data_core.security) - qdel(R) - GLOB.data_core.security.Cut() - temp = "All Security records deleted." - - if("Add Entry") - if(!( istype(active2, /datum/data/record) )) - return - var/a2 = active2 - var/t1 = stripped_multiline_input("Add Comment:", "Secure. records", null, null) - if(!canUseSecurityRecordsConsole(usr, t1, null, a2)) - return - var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - counter++ - active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []
      []", src.authenticated, src.rank, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1) - - if("Delete Record (ALL)") - if(active1) - temp = "
      Are you sure you wish to delete the record (ALL)?
      " - temp += "Yes
      " - temp += "No" - - if("Delete Record (Security)") - if(active2) - temp = "
      Are you sure you wish to delete the record (Security Portion Only)?
      " - temp += "Yes
      " - temp += "No" - - if("Delete Entry") - if((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])])) - active2.fields[text("com_[]", href_list["del_c"])] = "Deleted" -//RECORD CREATE - if("New Record (Security)") - if((istype(active1, /datum/data/record) && !( istype(active2, /datum/data/record) ))) - var/datum/data/record/R = new /datum/data/record() - R.fields["name"] = active1.fields["name"] - R.fields["id"] = active1.fields["id"] - R.name = text("Security Record #[]", R.fields["id"]) - R.fields["criminal"] = "None" - R.fields["mi_crim"] = list() - R.fields["ma_crim"] = list() - R.fields["notes"] = "No notes." - GLOB.data_core.security += R - active2 = R - screen = 3 - - if("New Record (General)") - //General Record - var/datum/data/record/G = new /datum/data/record() - G.fields["name"] = "New Record" - G.fields["id"] = "[num2hex(rand(1, 1.6777215E7), 6)]" - G.fields["rank"] = "Unassigned" - G.fields["gender"] = "Male" - G.fields["age"] = "Unknown" - G.fields["species"] = "Human" - G.fields["photo_front"] = new /icon() - G.fields["photo_side"] = new /icon() - G.fields["fingerprint"] = "?????" - G.fields["p_stat"] = "Active" - G.fields["m_stat"] = "Stable" - GLOB.data_core.general += G - active1 = G - - //Security Record - var/datum/data/record/R = new /datum/data/record() - R.fields["name"] = active1.fields["name"] - R.fields["id"] = active1.fields["id"] - R.name = text("Security Record #[]", R.fields["id"]) - R.fields["criminal"] = "None" - R.fields["mi_crim"] = list() - R.fields["ma_crim"] = list() - R.fields["notes"] = "No notes." - GLOB.data_core.security += R - active2 = R - - //Medical Record - var/datum/data/record/M = new /datum/data/record() - M.fields["id"] = active1.fields["id"] - M.fields["name"] = active1.fields["name"] - M.fields["blood_type"] = "?" - M.fields["b_dna"] = "?????" - M.fields["mi_dis"] = "None" - M.fields["mi_dis_d"] = "No minor disabilities have been declared." - M.fields["ma_dis"] = "None" - M.fields["ma_dis_d"] = "No major disabilities have been diagnosed." - M.fields["alg"] = "None" - M.fields["alg_d"] = "No allergies have been detected in this patient." - M.fields["cdi"] = "None" - M.fields["cdi_d"] = "No diseases have been diagnosed at the moment." - M.fields["notes"] = "No notes." - GLOB.data_core.medical += M - - - -//FIELD FUNCTIONS - if("Edit Field") - var/a1 = active1 - var/a2 = active2 - - switch(href_list["field"]) - if("name") - if(istype(active1, /datum/data/record) || istype(active2, /datum/data/record)) - var/t1 = copytext(sanitize(input("Please input name:", "Secure. records", active1.fields["name"], null) as text),1,MAX_MESSAGE_LEN) - if(!canUseSecurityRecordsConsole(usr, t1, a1)) - return - if(istype(active1, /datum/data/record)) - active1.fields["name"] = t1 - if(istype(active2, /datum/data/record)) - active2.fields["name"] = t1 - if("id") - if(istype(active2, /datum/data/record) || istype(active1, /datum/data/record)) - var/t1 = stripped_input(usr, "Please input id:", "Secure. records", active1.fields["id"], null) - if(!canUseSecurityRecordsConsole(usr, t1, a1)) - return - if(istype(active1, /datum/data/record)) - active1.fields["id"] = t1 - if(istype(active2, /datum/data/record)) - active2.fields["id"] = t1 - if("fingerprint") - if(istype(active1, /datum/data/record)) - var/t1 = stripped_input(usr, "Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) - if(!canUseSecurityRecordsConsole(usr, t1, a1)) - return - active1.fields["fingerprint"] = t1 - if("gender") - if(istype(active1, /datum/data/record)) - if(active1.fields["gender"] == "Male") - active1.fields["gender"] = "Female" - else if(active1.fields["gender"] == "Female") - active1.fields["gender"] = "Other" - else - active1.fields["gender"] = "Male" - if("age") - if(istype(active1, /datum/data/record)) - var/t1 = input("Please input age:", "Secure. records", active1.fields["age"], null) as num - if(!canUseSecurityRecordsConsole(usr, "age", a1)) - return - active1.fields["age"] = t1 - if("species") - if(istype(active1, /datum/data/record)) - var/t1 = input("Select a species", "Species Selection") as null|anything in GLOB.roundstart_races - if(!canUseSecurityRecordsConsole(usr, t1, a1)) - return - active1.fields["species"] = t1 - if("show_photo_front") - if(active1.fields["photo_front"]) - if(istype(active1.fields["photo_front"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_front"] - P.show(usr) - if("upd_photo_front") - var/obj/item/photo/photo = get_photo(usr) - if(photo) - qdel(active1.fields["photo_front"]) - //Lets center it to a 32x32. - var/icon/I = photo.picture.picture_image - var/w = I.Width() - var/h = I.Height() - var/dw = w - 32 - var/dh = w - 32 - I.Crop(dw/2, dh/2, w - dw/2, h - dh/2) - active1.fields["photo_front"] = photo - if("print_photo_front") - if(active1.fields["photo_front"]) - if(istype(active1.fields["photo_front"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_front"] - print_photo(P.picture.picture_image, active1.fields["name"]) - if("show_photo_side") - if(active1.fields["photo_side"]) - if(istype(active1.fields["photo_side"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_side"] - P.show(usr) - if("upd_photo_side") - var/obj/item/photo/photo = get_photo(usr) - if(photo) - qdel(active1.fields["photo_side"]) - //Lets center it to a 32x32. - var/icon/I = photo.picture.picture_image - var/w = I.Width() - var/h = I.Height() - var/dw = w - 32 - var/dh = w - 32 - I.Crop(dw/2, dh/2, w - dw/2, h - dh/2) - active1.fields["photo_side"] = photo - if("print_photo_side") - if(active1.fields["photo_side"]) - if(istype(active1.fields["photo_side"], /obj/item/photo)) - var/obj/item/photo/P = active1.fields["photo_side"] - print_photo(P.picture.picture_image, active1.fields["name"]) - if("mi_crim_add") - if(istype(active1, /datum/data/record)) - var/t1 = stripped_input(usr, "Please input minor crime names:", "Secure. records", "", null) - var/t2 = stripped_input(usr, "Please input minor crime details:", "Secure. records", "", null) - if(!canUseSecurityRecordsConsole(usr, t1, null, a2)) - return - var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, STATION_TIME_TIMESTAMP("hh:mm:ss")) - GLOB.data_core.addMinorCrime(active1.fields["id"], crime) - investigate_log("New Minor Crime: [t1]: [t2] | Added to [active1.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS) - if("mi_crim_delete") - if(istype(active1, /datum/data/record)) - if(href_list["cdataid"]) - if(!canUseSecurityRecordsConsole(usr, "delete", null, a2)) - return - GLOB.data_core.removeMinorCrime(active1.fields["id"], href_list["cdataid"]) - if("ma_crim_add") - if(istype(active1, /datum/data/record)) - var/t1 = stripped_input(usr, "Please input major crime names:", "Secure. records", "", null) - var/t2 = stripped_input(usr, "Please input major crime details:", "Secure. records", "", null) - if(!canUseSecurityRecordsConsole(usr, t1, null, a2)) - return - var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, STATION_TIME_TIMESTAMP("hh:mm:ss")) - GLOB.data_core.addMajorCrime(active1.fields["id"], crime) - investigate_log("New Major Crime: [t1]: [t2] | Added to [active1.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS) - if("ma_crim_delete") - if(istype(active1, /datum/data/record)) - if(href_list["cdataid"]) - if(!canUseSecurityRecordsConsole(usr, "delete", null, a2)) - return - GLOB.data_core.removeMajorCrime(active1.fields["id"], href_list["cdataid"]) - if("notes") - if(istype(active2, /datum/data/record)) - var/t1 = stripped_input(usr, "Please summarize notes:", "Secure. records", active2.fields["notes"], null) - if(!canUseSecurityRecordsConsole(usr, t1, null, a2)) - return - active2.fields["notes"] = t1 - if("criminal") - if(istype(active2, /datum/data/record)) - temp = "
      Criminal Status:
      " - temp += "" - if("rank") - var/list/L = list( "Head of Personnel", "Captain", "AI", "Central Command" ) - //This was so silly before the change. Now it actually works without beating your head against the keyboard. /N - if((istype(active1, /datum/data/record) && L.Find(rank))) - temp = "
      Rank:
      " - temp += "
        " - for(var/rank in get_all_jobs()) - temp += "
      • [rank]
      • " - temp += "
      " - else - alert(usr, "You do not have the required rank to do this!") -//TEMPORARY MENU FUNCTIONS - else//To properly clear as per clear screen. - temp=null - switch(href_list["choice"]) - if("Change Rank") - if(active1) - active1.fields["rank"] = href_list["rank"] - if(href_list["rank"] in get_all_jobs()) - active1.fields["real_rank"] = href_list["real_rank"] - - if("Change Criminal Status") - if(active2) - var/old_field = active2.fields["criminal"] - switch(href_list["criminal2"]) - if("none") - active2.fields["criminal"] = "None" - if("arrest") - active2.fields["criminal"] = "*Arrest*" - if("incarcerated") - active2.fields["criminal"] = "Incarcerated" - if("paroled") - active2.fields["criminal"] = "Paroled" - if("released") - active2.fields["criminal"] = "Discharged" - investigate_log("[active1.fields["name"]] has been set from [old_field] to [active2.fields["criminal"]] by [key_name(usr)].", INVESTIGATE_RECORDS) - for(var/mob/living/carbon/human/H in GLOB.carbon_list) - H.sec_hud_set_security_status() - if("Delete Record (Security) Execute") - investigate_log("[key_name(usr)] has deleted the security records for [active1.fields["name"]].", INVESTIGATE_RECORDS) - if(active2) - qdel(active2) - active2 = null - - if("Delete Record (ALL) Execute") - if(active1) - investigate_log("[key_name(usr)] has deleted all records for [active1.fields["name"]].", INVESTIGATE_RECORDS) - for(var/datum/data/record/R in GLOB.data_core.medical) - if((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"])) - qdel(R) - break - qdel(active1) - active1 = null - - if(active2) - qdel(active2) - active2 = null - else - temp = "This function does not appear to be working at the moment. Our apologies." - - add_fingerprint(usr) - updateUsrDialog() - return - -/obj/machinery/computer/secure_data/proc/get_photo(mob/user) - var/obj/item/photo/P = null - if(issilicon(user)) - var/mob/living/silicon/tempAI = user - var/datum/picture/selection = tempAI.GetPhoto(user) - if(selection) - P = new(null, selection) - else if(istype(user.get_active_held_item(), /obj/item/photo)) - P = user.get_active_held_item() - return P - -/obj/machinery/computer/secure_data/proc/print_photo(icon/temp, person_name) - if (printing) - return - printing = TRUE - sleep(20) - var/obj/item/photo/P = new/obj/item/photo(drop_location()) - var/datum/picture/toEmbed = new(name = person_name, desc = "The photo on file for [person_name].", image = temp) - P.set_picture(toEmbed, TRUE, TRUE) - P.pixel_x = rand(-10, 10) - P.pixel_y = rand(-10, 10) - printing = FALSE - -/obj/machinery/computer/secure_data/emp_act(severity) - . = ..() - - if(stat & (BROKEN|NOPOWER) || . & EMP_PROTECT_SELF) - return - - for(var/datum/data/record/R in GLOB.data_core.security) - if(prob(10/severity)) - switch(rand(1,8)) - if(1) - if(prob(10)) - R.fields["name"] = "[pick(lizard_name(MALE),lizard_name(FEMALE))]" - else - R.fields["name"] = "[pick(pick(GLOB.first_names_male), pick(GLOB.first_names_female))] [pick(GLOB.last_names)]" - if(2) - R.fields["gender"] = pick("Male", "Female", "Other") - if(3) - R.fields["age"] = rand(5, 85) - if(4) - R.fields["criminal"] = pick("None", "*Arrest*", "Incarcerated", "Paroled", "Discharged") - if(5) - R.fields["p_stat"] = pick("*Unconscious*", "Active", "Physically Unfit") - if(6) - R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable") - if(7) - R.fields["species"] = pick(GLOB.roundstart_races) - if(8) - var/datum/data/record/G = pick(GLOB.data_core.general) - R.fields["photo_front"] = G.fields["photo_front"] - R.fields["photo_side"] = G.fields["photo_side"] - continue - - else if(prob(1)) - qdel(R) - continue - -/obj/machinery/computer/secure_data/proc/canUseSecurityRecordsConsole(mob/user, message1 = 0, record1, record2) - if(user) - if(authenticated) - if(user.canUseTopic(src, !issilicon(user))) - if(!trim(message1)) - return 0 - if(!record1 || record1 == active1) - if(!record2 || record2 == active2) - return 1 - return 0 - +/obj/machinery/computer/secure_data//TODO:SANITY + name = "security records console" + desc = "Used to view and edit personnel's security records." + icon_screen = "security" + icon_keyboard = "security_key" + req_one_access = list(ACCESS_SECURITY, ACCESS_FORENSICS_LOCKERS) + circuit = /obj/item/circuitboard/computer/secure_data + var/rank = null + var/screen = null + var/datum/data/record/active1 = null + var/datum/data/record/active2 = null + var/temp = null + var/printing = null + var/can_change_id = 0 + var/list/Perp + var/tempname = null + //Sorting Variables + var/sortBy = "name" + var/order = 1 // -1 = Descending - 1 = Ascending + + light_color = LIGHT_COLOR_RED + +/obj/machinery/computer/secure_data/syndie + icon_keyboard = "syndie_key" + +/obj/machinery/computer/secure_data/laptop + name = "security laptop" + desc = "A cheap Nanotrasen security laptop, it functions as a security records console. It's bolted to the table." + icon_state = "laptop" + icon_screen = "seclaptop" + icon_keyboard = "laptop_key" + clockwork = TRUE //it'd look weird + pass_flags = PASSTABLE + +//Someone needs to break down the dat += into chunks instead of long ass lines. +/obj/machinery/computer/secure_data/ui_interact(mob/user) + . = ..() + if(isliving(user)) + playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE) + if(src.z > 6) + to_chat(user, "Unable to establish a connection: \black You're too far away from the station!") + return + var/dat + + if(temp) + dat = "[temp]

      Clear Screen" + else + dat = "" + if(authenticated) + switch(screen) + if(1) + + //body tag start + onload and onkeypress (onkeyup) javascript event calls + dat += "" + //search bar javascript + dat += {" + + + + + + + + "} + dat += {" +

      "} + dat += "New Record
      " + //search bar + dat += {" + + + + +
      + Search: +
      + "} + dat += {" +

      + + + + +
      Records:
      + + + + + + + + + +"} + if(!isnull(GLOB.data_core.general)) + for(var/datum/data/record/R in sortRecord(GLOB.data_core.general, sortBy, order)) + var/crimstat = "" + for(var/datum/data/record/E in GLOB.data_core.security) + if((E.fields["name"] == R.fields["name"]) && (E.fields["id"] == R.fields["id"])) + crimstat = E.fields["criminal"] + var/background + switch(crimstat) + if("*Arrest*") + background = "'background-color:#990000;'" + if("Incarcerated") + background = "'background-color:#CD6500;'" + if("Paroled") + background = "'background-color:#CD6500;'" + if("Discharged") + background = "'background-color:#006699;'" + if("None") + background = "'background-color:#4F7529;'" + if("") + background = "''" //"'background-color:#FFFFFF;'" + crimstat = "No Record." + dat += "" + dat += text("", R.fields["name"], R.fields["id"], R.fields["rank"], R.fields["fingerprint"], R.fields["name"]) + dat += text("", R.fields["id"]) + dat += text("", R.fields["rank"]) + dat += text("", R.fields["fingerprint"]) + dat += text("", crimstat) + dat += {" +
      NameIDRankFingerprintsCriminal Status
      [][][][][]
      + +
      "} + dat += "Record Maintenance

      " + dat += "{Log Out}" + if(2) + dat += "Records Maintenance
      " + dat += "
      Delete All Records

      Back" + if(3) + dat += "Security Record
      " + if(istype(active1, /datum/data/record) && GLOB.data_core.general.Find(active1)) + if(istype(active1.fields["photo_front"], /obj/item/photo)) + var/obj/item/photo/P1 = active1.fields["photo_front"] + user << browse_rsc(P1.picture.picture_image, "photo_front") + if(istype(active1.fields["photo_side"], /obj/item/photo)) + var/obj/item/photo/P2 = active1.fields["photo_side"] + user << browse_rsc(P2.picture.picture_image, "photo_side") + dat += {" +
      + + + + "} + dat += "" + dat += {" + + + +
      Name: [active1.fields["name"]] 
      ID: [active1.fields["id"]] 
      Gender: [active1.fields["gender"]] 
      Age: [active1.fields["age"]] 
      Species: [active1.fields["species"]] 
      Rank: [active1.fields["rank"]] 
      Fingerprint: [active1.fields["fingerprint"]] 
      Physical Status: [active1.fields["p_stat"]] 
      Mental Status: [active1.fields["m_stat"]] 
      +

      + Print photo
      + Update front photo

      + Print photo
      + Update side photo
      +
      "} + else + dat += "
      General Record Lost!
      " + if((istype(active2, /datum/data/record) && GLOB.data_core.security.Find(active2))) + dat += "Security Data" + dat += "
      Criminal Status: [active2.fields["criminal"]]" + dat += "

      Minor Crimes: Add New" + + + dat +={" + + + + + + + "} + for(var/datum/data/crime/c in active2.fields["mi_crim"]) + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "
      CrimeDetailsAuthorTime AddedDel
      [c.crimeName][c.crimeDetails][c.author][c.time]\[X\]
      " + + + dat += "
      Major Crimes: Add New" + + dat +={" + + + + + + + "} + for(var/datum/data/crime/c in active2.fields["ma_crim"]) + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "" + dat += "
      CrimeDetailsAuthorTime AddedDel
      [c.crimeName][c.crimeDetails][c.author][c.time]\[X\]
      " + + dat += "
      \nImportant Notes:
      \n\t [active2.fields["notes"]] " + dat += "

      Comments/Log
      " + var/counter = 1 + while(active2.fields[text("com_[]", counter)]) + dat += (active2.fields[text("com_[]", counter)] + "
      ") + if(active2.fields[text("com_[]", counter)] != "Deleted") + dat += text("Delete Entry

      ", counter) + counter++ + dat += "Add Entry

      " + dat += "Delete Record (Security Only)
      " + else + dat += "Security Record Lost!
      " + dat += "New Security Record

      " + dat += "Delete Record (ALL)
      Print Record
      Print Wanted Poster
      Back

      " + dat += "{Log Out}" + else + else + dat += "{Log In}" + var/datum/browser/popup = new(user, "secure_rec", "Security Records Console", 600, 400) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + return + +/*Revised /N +I can't be bothered to look more of the actual code outside of switch but that probably needs revising too. +What a mess.*/ +/obj/machinery/computer/secure_data/Topic(href, href_list) + . = ..() + if(.) + return . + if(!( GLOB.data_core.general.Find(active1) )) + active1 = null + if(!( GLOB.data_core.security.Find(active2) )) + active2 = null + if(usr.contents.Find(src) || (in_range(src, usr) && isturf(loc)) || issilicon(usr) || IsAdminGhost(usr)) + usr.set_machine(src) + switch(href_list["choice"]) +// SORTING! + if("Sorting") + // Reverse the order if clicked twice + if(sortBy == href_list["sort"]) + if(order == 1) + order = -1 + else + order = 1 + else + // New sorting order! + sortBy = href_list["sort"] + order = initial(order) +//BASIC FUNCTIONS + if("Clear Screen") + temp = null + + if("Return") + screen = 1 + active1 = null + active2 = null + + if("Log Out") + authenticated = null + screen = null + active1 = null + active2 = null + playsound(src, 'sound/machines/terminal_off.ogg', 50, FALSE) + + if("Log In") + var/mob/M = usr + var/obj/item/card/id/I = M.get_idcard(TRUE) + if(issilicon(M)) + var/mob/living/silicon/borg = M + active1 = null + active2 = null + authenticated = borg.name + rank = "AI" + screen = 1 + else if(IsAdminGhost(M)) + active1 = null + active2 = null + authenticated = M.client.holder.admin_signature + rank = "Central Command" + screen = 1 + else if(I && check_access(I)) + active1 = null + active2 = null + authenticated = I.registered_name + rank = I.assignment + screen = 1 + else + to_chat(usr, "Unauthorized Access.") + playsound(src, 'sound/machines/terminal_on.ogg', 50, FALSE) + +//RECORD FUNCTIONS + if("Record Maintenance") + screen = 2 + active1 = null + active2 = null + + if("Browse Record") + var/datum/data/record/R = locate(href_list["d_rec"]) in GLOB.data_core.general + if(!R) + temp = "Record Not Found!" + else + active1 = active2 = R + for(var/datum/data/record/E in GLOB.data_core.security) + if((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) + active2 = E + screen = 3 + + + if("Print Record") + if(!( printing )) + printing = 1 + GLOB.data_core.securityPrintCount++ + playsound(loc, 'sound/items/poster_being_created.ogg', 100, 1) + sleep(30) + var/obj/item/paper/P = new /obj/item/paper( loc ) + P.info = "
      Security Record - (SR-[GLOB.data_core.securityPrintCount])

      " + if((istype(active1, /datum/data/record) && GLOB.data_core.general.Find(active1))) + P.info += text("Name: [] ID: []
      \nGender: []
      \nAge: []
      ", active1.fields["name"], active1.fields["id"], active1.fields["gender"], active1.fields["age"]) + P.info += "\nSpecies: [active1.fields["species"]]
      " + P.info += text("\nFingerprint: []
      \nPhysical Status: []
      \nMental Status: []
      ", active1.fields["fingerprint"], active1.fields["p_stat"], active1.fields["m_stat"]) + else + P.info += "General Record Lost!
      " + if((istype(active2, /datum/data/record) && GLOB.data_core.security.Find(active2))) + P.info += text("
      \n
      Security Data

      \nCriminal Status: []", active2.fields["criminal"]) + + P.info += "
      \n
      \nMinor Crimes:
      \n" + P.info +={" + + + + + +"} + for(var/datum/data/crime/c in active2.fields["mi_crim"]) + P.info += "" + P.info += "" + P.info += "" + P.info += "" + P.info += "" + P.info += "
      CrimeDetailsAuthorTime Added
      [c.crimeName][c.crimeDetails][c.author][c.time]
      " + + P.info += "
      \nMajor Crimes:
      \n" + P.info +={" + + + + + +"} + for(var/datum/data/crime/c in active2.fields["ma_crim"]) + P.info += "" + P.info += "" + P.info += "" + P.info += "" + P.info += "" + P.info += "
      CrimeDetailsAuthorTime Added
      [c.crimeName][c.crimeDetails][c.author][c.time]
      " + + + P.info += text("
      \nImportant Notes:
      \n\t[]
      \n
      \n
      Comments/Log

      ", active2.fields["notes"]) + var/counter = 1 + while(active2.fields[text("com_[]", counter)]) + P.info += text("[]
      ", active2.fields[text("com_[]", counter)]) + counter++ + P.name = text("SR-[] '[]'", GLOB.data_core.securityPrintCount, active1.fields["name"]) + else + P.info += "Security Record Lost!
      " + P.name = text("SR-[] '[]'", GLOB.data_core.securityPrintCount, "Record Lost") + P.info += "" + P.update_icon() + printing = null + if("Print Poster") + if(!( printing )) + var/wanted_name = stripped_input(usr, "Please enter an alias for the criminal:", "Print Wanted Poster", active1.fields["name"]) + if(wanted_name) + var/default_description = "A poster declaring [wanted_name] to be a dangerous individual, wanted by Nanotrasen. Report any sightings to security immediately." + var/list/major_crimes = active2.fields["ma_crim"] + var/list/minor_crimes = active2.fields["mi_crim"] + if(major_crimes.len + minor_crimes.len) + default_description += "\n[wanted_name] is wanted for the following crimes:\n" + if(minor_crimes.len) + default_description += "\nMinor Crimes:" + for(var/datum/data/crime/c in active2.fields["mi_crim"]) + default_description += "\n[c.crimeName]\n" + default_description += "[c.crimeDetails]\n" + if(major_crimes.len) + default_description += "\nMajor Crimes:" + for(var/datum/data/crime/c in active2.fields["ma_crim"]) + default_description += "\n[c.crimeName]\n" + default_description += "[c.crimeDetails]\n" + + var/info = stripped_multiline_input(usr, "Please input a description for the poster:", "Print Wanted Poster", default_description, null) + if(info) + playsound(loc, 'sound/items/poster_being_created.ogg', 100, 1) + printing = 1 + sleep(30) + if((istype(active1, /datum/data/record) && GLOB.data_core.general.Find(active1)))//make sure the record still exists. + var/obj/item/photo/photo = active1.fields["photo_front"] + new /obj/item/poster/wanted(loc, photo.picture.picture_image, wanted_name, info) + printing = 0 + +//RECORD DELETE + if("Delete All Records") + temp = "" + temp += "Are you sure you wish to delete all Security records?
      " + temp += "Yes
      " + temp += "No" + + if("Purge All Records") + investigate_log("[key_name(usr)] has purged all the security records.", INVESTIGATE_RECORDS) + for(var/datum/data/record/R in GLOB.data_core.security) + qdel(R) + GLOB.data_core.security.Cut() + temp = "All Security records deleted." + + if("Add Entry") + if(!( istype(active2, /datum/data/record) )) + return + var/a2 = active2 + var/t1 = stripped_multiline_input("Add Comment:", "Secure. records", null, null) + if(!canUseSecurityRecordsConsole(usr, t1, null, a2)) + return + var/counter = 1 + while(active2.fields[text("com_[]", counter)]) + counter++ + active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []
      []", src.authenticated, src.rank, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1) + + if("Delete Record (ALL)") + if(active1) + temp = "
      Are you sure you wish to delete the record (ALL)?
      " + temp += "Yes
      " + temp += "No" + + if("Delete Record (Security)") + if(active2) + temp = "
      Are you sure you wish to delete the record (Security Portion Only)?
      " + temp += "Yes
      " + temp += "No" + + if("Delete Entry") + if((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])])) + active2.fields[text("com_[]", href_list["del_c"])] = "Deleted" +//RECORD CREATE + if("New Record (Security)") + if((istype(active1, /datum/data/record) && !( istype(active2, /datum/data/record) ))) + var/datum/data/record/R = new /datum/data/record() + R.fields["name"] = active1.fields["name"] + R.fields["id"] = active1.fields["id"] + R.name = text("Security Record #[]", R.fields["id"]) + R.fields["criminal"] = "None" + R.fields["mi_crim"] = list() + R.fields["ma_crim"] = list() + R.fields["notes"] = "No notes." + GLOB.data_core.security += R + active2 = R + screen = 3 + + if("New Record (General)") + //General Record + var/datum/data/record/G = new /datum/data/record() + G.fields["name"] = "New Record" + G.fields["id"] = "[num2hex(rand(1, 1.6777215E7), 6)]" + G.fields["rank"] = "Unassigned" + G.fields["gender"] = "Male" + G.fields["age"] = "Unknown" + G.fields["species"] = "Human" + G.fields["photo_front"] = new /icon() + G.fields["photo_side"] = new /icon() + G.fields["fingerprint"] = "?????" + G.fields["p_stat"] = "Active" + G.fields["m_stat"] = "Stable" + GLOB.data_core.general += G + active1 = G + + //Security Record + var/datum/data/record/R = new /datum/data/record() + R.fields["name"] = active1.fields["name"] + R.fields["id"] = active1.fields["id"] + R.name = text("Security Record #[]", R.fields["id"]) + R.fields["criminal"] = "None" + R.fields["mi_crim"] = list() + R.fields["ma_crim"] = list() + R.fields["notes"] = "No notes." + GLOB.data_core.security += R + active2 = R + + //Medical Record + var/datum/data/record/M = new /datum/data/record() + M.fields["id"] = active1.fields["id"] + M.fields["name"] = active1.fields["name"] + M.fields["blood_type"] = "?" + M.fields["b_dna"] = "?????" + M.fields["mi_dis"] = "None" + M.fields["mi_dis_d"] = "No minor disabilities have been declared." + M.fields["ma_dis"] = "None" + M.fields["ma_dis_d"] = "No major disabilities have been diagnosed." + M.fields["alg"] = "None" + M.fields["alg_d"] = "No allergies have been detected in this patient." + M.fields["cdi"] = "None" + M.fields["cdi_d"] = "No diseases have been diagnosed at the moment." + M.fields["notes"] = "No notes." + GLOB.data_core.medical += M + + + +//FIELD FUNCTIONS + if("Edit Field") + var/a1 = active1 + var/a2 = active2 + + switch(href_list["field"]) + if("name") + if(istype(active1, /datum/data/record) || istype(active2, /datum/data/record)) + var/t1 = copytext(sanitize(input("Please input name:", "Secure. records", active1.fields["name"], null) as text),1,MAX_MESSAGE_LEN) + if(!canUseSecurityRecordsConsole(usr, t1, a1)) + return + if(istype(active1, /datum/data/record)) + active1.fields["name"] = t1 + if(istype(active2, /datum/data/record)) + active2.fields["name"] = t1 + if("id") + if(istype(active2, /datum/data/record) || istype(active1, /datum/data/record)) + var/t1 = stripped_input(usr, "Please input id:", "Secure. records", active1.fields["id"], null) + if(!canUseSecurityRecordsConsole(usr, t1, a1)) + return + if(istype(active1, /datum/data/record)) + active1.fields["id"] = t1 + if(istype(active2, /datum/data/record)) + active2.fields["id"] = t1 + if("fingerprint") + if(istype(active1, /datum/data/record)) + var/t1 = stripped_input(usr, "Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) + if(!canUseSecurityRecordsConsole(usr, t1, a1)) + return + active1.fields["fingerprint"] = t1 + if("gender") + if(istype(active1, /datum/data/record)) + if(active1.fields["gender"] == "Male") + active1.fields["gender"] = "Female" + else if(active1.fields["gender"] == "Female") + active1.fields["gender"] = "Other" + else + active1.fields["gender"] = "Male" + if("age") + if(istype(active1, /datum/data/record)) + var/t1 = input("Please input age:", "Secure. records", active1.fields["age"], null) as num + if(!canUseSecurityRecordsConsole(usr, "age", a1)) + return + active1.fields["age"] = t1 + if("species") + if(istype(active1, /datum/data/record)) + var/t1 = input("Select a species", "Species Selection") as null|anything in GLOB.roundstart_races + if(!canUseSecurityRecordsConsole(usr, t1, a1)) + return + active1.fields["species"] = t1 + if("show_photo_front") + if(active1.fields["photo_front"]) + if(istype(active1.fields["photo_front"], /obj/item/photo)) + var/obj/item/photo/P = active1.fields["photo_front"] + P.show(usr) + if("upd_photo_front") + var/obj/item/photo/photo = get_photo(usr) + if(photo) + qdel(active1.fields["photo_front"]) + //Lets center it to a 32x32. + var/icon/I = photo.picture.picture_image + var/w = I.Width() + var/h = I.Height() + var/dw = w - 32 + var/dh = w - 32 + I.Crop(dw/2, dh/2, w - dw/2, h - dh/2) + active1.fields["photo_front"] = photo + if("print_photo_front") + if(active1.fields["photo_front"]) + if(istype(active1.fields["photo_front"], /obj/item/photo)) + var/obj/item/photo/P = active1.fields["photo_front"] + print_photo(P.picture.picture_image, active1.fields["name"]) + if("show_photo_side") + if(active1.fields["photo_side"]) + if(istype(active1.fields["photo_side"], /obj/item/photo)) + var/obj/item/photo/P = active1.fields["photo_side"] + P.show(usr) + if("upd_photo_side") + var/obj/item/photo/photo = get_photo(usr) + if(photo) + qdel(active1.fields["photo_side"]) + //Lets center it to a 32x32. + var/icon/I = photo.picture.picture_image + var/w = I.Width() + var/h = I.Height() + var/dw = w - 32 + var/dh = w - 32 + I.Crop(dw/2, dh/2, w - dw/2, h - dh/2) + active1.fields["photo_side"] = photo + if("print_photo_side") + if(active1.fields["photo_side"]) + if(istype(active1.fields["photo_side"], /obj/item/photo)) + var/obj/item/photo/P = active1.fields["photo_side"] + print_photo(P.picture.picture_image, active1.fields["name"]) + if("mi_crim_add") + if(istype(active1, /datum/data/record)) + var/t1 = stripped_input(usr, "Please input minor crime names:", "Secure. records", "", null) + var/t2 = stripped_input(usr, "Please input minor crime details:", "Secure. records", "", null) + if(!canUseSecurityRecordsConsole(usr, t1, null, a2)) + return + var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, STATION_TIME_TIMESTAMP("hh:mm:ss")) + GLOB.data_core.addMinorCrime(active1.fields["id"], crime) + investigate_log("New Minor Crime: [t1]: [t2] | Added to [active1.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS) + if("mi_crim_delete") + if(istype(active1, /datum/data/record)) + if(href_list["cdataid"]) + if(!canUseSecurityRecordsConsole(usr, "delete", null, a2)) + return + GLOB.data_core.removeMinorCrime(active1.fields["id"], href_list["cdataid"]) + if("ma_crim_add") + if(istype(active1, /datum/data/record)) + var/t1 = stripped_input(usr, "Please input major crime names:", "Secure. records", "", null) + var/t2 = stripped_input(usr, "Please input major crime details:", "Secure. records", "", null) + if(!canUseSecurityRecordsConsole(usr, t1, null, a2)) + return + var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, STATION_TIME_TIMESTAMP("hh:mm:ss")) + GLOB.data_core.addMajorCrime(active1.fields["id"], crime) + investigate_log("New Major Crime: [t1]: [t2] | Added to [active1.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS) + if("ma_crim_delete") + if(istype(active1, /datum/data/record)) + if(href_list["cdataid"]) + if(!canUseSecurityRecordsConsole(usr, "delete", null, a2)) + return + GLOB.data_core.removeMajorCrime(active1.fields["id"], href_list["cdataid"]) + if("notes") + if(istype(active2, /datum/data/record)) + var/t1 = stripped_input(usr, "Please summarize notes:", "Secure. records", active2.fields["notes"], null) + if(!canUseSecurityRecordsConsole(usr, t1, null, a2)) + return + active2.fields["notes"] = t1 + if("criminal") + if(istype(active2, /datum/data/record)) + temp = "
      Criminal Status:
      " + temp += "" + if("rank") + var/list/L = list( "Head of Personnel", "Captain", "AI", "Central Command" ) + //This was so silly before the change. Now it actually works without beating your head against the keyboard. /N + if((istype(active1, /datum/data/record) && L.Find(rank))) + temp = "
      Rank:
      " + temp += "
        " + for(var/rank in get_all_jobs()) + temp += "
      • [rank]
      • " + temp += "
      " + else + alert(usr, "You do not have the required rank to do this!") +//TEMPORARY MENU FUNCTIONS + else//To properly clear as per clear screen. + temp=null + switch(href_list["choice"]) + if("Change Rank") + if(active1) + active1.fields["rank"] = href_list["rank"] + if(href_list["rank"] in get_all_jobs()) + active1.fields["real_rank"] = href_list["real_rank"] + + if("Change Criminal Status") + if(active2) + var/old_field = active2.fields["criminal"] + switch(href_list["criminal2"]) + if("none") + active2.fields["criminal"] = "None" + if("arrest") + active2.fields["criminal"] = "*Arrest*" + if("incarcerated") + active2.fields["criminal"] = "Incarcerated" + if("paroled") + active2.fields["criminal"] = "Paroled" + if("released") + active2.fields["criminal"] = "Discharged" + investigate_log("[active1.fields["name"]] has been set from [old_field] to [active2.fields["criminal"]] by [key_name(usr)].", INVESTIGATE_RECORDS) + for(var/mob/living/carbon/human/H in GLOB.carbon_list) + H.sec_hud_set_security_status() + if("Delete Record (Security) Execute") + investigate_log("[key_name(usr)] has deleted the security records for [active1.fields["name"]].", INVESTIGATE_RECORDS) + if(active2) + qdel(active2) + active2 = null + + if("Delete Record (ALL) Execute") + if(active1) + investigate_log("[key_name(usr)] has deleted all records for [active1.fields["name"]].", INVESTIGATE_RECORDS) + for(var/datum/data/record/R in GLOB.data_core.medical) + if((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"])) + qdel(R) + break + qdel(active1) + active1 = null + + if(active2) + qdel(active2) + active2 = null + else + temp = "This function does not appear to be working at the moment. Our apologies." + + add_fingerprint(usr) + updateUsrDialog() + return + +/obj/machinery/computer/secure_data/proc/get_photo(mob/user) + var/obj/item/photo/P = null + if(issilicon(user)) + var/mob/living/silicon/tempAI = user + var/datum/picture/selection = tempAI.GetPhoto(user) + if(selection) + P = new(null, selection) + else if(istype(user.get_active_held_item(), /obj/item/photo)) + P = user.get_active_held_item() + return P + +/obj/machinery/computer/secure_data/proc/print_photo(icon/temp, person_name) + if (printing) + return + printing = TRUE + sleep(20) + var/obj/item/photo/P = new/obj/item/photo(drop_location()) + var/datum/picture/toEmbed = new(name = person_name, desc = "The photo on file for [person_name].", image = temp) + P.set_picture(toEmbed, TRUE, TRUE) + P.pixel_x = rand(-10, 10) + P.pixel_y = rand(-10, 10) + printing = FALSE + +/obj/machinery/computer/secure_data/emp_act(severity) + . = ..() + + if(stat & (BROKEN|NOPOWER) || . & EMP_PROTECT_SELF) + return + + for(var/datum/data/record/R in GLOB.data_core.security) + if(prob(10/severity)) + switch(rand(1,8)) + if(1) + if(prob(10)) + R.fields["name"] = "[pick(lizard_name(MALE),lizard_name(FEMALE))]" + else + R.fields["name"] = "[pick(pick(GLOB.first_names_male), pick(GLOB.first_names_female))] [pick(GLOB.last_names)]" + if(2) + R.fields["gender"] = pick("Male", "Female", "Other") + if(3) + R.fields["age"] = rand(5, 85) + if(4) + R.fields["criminal"] = pick("None", "*Arrest*", "Incarcerated", "Paroled", "Discharged") + if(5) + R.fields["p_stat"] = pick("*Unconscious*", "Active", "Physically Unfit") + if(6) + R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable") + if(7) + R.fields["species"] = pick(GLOB.roundstart_races) + if(8) + var/datum/data/record/G = pick(GLOB.data_core.general) + R.fields["photo_front"] = G.fields["photo_front"] + R.fields["photo_side"] = G.fields["photo_side"] + continue + + else if(prob(1)) + qdel(R) + continue + +/obj/machinery/computer/secure_data/proc/canUseSecurityRecordsConsole(mob/user, message1 = 0, record1, record2) + if(user) + if(authenticated) + if(user.canUseTopic(src, !issilicon(user))) + if(!trim(message1)) + return 0 + if(!record1 || record1 == active1) + if(!record2 || record2 == active2) + return 1 + return 0 + diff --git a/code/game/machinery/computer/station_alert.dm b/code/game/machinery/computer/station_alert.dm index 36ba4b0c94..1b700fdf36 100644 --- a/code/game/machinery/computer/station_alert.dm +++ b/code/game/machinery/computer/station_alert.dm @@ -1,98 +1,98 @@ -/obj/machinery/computer/station_alert - name = "station alert console" - desc = "Used to access the station's automated alert system." - icon_screen = "alert:0" - icon_keyboard = "atmos_key" - circuit = /obj/item/circuitboard/computer/stationalert - var/alarms = list("Fire" = list(), "Atmosphere" = list(), "Power" = list()) - - light_color = LIGHT_COLOR_CYAN - -/obj/machinery/computer/station_alert/Initialize() - . = ..() - GLOB.alert_consoles += src - -/obj/machinery/computer/station_alert/Destroy() - GLOB.alert_consoles -= src - return ..() - -/obj/machinery/computer/station_alert/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, "station_alert", name, 300, 500, master_ui, state) - ui.open() - -/obj/machinery/computer/station_alert/ui_data(mob/user) - . = list() - - .["alarms"] = list() - for(var/class in alarms) - .["alarms"][class] = list() - for(var/area in alarms[class]) - .["alarms"][class] += area - -/obj/machinery/computer/station_alert/proc/triggerAlarm(class, area/A, O, obj/source) - if(source.z != z) - return - if(stat & (BROKEN)) - return - - var/list/L = alarms[class] - for(var/I in L) - if (I == A.name) - var/list/alarm = L[I] - var/list/sources = alarm[3] - if (!(source in sources)) - sources += source - return 1 - var/obj/machinery/camera/C = null - var/list/CL = null - if(O && islist(O)) - CL = O - if (CL.len == 1) - C = CL[1] - else if(O && istype(O, /obj/machinery/camera)) - C = O - L[A.name] = list(A, (C ? C : O), list(source)) - return 1 - - -/obj/machinery/computer/station_alert/proc/cancelAlarm(class, area/A, obj/origin) - if(stat & (BROKEN)) - return - var/list/L = alarms[class] - var/cleared = 0 - for (var/I in L) - if (I == A.name) - var/list/alarm = L[I] - var/list/srcs = alarm[3] - if (origin in srcs) - srcs -= origin - if (srcs.len == 0) - cleared = 1 - L -= I - return !cleared - -/obj/machinery/computer/station_alert/update_icon() - ..() - cut_overlays() - SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) - var/overlay_state = icon_screen - if(stat & (NOPOWER|BROKEN)) - add_overlay("[icon_keyboard]_off") - return - add_overlay(icon_keyboard) - var/active_alarms = FALSE - for(var/cat in alarms) - var/list/L = alarms[cat] - if(L.len) - active_alarms = TRUE - if(active_alarms) - overlay_state = "alert:2" - add_overlay("alert:2") - else - overlay_state = "alert:0" - add_overlay("alert:0") - SSvis_overlays.add_vis_overlay(src, icon, overlay_state, layer, plane, dir) - SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir, alpha=128) +/obj/machinery/computer/station_alert + name = "station alert console" + desc = "Used to access the station's automated alert system." + icon_screen = "alert:0" + icon_keyboard = "atmos_key" + circuit = /obj/item/circuitboard/computer/stationalert + var/alarms = list("Fire" = list(), "Atmosphere" = list(), "Power" = list()) + + light_color = LIGHT_COLOR_CYAN + +/obj/machinery/computer/station_alert/Initialize() + . = ..() + GLOB.alert_consoles += src + +/obj/machinery/computer/station_alert/Destroy() + GLOB.alert_consoles -= src + return ..() + +/obj/machinery/computer/station_alert/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, "station_alert", name, 300, 500, master_ui, state) + ui.open() + +/obj/machinery/computer/station_alert/ui_data(mob/user) + . = list() + + .["alarms"] = list() + for(var/class in alarms) + .["alarms"][class] = list() + for(var/area in alarms[class]) + .["alarms"][class] += area + +/obj/machinery/computer/station_alert/proc/triggerAlarm(class, area/A, O, obj/source) + if(source.z != z) + return + if(stat & (BROKEN)) + return + + var/list/L = alarms[class] + for(var/I in L) + if (I == A.name) + var/list/alarm = L[I] + var/list/sources = alarm[3] + if (!(source in sources)) + sources += source + return 1 + var/obj/machinery/camera/C = null + var/list/CL = null + if(O && islist(O)) + CL = O + if (CL.len == 1) + C = CL[1] + else if(O && istype(O, /obj/machinery/camera)) + C = O + L[A.name] = list(A, (C ? C : O), list(source)) + return 1 + + +/obj/machinery/computer/station_alert/proc/cancelAlarm(class, area/A, obj/origin) + if(stat & (BROKEN)) + return + var/list/L = alarms[class] + var/cleared = 0 + for (var/I in L) + if (I == A.name) + var/list/alarm = L[I] + var/list/srcs = alarm[3] + if (origin in srcs) + srcs -= origin + if (srcs.len == 0) + cleared = 1 + L -= I + return !cleared + +/obj/machinery/computer/station_alert/update_icon() + ..() + cut_overlays() + SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) + var/overlay_state = icon_screen + if(stat & (NOPOWER|BROKEN)) + add_overlay("[icon_keyboard]_off") + return + add_overlay(icon_keyboard) + var/active_alarms = FALSE + for(var/cat in alarms) + var/list/L = alarms[cat] + if(L.len) + active_alarms = TRUE + if(active_alarms) + overlay_state = "alert:2" + add_overlay("alert:2") + else + overlay_state = "alert:0" + add_overlay("alert:0") + SSvis_overlays.add_vis_overlay(src, icon, overlay_state, layer, plane, dir) + SSvis_overlays.add_vis_overlay(src, icon, overlay_state, ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir, alpha=128) diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm index 75e4a866f0..768faa8301 100644 --- a/code/game/machinery/computer/telecrystalconsoles.dm +++ b/code/game/machinery/computer/telecrystalconsoles.dm @@ -1,215 +1,215 @@ -#define NUKESCALINGMODIFIER 1 - -GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","Echo","Foxtrot","Zero", "Niner")) - -/obj/machinery/computer/telecrystals - name = "\improper telecrystal assignment station" - desc = "A device used to manage telecrystals during group operations. You shouldn't be looking at this particular one..." - icon_state = "tcstation" - icon_keyboard = "tcstation_key" - icon_screen = "syndie" - clockwork = TRUE //it'd look weird, at least if ratvar ever got there - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF - - light_color = LIGHT_COLOR_RED - -///////////////////////////////////////////// -/obj/machinery/computer/telecrystals/uplinker - name = "\improper telecrystal upload/receive station" - desc = "A device used to manage telecrystals during group operations. To use, simply insert your uplink. With your uplink installed \ - you can upload your telecrystals to the group's pool using the console, or be assigned additional telecrystals by your lieutenant." - var/obj/item/uplinkholder = null - var/obj/machinery/computer/telecrystals/boss/linkedboss = null - -/obj/machinery/computer/telecrystals/uplinker/Initialize() - . = ..() - - var/ID = pick_n_take(GLOB.possible_uplinker_IDs) - if(!ID) - ID = rand(1,999) - name = "[name] [ID]" - -/obj/machinery/computer/telecrystals/uplinker/attackby(obj/item/I, mob/user, params) - if(uplinkholder) - to_chat(user, "[src] already has an uplink in it.") - return - var/datum/component/uplink/hidden_uplink = I.GetComponent(/datum/component/uplink) - if(hidden_uplink) - if(!user.transferItemToLoc(I, src)) - return - uplinkholder = I - I.add_fingerprint(user) - update_icon() - updateUsrDialog() - else - to_chat(user, "[I] doesn't appear to be an uplink...") - -/obj/machinery/computer/telecrystals/uplinker/update_icon() - ..() - if(uplinkholder) - add_overlay("[initial(icon_state)]-closed") - -/obj/machinery/computer/telecrystals/uplinker/proc/ejectuplink() - if(uplinkholder) - uplinkholder.forceMove(drop_location()) - uplinkholder = null - update_icon() - -/obj/machinery/computer/telecrystals/uplinker/proc/donateTC(amt, addLog = 1) - if(uplinkholder && linkedboss) - var/datum/component/uplink/hidden_uplink = uplinkholder.GetComponent(/datum/component/uplink) - if(amt < 0) - linkedboss.storedcrystals += hidden_uplink.telecrystals - if(addLog) - linkedboss.logTransfer("[src] donated [hidden_uplink.telecrystals] telecrystals to [linkedboss].") - hidden_uplink.telecrystals = 0 - else if(amt <= hidden_uplink.telecrystals) - hidden_uplink.telecrystals -= amt - linkedboss.storedcrystals += amt - if(addLog) - linkedboss.logTransfer("[src] donated [amt] telecrystals to [linkedboss].") - -/obj/machinery/computer/telecrystals/uplinker/proc/giveTC(amt, addLog = 1) - if(uplinkholder && linkedboss) - var/datum/component/uplink/hidden_uplink = uplinkholder.GetComponent(/datum/component/uplink) - if(amt < 0) - hidden_uplink.telecrystals += linkedboss.storedcrystals - if(addLog) - linkedboss.logTransfer("[src] received [linkedboss.storedcrystals] telecrystals from [linkedboss].") - linkedboss.storedcrystals = 0 - else if(amt <= linkedboss.storedcrystals) - hidden_uplink.telecrystals += amt - linkedboss.storedcrystals -= amt - if(addLog) - linkedboss.logTransfer("[src] received [amt] telecrystals from [linkedboss].") - -/////// - -/obj/machinery/computer/telecrystals/uplinker/ui_interact(mob/user) - . = ..() - var/dat = "" - if(linkedboss) - dat += "[linkedboss] has [linkedboss.storedcrystals] telecrystals available for distribution.

      " - else - dat += "No linked management consoles detected. Scan for uplink stations using the management console.

      " - - if(uplinkholder) - var/datum/component/uplink/hidden_uplink = uplinkholder.GetComponent(/datum/component/uplink) - dat += "[hidden_uplink.telecrystals] telecrystals remain in this uplink.
      " - if(linkedboss) - dat += "Donate TC: 1 | 5 | All" - dat += "
      Eject Uplink" - - - var/datum/browser/popup = new(user, "computer", "Telecrystal Upload/Receive Station", 700, 500) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - -/obj/machinery/computer/telecrystals/uplinker/Topic(href, href_list) - if(..()) - return - - if(href_list["donate"]) - var/tcamt = text2num(href_list["donate"]) - donateTC(tcamt) - - if(href_list["eject"]) - ejectuplink() - - src.updateUsrDialog() - - -///////////////////////////////////////// -/obj/machinery/computer/telecrystals/boss - name = "team telecrystal management console" - desc = "A device used to manage telecrystals during group operations. To use, simply initialize the machine by scanning for nearby uplink stations. \ - Once the consoles are linked up, you can assign any telecrystals amongst your operatives; be they donated by your agents or rationed to the squad \ - based on the danger rating of the mission." - icon_state = "computer" - icon_screen = "tcboss" - icon_keyboard = "syndie_key" - var/virgin = 1 - var/scanrange = 10 - var/storedcrystals = 0 - var/list/TCstations = list() - var/list/transferlog = list() - -/obj/machinery/computer/telecrystals/boss/proc/logTransfer(logmessage) - transferlog += ("[STATION_TIME_TIMESTAMP("hh:mm:ss")] [logmessage]") - -/obj/machinery/computer/telecrystals/boss/proc/scanUplinkers() - for(var/obj/machinery/computer/telecrystals/uplinker/A in urange(scanrange, src.loc)) - if(!A.linkedboss) - TCstations += A - A.linkedboss = src - if(virgin) - getDangerous() - virgin = 0 - -/obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population. - var/list/nukeops = get_antag_minds(/datum/antagonist/nukeop) - var/danger = GLOB.joined_player_list.len - nukeops.len - danger = CEILING(danger, 10) - scaleTC(danger) - -/obj/machinery/computer/telecrystals/boss/proc/scaleTC(amt)//Its own proc, since it'll probably need a lot of tweaks for balance, use a fancier algorhithm, etc. - storedcrystals += amt * NUKESCALINGMODIFIER - -///////// - -/obj/machinery/computer/telecrystals/boss/ui_interact(mob/user) - . = ..() - var/dat = "" - dat += "Scan for TC stations.
      " - dat += "[storedcrystals] telecrystals are available for distribution.
      " - dat += "

      " - - - for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations) - dat += "[A.name] | " - if(A.uplinkholder) - var/datum/component/uplink/hidden_uplink = A.uplinkholder.GetComponent(/datum/component/uplink) - dat += "[hidden_uplink.telecrystals] telecrystals." - if(storedcrystals) - dat+= "
      Add TC: 1 | 5 | 10 | All" - dat += "
      " - - if(TCstations.len && storedcrystals) - dat += "

      Evenly distribute remaining TC.

      " - - - for(var/entry in transferlog) - dat += "[entry]
      " - - - var/datum/browser/popup = new(user, "computer", "Team Telecrystal Management Console", 700, 500) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - -/obj/machinery/computer/telecrystals/boss/Topic(href, href_list) - if(..()) - return - - if(href_list["scan"]) - scanUplinkers() - - if(href_list["give"]) - var/tcamt = text2num(href_list["give"]) - if(TCstations.len) // sanity - var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["target"]) in TCstations - A.giveTC(tcamt) - - if(href_list["distrib"]) - var/sanity = 0 - while(storedcrystals && sanity < 100) - for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations) - A.giveTC(1,0) - sanity++ - logTransfer("[src] evenly distributed telecrystals.") - - src.updateUsrDialog() - return - -#undef NUKESCALINGMODIFIER +#define NUKESCALINGMODIFIER 1 + +GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","Echo","Foxtrot","Zero", "Niner")) + +/obj/machinery/computer/telecrystals + name = "\improper telecrystal assignment station" + desc = "A device used to manage telecrystals during group operations. You shouldn't be looking at this particular one..." + icon_state = "tcstation" + icon_keyboard = "tcstation_key" + icon_screen = "syndie" + clockwork = TRUE //it'd look weird, at least if ratvar ever got there + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF + + light_color = LIGHT_COLOR_RED + +///////////////////////////////////////////// +/obj/machinery/computer/telecrystals/uplinker + name = "\improper telecrystal upload/receive station" + desc = "A device used to manage telecrystals during group operations. To use, simply insert your uplink. With your uplink installed \ + you can upload your telecrystals to the group's pool using the console, or be assigned additional telecrystals by your lieutenant." + var/obj/item/uplinkholder = null + var/obj/machinery/computer/telecrystals/boss/linkedboss = null + +/obj/machinery/computer/telecrystals/uplinker/Initialize() + . = ..() + + var/ID = pick_n_take(GLOB.possible_uplinker_IDs) + if(!ID) + ID = rand(1,999) + name = "[name] [ID]" + +/obj/machinery/computer/telecrystals/uplinker/attackby(obj/item/I, mob/user, params) + if(uplinkholder) + to_chat(user, "[src] already has an uplink in it.") + return + var/datum/component/uplink/hidden_uplink = I.GetComponent(/datum/component/uplink) + if(hidden_uplink) + if(!user.transferItemToLoc(I, src)) + return + uplinkholder = I + I.add_fingerprint(user) + update_icon() + updateUsrDialog() + else + to_chat(user, "[I] doesn't appear to be an uplink...") + +/obj/machinery/computer/telecrystals/uplinker/update_icon() + ..() + if(uplinkholder) + add_overlay("[initial(icon_state)]-closed") + +/obj/machinery/computer/telecrystals/uplinker/proc/ejectuplink() + if(uplinkholder) + uplinkholder.forceMove(drop_location()) + uplinkholder = null + update_icon() + +/obj/machinery/computer/telecrystals/uplinker/proc/donateTC(amt, addLog = 1) + if(uplinkholder && linkedboss) + var/datum/component/uplink/hidden_uplink = uplinkholder.GetComponent(/datum/component/uplink) + if(amt < 0) + linkedboss.storedcrystals += hidden_uplink.telecrystals + if(addLog) + linkedboss.logTransfer("[src] donated [hidden_uplink.telecrystals] telecrystals to [linkedboss].") + hidden_uplink.telecrystals = 0 + else if(amt <= hidden_uplink.telecrystals) + hidden_uplink.telecrystals -= amt + linkedboss.storedcrystals += amt + if(addLog) + linkedboss.logTransfer("[src] donated [amt] telecrystals to [linkedboss].") + +/obj/machinery/computer/telecrystals/uplinker/proc/giveTC(amt, addLog = 1) + if(uplinkholder && linkedboss) + var/datum/component/uplink/hidden_uplink = uplinkholder.GetComponent(/datum/component/uplink) + if(amt < 0) + hidden_uplink.telecrystals += linkedboss.storedcrystals + if(addLog) + linkedboss.logTransfer("[src] received [linkedboss.storedcrystals] telecrystals from [linkedboss].") + linkedboss.storedcrystals = 0 + else if(amt <= linkedboss.storedcrystals) + hidden_uplink.telecrystals += amt + linkedboss.storedcrystals -= amt + if(addLog) + linkedboss.logTransfer("[src] received [amt] telecrystals from [linkedboss].") + +/////// + +/obj/machinery/computer/telecrystals/uplinker/ui_interact(mob/user) + . = ..() + var/dat = "" + if(linkedboss) + dat += "[linkedboss] has [linkedboss.storedcrystals] telecrystals available for distribution.

      " + else + dat += "No linked management consoles detected. Scan for uplink stations using the management console.

      " + + if(uplinkholder) + var/datum/component/uplink/hidden_uplink = uplinkholder.GetComponent(/datum/component/uplink) + dat += "[hidden_uplink.telecrystals] telecrystals remain in this uplink.
      " + if(linkedboss) + dat += "Donate TC: 1 | 5 | All" + dat += "
      Eject Uplink" + + + var/datum/browser/popup = new(user, "computer", "Telecrystal Upload/Receive Station", 700, 500) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + +/obj/machinery/computer/telecrystals/uplinker/Topic(href, href_list) + if(..()) + return + + if(href_list["donate"]) + var/tcamt = text2num(href_list["donate"]) + donateTC(tcamt) + + if(href_list["eject"]) + ejectuplink() + + src.updateUsrDialog() + + +///////////////////////////////////////// +/obj/machinery/computer/telecrystals/boss + name = "team telecrystal management console" + desc = "A device used to manage telecrystals during group operations. To use, simply initialize the machine by scanning for nearby uplink stations. \ + Once the consoles are linked up, you can assign any telecrystals amongst your operatives; be they donated by your agents or rationed to the squad \ + based on the danger rating of the mission." + icon_state = "computer" + icon_screen = "tcboss" + icon_keyboard = "syndie_key" + var/virgin = 1 + var/scanrange = 10 + var/storedcrystals = 0 + var/list/TCstations = list() + var/list/transferlog = list() + +/obj/machinery/computer/telecrystals/boss/proc/logTransfer(logmessage) + transferlog += ("[STATION_TIME_TIMESTAMP("hh:mm:ss")] [logmessage]") + +/obj/machinery/computer/telecrystals/boss/proc/scanUplinkers() + for(var/obj/machinery/computer/telecrystals/uplinker/A in urange(scanrange, src.loc)) + if(!A.linkedboss) + TCstations += A + A.linkedboss = src + if(virgin) + getDangerous() + virgin = 0 + +/obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population. + var/list/nukeops = get_antag_minds(/datum/antagonist/nukeop) + var/danger = GLOB.joined_player_list.len - nukeops.len + danger = CEILING(danger, 10) + scaleTC(danger) + +/obj/machinery/computer/telecrystals/boss/proc/scaleTC(amt)//Its own proc, since it'll probably need a lot of tweaks for balance, use a fancier algorhithm, etc. + storedcrystals += amt * NUKESCALINGMODIFIER + +///////// + +/obj/machinery/computer/telecrystals/boss/ui_interact(mob/user) + . = ..() + var/dat = "" + dat += "Scan for TC stations.
      " + dat += "[storedcrystals] telecrystals are available for distribution.
      " + dat += "

      " + + + for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations) + dat += "[A.name] | " + if(A.uplinkholder) + var/datum/component/uplink/hidden_uplink = A.uplinkholder.GetComponent(/datum/component/uplink) + dat += "[hidden_uplink.telecrystals] telecrystals." + if(storedcrystals) + dat+= "
      Add TC: 1 | 5 | 10 | All" + dat += "
      " + + if(TCstations.len && storedcrystals) + dat += "

      Evenly distribute remaining TC.

      " + + + for(var/entry in transferlog) + dat += "[entry]
      " + + + var/datum/browser/popup = new(user, "computer", "Team Telecrystal Management Console", 700, 500) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + +/obj/machinery/computer/telecrystals/boss/Topic(href, href_list) + if(..()) + return + + if(href_list["scan"]) + scanUplinkers() + + if(href_list["give"]) + var/tcamt = text2num(href_list["give"]) + if(TCstations.len) // sanity + var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["target"]) in TCstations + A.giveTC(tcamt) + + if(href_list["distrib"]) + var/sanity = 0 + while(storedcrystals && sanity < 100) + for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations) + A.giveTC(1,0) + sanity++ + logTransfer("[src] evenly distributed telecrystals.") + + src.updateUsrDialog() + return + +#undef NUKESCALINGMODIFIER diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index 7a39e73ad3..96487915dd 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -1,279 +1,279 @@ -/obj/structure/frame - name = "frame" - icon = 'icons/obj/stock_parts.dmi' - icon_state = "box_0" - density = TRUE - max_integrity = 250 - var/obj/item/circuitboard/machine/circuit = null - var/state = 1 - -/obj/structure/frame/examine(user) - . = ..() - if(circuit) - . += "It has \a [circuit] installed." - - -/obj/structure/frame/deconstruct(disassembled = TRUE) - if(!(flags_1 & NODECONSTRUCT_1)) - new /obj/item/stack/sheet/metal(loc, 5) - if(circuit) - circuit.forceMove(loc) - circuit = null - qdel(src) - - -/obj/structure/frame/machine - name = "machine frame" - var/list/components = null - var/list/req_components = null - var/list/req_component_names = null // user-friendly names of components - -/obj/structure/frame/machine/examine(user) - . = ..() - if(state == 3 && req_components && req_component_names) - var/hasContent = 0 - var/requires = "It requires" - - for(var/i = 1 to req_components.len) - var/tname = req_components[i] - var/amt = req_components[tname] - if(amt == 0) - continue - var/use_and = i == req_components.len - requires += "[(hasContent ? (use_and ? ", and" : ",") : "")] [amt] [amt == 1 ? req_component_names[tname] : "[req_component_names[tname]]\s"]" - hasContent = 1 - - if(hasContent) - . += requires + "." - else - . += "It does not require any more components." - -/obj/structure/frame/machine/proc/update_namelist() - if(!req_components) - return - - req_component_names = new() - for(var/tname in req_components) - if(ispath(tname, /obj/item/stack)) - var/obj/item/stack/S = tname - var/singular_name = initial(S.singular_name) - if(singular_name) - req_component_names[tname] = singular_name - else - req_component_names[tname] = initial(S.name) - else - var/obj/O = tname - req_component_names[tname] = initial(O.name) - -/obj/structure/frame/machine/proc/get_req_components_amt() - var/amt = 0 - for(var/path in req_components) - amt += req_components[path] - return amt - -/obj/structure/frame/machine/attackby(obj/item/P, mob/user, params) - switch(state) - if(1) - if(istype(P, /obj/item/circuitboard/machine)) - to_chat(user, "The frame needs wiring first!") - return - else if(istype(P, /obj/item/circuitboard)) - to_chat(user, "This frame does not accept circuit boards of this type!") - return - if(istype(P, /obj/item/stack/cable_coil)) - if(!P.tool_start_check(user, amount=5)) - return - - to_chat(user, "You start to add cables to the frame...") - if(P.use_tool(src, user, 20, volume=50, amount=5)) - to_chat(user, "You add cables to the frame.") - state = 2 - icon_state = "box_1" - - return - if(istype(P, /obj/item/screwdriver) && !anchored) - user.visible_message("[user] disassembles the frame.", \ - "You start to disassemble the frame...", "You hear banging and clanking.") - if(P.use_tool(src, user, 40, volume=50)) - if(state == 1) - to_chat(user, "You disassemble the frame.") - var/obj/item/stack/sheet/metal/M = new (loc, 5) - M.add_fingerprint(user) - qdel(src) - return - if(istype(P, /obj/item/wrench)) - to_chat(user, "You start [anchored ? "un" : ""]securing [name]...") - if(P.use_tool(src, user, 40, volume=75)) - if(state == 1) - to_chat(user, "You [anchored ? "un" : ""]secure [name].") - setAnchored(!anchored) - return - - if(2) - if(istype(P, /obj/item/wrench)) - to_chat(user, "You start [anchored ? "un" : ""]securing [name]...") - if(P.use_tool(src, user, 40, volume=75)) - to_chat(user, "You [anchored ? "un" : ""]secure [name].") - setAnchored(!anchored) - return - - if(istype(P, /obj/item/circuitboard/machine)) - var/obj/item/circuitboard/machine/B = P - if(!anchored && B.needs_anchored) - to_chat(user, "The frame needs to be secured first!") - return - if(!user.transferItemToLoc(B, src)) - return - playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) - to_chat(user, "You add the circuit board to the frame.") - circuit = B - icon_state = "box_2" - state = 3 - components = list() - req_components = B.req_components.Copy() - update_namelist() - return - - else if(istype(P, /obj/item/circuitboard)) - to_chat(user, "This frame does not accept circuit boards of this type!") - return - - if(istype(P, /obj/item/wirecutters)) - P.play_tool_sound(src) - to_chat(user, "You remove the cables.") - state = 1 - icon_state = "box_0" - new /obj/item/stack/cable_coil(drop_location(), 5) - return - - if(3) - if(istype(P, /obj/item/crowbar)) - P.play_tool_sound(src) - state = 2 - circuit.forceMove(drop_location()) - components.Remove(circuit) - circuit = null - if(components.len == 0) - to_chat(user, "You remove the circuit board.") - else - to_chat(user, "You remove the circuit board and other components.") - for(var/atom/movable/AM in components) - AM.forceMove(drop_location()) - desc = initial(desc) - req_components = null - components = null - icon_state = "box_1" - return - - if(istype(P, /obj/item/wrench) && !circuit.needs_anchored) - to_chat(user, "You start [anchored ? "un" : ""]securing [name]...") - if(P.use_tool(src, user, 40, volume=75)) - to_chat(user, "You [anchored ? "un" : ""]secure [name].") - setAnchored(!anchored) - return - - if(istype(P, /obj/item/screwdriver)) - var/component_check = 1 - for(var/R in req_components) - if(req_components[R] > 0) - component_check = 0 - break - if(component_check) - P.play_tool_sound(src) - var/obj/machinery/new_machine = new circuit.build_path(loc) - new_machine.setAnchored(anchored) - new_machine.on_construction() - for(var/obj/O in new_machine.component_parts) - qdel(O) - new_machine.component_parts = list() - for(var/obj/O in src) - O.moveToNullspace() - new_machine.component_parts += O - if(new_machine.circuit) - QDEL_NULL(new_machine.circuit) - new_machine.circuit = circuit - circuit.moveToNullspace() - new_machine.RefreshParts() - qdel(src) - return - - if(istype(P, /obj/item/storage/part_replacer) && P.contents.len && get_req_components_amt()) - var/obj/item/storage/part_replacer/replacer = P - var/list/added_components = list() - var/list/part_list = list() - - //Assemble a list of current parts, then sort them by their rating! - for(var/obj/item/co in replacer) - part_list += co - //Sort the parts. This ensures that higher tier items are applied first. - part_list = sortTim(part_list, /proc/cmp_rped_sort) - - for(var/path in req_components) - while(req_components[path] > 0 && (locate(path) in part_list)) - var/obj/item/part = (locate(path) in part_list) - part_list -= part - if(istype(part,/obj/item/stack)) - var/obj/item/stack/S = part - var/used_amt = min(round(S.get_amount()), req_components[path]) - if(!used_amt || !S.use(used_amt)) - continue - var/NS = new S.merge_type(src, used_amt) - added_components[NS] = path - req_components[path] -= used_amt - else - added_components[part] = path - if(SEND_SIGNAL(replacer, COMSIG_TRY_STORAGE_TAKE, part, src)) - req_components[path]-- - - for(var/obj/item/part in added_components) - if(istype(part,/obj/item/stack)) - var/obj/item/stack/S = part - var/obj/item/stack/NS = locate(S.merge_type) in components //find a stack to merge with - if(NS) - S.merge(NS) - if(!QDELETED(part)) //If we're a stack and we merged we might not exist anymore - components += part - to_chat(user, "[part.name] applied.") - if(added_components.len) - replacer.play_rped_sound() - return - - if(isitem(P) && get_req_components_amt()) - for(var/I in req_components) - if(istype(P, I) && (req_components[I] > 0)) - if(istype(P, /obj/item/stack)) - var/obj/item/stack/S = P - var/used_amt = min(round(S.get_amount()), req_components[I]) - - if(used_amt && S.use(used_amt)) - var/obj/item/stack/NS = locate(S.merge_type) in components - - if(!NS) - NS = new S.merge_type(src, used_amt) - components += NS - else - NS.add(used_amt) - - req_components[I] -= used_amt - to_chat(user, "You add [P] to [src].") - return - if(!user.transferItemToLoc(P, src)) - break - to_chat(user, "You add [P] to [src].") - components += P - req_components[I]-- - return 1 - to_chat(user, "You cannot add that to the machine!") - return 0 - if(user.a_intent == INTENT_HARM) - return ..() - -/obj/structure/frame/machine/deconstruct(disassembled = TRUE) - if(!(flags_1 & NODECONSTRUCT_1)) - if(state >= 2) - new /obj/item/stack/cable_coil(loc , 5) - for(var/X in components) - var/obj/item/I = X - I.forceMove(loc) - - ..() +/obj/structure/frame + name = "frame" + icon = 'icons/obj/stock_parts.dmi' + icon_state = "box_0" + density = TRUE + max_integrity = 250 + var/obj/item/circuitboard/machine/circuit = null + var/state = 1 + +/obj/structure/frame/examine(user) + . = ..() + if(circuit) + . += "It has \a [circuit] installed." + + +/obj/structure/frame/deconstruct(disassembled = TRUE) + if(!(flags_1 & NODECONSTRUCT_1)) + new /obj/item/stack/sheet/metal(loc, 5) + if(circuit) + circuit.forceMove(loc) + circuit = null + qdel(src) + + +/obj/structure/frame/machine + name = "machine frame" + var/list/components = null + var/list/req_components = null + var/list/req_component_names = null // user-friendly names of components + +/obj/structure/frame/machine/examine(user) + . = ..() + if(state == 3 && req_components && req_component_names) + var/hasContent = 0 + var/requires = "It requires" + + for(var/i = 1 to req_components.len) + var/tname = req_components[i] + var/amt = req_components[tname] + if(amt == 0) + continue + var/use_and = i == req_components.len + requires += "[(hasContent ? (use_and ? ", and" : ",") : "")] [amt] [amt == 1 ? req_component_names[tname] : "[req_component_names[tname]]\s"]" + hasContent = 1 + + if(hasContent) + . += requires + "." + else + . += "It does not require any more components." + +/obj/structure/frame/machine/proc/update_namelist() + if(!req_components) + return + + req_component_names = new() + for(var/tname in req_components) + if(ispath(tname, /obj/item/stack)) + var/obj/item/stack/S = tname + var/singular_name = initial(S.singular_name) + if(singular_name) + req_component_names[tname] = singular_name + else + req_component_names[tname] = initial(S.name) + else + var/obj/O = tname + req_component_names[tname] = initial(O.name) + +/obj/structure/frame/machine/proc/get_req_components_amt() + var/amt = 0 + for(var/path in req_components) + amt += req_components[path] + return amt + +/obj/structure/frame/machine/attackby(obj/item/P, mob/user, params) + switch(state) + if(1) + if(istype(P, /obj/item/circuitboard/machine)) + to_chat(user, "The frame needs wiring first!") + return + else if(istype(P, /obj/item/circuitboard)) + to_chat(user, "This frame does not accept circuit boards of this type!") + return + if(istype(P, /obj/item/stack/cable_coil)) + if(!P.tool_start_check(user, amount=5)) + return + + to_chat(user, "You start to add cables to the frame...") + if(P.use_tool(src, user, 20, volume=50, amount=5)) + to_chat(user, "You add cables to the frame.") + state = 2 + icon_state = "box_1" + + return + if(istype(P, /obj/item/screwdriver) && !anchored) + user.visible_message("[user] disassembles the frame.", \ + "You start to disassemble the frame...", "You hear banging and clanking.") + if(P.use_tool(src, user, 40, volume=50)) + if(state == 1) + to_chat(user, "You disassemble the frame.") + var/obj/item/stack/sheet/metal/M = new (loc, 5) + M.add_fingerprint(user) + qdel(src) + return + if(istype(P, /obj/item/wrench)) + to_chat(user, "You start [anchored ? "un" : ""]securing [name]...") + if(P.use_tool(src, user, 40, volume=75)) + if(state == 1) + to_chat(user, "You [anchored ? "un" : ""]secure [name].") + setAnchored(!anchored) + return + + if(2) + if(istype(P, /obj/item/wrench)) + to_chat(user, "You start [anchored ? "un" : ""]securing [name]...") + if(P.use_tool(src, user, 40, volume=75)) + to_chat(user, "You [anchored ? "un" : ""]secure [name].") + setAnchored(!anchored) + return + + if(istype(P, /obj/item/circuitboard/machine)) + var/obj/item/circuitboard/machine/B = P + if(!anchored && B.needs_anchored) + to_chat(user, "The frame needs to be secured first!") + return + if(!user.transferItemToLoc(B, src)) + return + playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1) + to_chat(user, "You add the circuit board to the frame.") + circuit = B + icon_state = "box_2" + state = 3 + components = list() + req_components = B.req_components.Copy() + update_namelist() + return + + else if(istype(P, /obj/item/circuitboard)) + to_chat(user, "This frame does not accept circuit boards of this type!") + return + + if(istype(P, /obj/item/wirecutters)) + P.play_tool_sound(src) + to_chat(user, "You remove the cables.") + state = 1 + icon_state = "box_0" + new /obj/item/stack/cable_coil(drop_location(), 5) + return + + if(3) + if(istype(P, /obj/item/crowbar)) + P.play_tool_sound(src) + state = 2 + circuit.forceMove(drop_location()) + components.Remove(circuit) + circuit = null + if(components.len == 0) + to_chat(user, "You remove the circuit board.") + else + to_chat(user, "You remove the circuit board and other components.") + for(var/atom/movable/AM in components) + AM.forceMove(drop_location()) + desc = initial(desc) + req_components = null + components = null + icon_state = "box_1" + return + + if(istype(P, /obj/item/wrench) && !circuit.needs_anchored) + to_chat(user, "You start [anchored ? "un" : ""]securing [name]...") + if(P.use_tool(src, user, 40, volume=75)) + to_chat(user, "You [anchored ? "un" : ""]secure [name].") + setAnchored(!anchored) + return + + if(istype(P, /obj/item/screwdriver)) + var/component_check = 1 + for(var/R in req_components) + if(req_components[R] > 0) + component_check = 0 + break + if(component_check) + P.play_tool_sound(src) + var/obj/machinery/new_machine = new circuit.build_path(loc) + new_machine.setAnchored(anchored) + new_machine.on_construction() + for(var/obj/O in new_machine.component_parts) + qdel(O) + new_machine.component_parts = list() + for(var/obj/O in src) + O.moveToNullspace() + new_machine.component_parts += O + if(new_machine.circuit) + QDEL_NULL(new_machine.circuit) + new_machine.circuit = circuit + circuit.moveToNullspace() + new_machine.RefreshParts() + qdel(src) + return + + if(istype(P, /obj/item/storage/part_replacer) && P.contents.len && get_req_components_amt()) + var/obj/item/storage/part_replacer/replacer = P + var/list/added_components = list() + var/list/part_list = list() + + //Assemble a list of current parts, then sort them by their rating! + for(var/obj/item/co in replacer) + part_list += co + //Sort the parts. This ensures that higher tier items are applied first. + part_list = sortTim(part_list, /proc/cmp_rped_sort) + + for(var/path in req_components) + while(req_components[path] > 0 && (locate(path) in part_list)) + var/obj/item/part = (locate(path) in part_list) + part_list -= part + if(istype(part,/obj/item/stack)) + var/obj/item/stack/S = part + var/used_amt = min(round(S.get_amount()), req_components[path]) + if(!used_amt || !S.use(used_amt)) + continue + var/NS = new S.merge_type(src, used_amt) + added_components[NS] = path + req_components[path] -= used_amt + else + added_components[part] = path + if(SEND_SIGNAL(replacer, COMSIG_TRY_STORAGE_TAKE, part, src)) + req_components[path]-- + + for(var/obj/item/part in added_components) + if(istype(part,/obj/item/stack)) + var/obj/item/stack/S = part + var/obj/item/stack/NS = locate(S.merge_type) in components //find a stack to merge with + if(NS) + S.merge(NS) + if(!QDELETED(part)) //If we're a stack and we merged we might not exist anymore + components += part + to_chat(user, "[part.name] applied.") + if(added_components.len) + replacer.play_rped_sound() + return + + if(isitem(P) && get_req_components_amt()) + for(var/I in req_components) + if(istype(P, I) && (req_components[I] > 0)) + if(istype(P, /obj/item/stack)) + var/obj/item/stack/S = P + var/used_amt = min(round(S.get_amount()), req_components[I]) + + if(used_amt && S.use(used_amt)) + var/obj/item/stack/NS = locate(S.merge_type) in components + + if(!NS) + NS = new S.merge_type(src, used_amt) + components += NS + else + NS.add(used_amt) + + req_components[I] -= used_amt + to_chat(user, "You add [P] to [src].") + return + if(!user.transferItemToLoc(P, src)) + break + to_chat(user, "You add [P] to [src].") + components += P + req_components[I]-- + return 1 + to_chat(user, "You cannot add that to the machine!") + return 0 + if(user.a_intent == INTENT_HARM) + return ..() + +/obj/structure/frame/machine/deconstruct(disassembled = TRUE) + if(!(flags_1 & NODECONSTRUCT_1)) + if(state >= 2) + new /obj/item/stack/cable_coil(loc , 5) + for(var/X in components) + var/obj/item/I = X + I.forceMove(loc) + + ..() diff --git a/code/game/machinery/doors/alarmlock.dm b/code/game/machinery/doors/alarmlock.dm index cf46e6b0fd..42649a9ff2 100644 --- a/code/game/machinery/doors/alarmlock.dm +++ b/code/game/machinery/doors/alarmlock.dm @@ -1,43 +1,43 @@ -/obj/machinery/door/airlock/alarmlock - name = "glass alarm airlock" - icon = 'icons/obj/doors/airlocks/station2/glass.dmi' - overlays_file = 'icons/obj/doors/airlocks/station2/overlays.dmi' - opacity = 0 - assemblytype = /obj/structure/door_assembly/door_assembly_public - glass = TRUE - - var/datum/radio_frequency/air_connection - var/air_frequency = FREQ_ATMOS_ALARMS - autoclose = FALSE - -/obj/machinery/door/airlock/alarmlock/Initialize() - . = ..() - air_connection = new - -/obj/machinery/door/airlock/alarmlock/Destroy() - SSradio.remove_object(src,air_frequency) - air_connection = null - return ..() - -/obj/machinery/door/airlock/alarmlock/Initialize() - . = ..() - SSradio.remove_object(src, air_frequency) - air_connection = SSradio.add_object(src, air_frequency, RADIO_TO_AIRALARM) - open() - -/obj/machinery/door/airlock/alarmlock/receive_signal(datum/signal/signal) - ..() - if(stat & (NOPOWER|BROKEN)) - return - - var/alarm_area = signal.data["zone"] - var/alert = signal.data["alert"] - - if(alarm_area == get_area_name(src)) - switch(alert) - if("severe") - autoclose = TRUE - close() - if("minor", "clear") - autoclose = FALSE +/obj/machinery/door/airlock/alarmlock + name = "glass alarm airlock" + icon = 'icons/obj/doors/airlocks/station2/glass.dmi' + overlays_file = 'icons/obj/doors/airlocks/station2/overlays.dmi' + opacity = 0 + assemblytype = /obj/structure/door_assembly/door_assembly_public + glass = TRUE + + var/datum/radio_frequency/air_connection + var/air_frequency = FREQ_ATMOS_ALARMS + autoclose = FALSE + +/obj/machinery/door/airlock/alarmlock/Initialize() + . = ..() + air_connection = new + +/obj/machinery/door/airlock/alarmlock/Destroy() + SSradio.remove_object(src,air_frequency) + air_connection = null + return ..() + +/obj/machinery/door/airlock/alarmlock/Initialize() + . = ..() + SSradio.remove_object(src, air_frequency) + air_connection = SSradio.add_object(src, air_frequency, RADIO_TO_AIRALARM) + open() + +/obj/machinery/door/airlock/alarmlock/receive_signal(datum/signal/signal) + ..() + if(stat & (NOPOWER|BROKEN)) + return + + var/alarm_area = signal.data["zone"] + var/alert = signal.data["alert"] + + if(alarm_area == get_area_name(src)) + switch(alert) + if("severe") + autoclose = TRUE + close() + if("minor", "clear") + autoclose = FALSE open() \ No newline at end of file diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index 5c8cd4ffb8..beaf47d0a3 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -1,256 +1,256 @@ -#define CHARS_PER_LINE 5 -#define FONT_SIZE "5pt" -#define FONT_COLOR "#09f" -#define FONT_STYLE "Arial Black" -#define MAX_TIMER 9000 - -#define PRESET_SHORT 1200 -#define PRESET_MEDIUM 1800 -#define PRESET_LONG 3000 - - - -/////////////////////////////////////////////////////////////////////////////////////////////// -// Brig Door control displays. -// Description: This is a controls the timer for the brig doors, displays the timer on itself and -// has a popup window when used, allowing to set the timer. -// Code Notes: Combination of old brigdoor.dm code from rev4407 and the status_display.dm code -// Date: 01/September/2010 -// Programmer: Veryinky -///////////////////////////////////////////////////////////////////////////////////////////////// -/obj/machinery/door_timer - name = "door timer" - icon = 'icons/obj/status_display.dmi' - icon_state = "frame" - desc = "A remote control for a door." - req_access = list(ACCESS_SECURITY) - density = FALSE - var/id = null // id of linked machinery/lockers - - var/activation_time = 0 - var/timer_duration = 0 - - var/timing = FALSE // boolean, true/1 timer is on, false/0 means it's not timing - var/list/obj/machinery/targets = list() - var/obj/item/radio/Radio //needed to send messages to sec radio - - maptext_height = 26 - maptext_width = 32 - -/obj/machinery/door_timer/Initialize() - . = ..() - - Radio = new/obj/item/radio(src) - Radio.listening = 0 - -/obj/machinery/door_timer/Initialize() - . = ..() - if(id != null) - for(var/obj/machinery/door/window/brigdoor/M in urange(20, src)) - if (M.id == id) - targets += M - - for(var/obj/machinery/flasher/F in urange(20, src)) - if(F.id == id) - targets += F - - for(var/obj/structure/closet/secure_closet/brig/C in urange(20, src)) - if(C.id == id) - targets += C - - if(!targets.len) - stat |= BROKEN - update_icon() - - -//Main door timer loop, if it's timing and time is >0 reduce time by 1. -// if it's less than 0, open door, reset timer -// update the door_timer window and the icon -/obj/machinery/door_timer/process() - if(stat & (NOPOWER|BROKEN)) - return - - if(timing) - if(world.realtime - activation_time >= timer_duration) - timer_end() // open doors, reset timer, clear status screen - update_icon() - -// has the door power sitatuation changed, if so update icon. -/obj/machinery/door_timer/power_change() - ..() - update_icon() - - -// open/closedoor checks if door_timer has power, if so it checks if the -// linked door is open/closed (by density) then opens it/closes it. -/obj/machinery/door_timer/proc/timer_start() - if(stat & (NOPOWER|BROKEN)) - return 0 - - activation_time = world.realtime - timing = TRUE - - for(var/obj/machinery/door/window/brigdoor/door in targets) - if(door.density) - continue - INVOKE_ASYNC(door, /obj/machinery/door/window/brigdoor.proc/close) - - for(var/obj/structure/closet/secure_closet/brig/C in targets) - if(C.broken) - continue - if(C.opened && !C.close()) - continue - C.locked = TRUE - C.update_icon() - return 1 - - -/obj/machinery/door_timer/proc/timer_end(forced = FALSE) - - if(stat & (NOPOWER|BROKEN)) - return 0 - - if(!forced) - Radio.set_frequency(FREQ_SECURITY) - Radio.talk_into(src, "Timer has expired. Releasing prisoner.", FREQ_SECURITY) - - timing = FALSE - activation_time = null - set_timer(0) - update_icon() - - for(var/obj/machinery/door/window/brigdoor/door in targets) - if(!door.density) - continue - INVOKE_ASYNC(door, /obj/machinery/door/window/brigdoor.proc/open) - - for(var/obj/structure/closet/secure_closet/brig/C in targets) - if(C.broken) - continue - if(C.opened) - continue - C.locked = FALSE - C.update_icon() - - return 1 - - -/obj/machinery/door_timer/proc/time_left(seconds = FALSE) - . = max(0,timer_duration - (activation_time ? world.realtime - activation_time : 0)) - if(seconds) - . /= 10 - -/obj/machinery/door_timer/proc/set_timer(value) - var/new_time = CLAMP(value,0,MAX_TIMER) - . = new_time == timer_duration //return 1 on no change - timer_duration = new_time - -/obj/machinery/door_timer/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, "brig_timer", name, 300, 200, master_ui, state) - ui.open() - -//icon update function -// if NOPOWER, display blank -// if BROKEN, display blue screen of death icon AI uses -// if timing=true, run update display function -/obj/machinery/door_timer/update_icon() - if(stat & (NOPOWER)) - icon_state = "frame" - return - - if(stat & (BROKEN)) - set_picture("ai_bsod") - return - - if(timing) - var/disp1 = id - var/time_left = time_left(seconds = TRUE) - var/disp2 = "[add_zero(num2text((time_left / 60) % 60),2)]~[add_zero(num2text(time_left % 60), 2)]" - if(length(disp2) > CHARS_PER_LINE) - disp2 = "Error" - update_display(disp1, disp2) - else - if(maptext) - maptext = "" - return - - -// Adds an icon in case the screen is broken/off, stolen from status_display.dm -/obj/machinery/door_timer/proc/set_picture(state) - if(maptext) - maptext = "" - cut_overlays() - add_overlay(mutable_appearance('icons/obj/status_display.dmi', state)) - - -//Checks to see if there's 1 line or 2, adds text-icons-numbers/letters over display -// Stolen from status_display -/obj/machinery/door_timer/proc/update_display(line1, line2) - var/new_text = {"
      [line1]
      [line2]
      "} - if(maptext != new_text) - maptext = new_text - -/obj/machinery/door_timer/ui_data() - var/list/data = list() - var/time_left = time_left(seconds = TRUE) - data["seconds"] = round(time_left % 60) - data["minutes"] = round((time_left - data["seconds"]) / 60) - data["timing"] = timing - data["flash_charging"] = FALSE - for(var/obj/machinery/flasher/F in targets) - if(F.last_flash && (F.last_flash + 150) > world.time) - data["flash_charging"] = TRUE - break - return data - - -/obj/machinery/door_timer/ui_act(action, params) - if(..()) - return - . = TRUE - - if(!allowed(usr)) - to_chat(usr, "Access denied.") - return FALSE - - switch(action) - if("time") - var/value = text2num(params["adjust"]) - if(value) - . = set_timer(time_left()+value) - if("start") - timer_start() - if("stop") - timer_end(forced = TRUE) - if("flash") - for(var/obj/machinery/flasher/F in targets) - F.flash() - if("preset") - var/preset = params["preset"] - var/preset_time = time_left() - switch(preset) - if("short") - preset_time = PRESET_SHORT - if("medium") - preset_time = PRESET_MEDIUM - if("long") - preset_time = PRESET_LONG - . = set_timer(preset_time) - if(timing) - activation_time = world.realtime - else - . = FALSE - - -#undef PRESET_SHORT -#undef PRESET_MEDIUM -#undef PRESET_LONG - -#undef MAX_TIMER -#undef FONT_SIZE -#undef FONT_COLOR -#undef FONT_STYLE -#undef CHARS_PER_LINE +#define CHARS_PER_LINE 5 +#define FONT_SIZE "5pt" +#define FONT_COLOR "#09f" +#define FONT_STYLE "Arial Black" +#define MAX_TIMER 9000 + +#define PRESET_SHORT 1200 +#define PRESET_MEDIUM 1800 +#define PRESET_LONG 3000 + + + +/////////////////////////////////////////////////////////////////////////////////////////////// +// Brig Door control displays. +// Description: This is a controls the timer for the brig doors, displays the timer on itself and +// has a popup window when used, allowing to set the timer. +// Code Notes: Combination of old brigdoor.dm code from rev4407 and the status_display.dm code +// Date: 01/September/2010 +// Programmer: Veryinky +///////////////////////////////////////////////////////////////////////////////////////////////// +/obj/machinery/door_timer + name = "door timer" + icon = 'icons/obj/status_display.dmi' + icon_state = "frame" + desc = "A remote control for a door." + req_access = list(ACCESS_SECURITY) + density = FALSE + var/id = null // id of linked machinery/lockers + + var/activation_time = 0 + var/timer_duration = 0 + + var/timing = FALSE // boolean, true/1 timer is on, false/0 means it's not timing + var/list/obj/machinery/targets = list() + var/obj/item/radio/Radio //needed to send messages to sec radio + + maptext_height = 26 + maptext_width = 32 + +/obj/machinery/door_timer/Initialize() + . = ..() + + Radio = new/obj/item/radio(src) + Radio.listening = 0 + +/obj/machinery/door_timer/Initialize() + . = ..() + if(id != null) + for(var/obj/machinery/door/window/brigdoor/M in urange(20, src)) + if (M.id == id) + targets += M + + for(var/obj/machinery/flasher/F in urange(20, src)) + if(F.id == id) + targets += F + + for(var/obj/structure/closet/secure_closet/brig/C in urange(20, src)) + if(C.id == id) + targets += C + + if(!targets.len) + stat |= BROKEN + update_icon() + + +//Main door timer loop, if it's timing and time is >0 reduce time by 1. +// if it's less than 0, open door, reset timer +// update the door_timer window and the icon +/obj/machinery/door_timer/process() + if(stat & (NOPOWER|BROKEN)) + return + + if(timing) + if(world.realtime - activation_time >= timer_duration) + timer_end() // open doors, reset timer, clear status screen + update_icon() + +// has the door power sitatuation changed, if so update icon. +/obj/machinery/door_timer/power_change() + ..() + update_icon() + + +// open/closedoor checks if door_timer has power, if so it checks if the +// linked door is open/closed (by density) then opens it/closes it. +/obj/machinery/door_timer/proc/timer_start() + if(stat & (NOPOWER|BROKEN)) + return 0 + + activation_time = world.realtime + timing = TRUE + + for(var/obj/machinery/door/window/brigdoor/door in targets) + if(door.density) + continue + INVOKE_ASYNC(door, /obj/machinery/door/window/brigdoor.proc/close) + + for(var/obj/structure/closet/secure_closet/brig/C in targets) + if(C.broken) + continue + if(C.opened && !C.close()) + continue + C.locked = TRUE + C.update_icon() + return 1 + + +/obj/machinery/door_timer/proc/timer_end(forced = FALSE) + + if(stat & (NOPOWER|BROKEN)) + return 0 + + if(!forced) + Radio.set_frequency(FREQ_SECURITY) + Radio.talk_into(src, "Timer has expired. Releasing prisoner.", FREQ_SECURITY) + + timing = FALSE + activation_time = null + set_timer(0) + update_icon() + + for(var/obj/machinery/door/window/brigdoor/door in targets) + if(!door.density) + continue + INVOKE_ASYNC(door, /obj/machinery/door/window/brigdoor.proc/open) + + for(var/obj/structure/closet/secure_closet/brig/C in targets) + if(C.broken) + continue + if(C.opened) + continue + C.locked = FALSE + C.update_icon() + + return 1 + + +/obj/machinery/door_timer/proc/time_left(seconds = FALSE) + . = max(0,timer_duration - (activation_time ? world.realtime - activation_time : 0)) + if(seconds) + . /= 10 + +/obj/machinery/door_timer/proc/set_timer(value) + var/new_time = CLAMP(value,0,MAX_TIMER) + . = new_time == timer_duration //return 1 on no change + timer_duration = new_time + +/obj/machinery/door_timer/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, "brig_timer", name, 300, 200, master_ui, state) + ui.open() + +//icon update function +// if NOPOWER, display blank +// if BROKEN, display blue screen of death icon AI uses +// if timing=true, run update display function +/obj/machinery/door_timer/update_icon() + if(stat & (NOPOWER)) + icon_state = "frame" + return + + if(stat & (BROKEN)) + set_picture("ai_bsod") + return + + if(timing) + var/disp1 = id + var/time_left = time_left(seconds = TRUE) + var/disp2 = "[add_zero(num2text((time_left / 60) % 60),2)]~[add_zero(num2text(time_left % 60), 2)]" + if(length(disp2) > CHARS_PER_LINE) + disp2 = "Error" + update_display(disp1, disp2) + else + if(maptext) + maptext = "" + return + + +// Adds an icon in case the screen is broken/off, stolen from status_display.dm +/obj/machinery/door_timer/proc/set_picture(state) + if(maptext) + maptext = "" + cut_overlays() + add_overlay(mutable_appearance('icons/obj/status_display.dmi', state)) + + +//Checks to see if there's 1 line or 2, adds text-icons-numbers/letters over display +// Stolen from status_display +/obj/machinery/door_timer/proc/update_display(line1, line2) + var/new_text = {"
      [line1]
      [line2]
      "} + if(maptext != new_text) + maptext = new_text + +/obj/machinery/door_timer/ui_data() + var/list/data = list() + var/time_left = time_left(seconds = TRUE) + data["seconds"] = round(time_left % 60) + data["minutes"] = round((time_left - data["seconds"]) / 60) + data["timing"] = timing + data["flash_charging"] = FALSE + for(var/obj/machinery/flasher/F in targets) + if(F.last_flash && (F.last_flash + 150) > world.time) + data["flash_charging"] = TRUE + break + return data + + +/obj/machinery/door_timer/ui_act(action, params) + if(..()) + return + . = TRUE + + if(!allowed(usr)) + to_chat(usr, "Access denied.") + return FALSE + + switch(action) + if("time") + var/value = text2num(params["adjust"]) + if(value) + . = set_timer(time_left()+value) + if("start") + timer_start() + if("stop") + timer_end(forced = TRUE) + if("flash") + for(var/obj/machinery/flasher/F in targets) + F.flash() + if("preset") + var/preset = params["preset"] + var/preset_time = time_left() + switch(preset) + if("short") + preset_time = PRESET_SHORT + if("medium") + preset_time = PRESET_MEDIUM + if("long") + preset_time = PRESET_LONG + . = set_timer(preset_time) + if(timing) + activation_time = world.realtime + else + . = FALSE + + +#undef PRESET_SHORT +#undef PRESET_MEDIUM +#undef PRESET_LONG + +#undef MAX_TIMER +#undef FONT_SIZE +#undef FONT_COLOR +#undef FONT_STYLE +#undef CHARS_PER_LINE diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index ee8742e84f..2e43670624 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -1,385 +1,385 @@ -/obj/machinery/door - name = "door" - desc = "It opens and closes." - icon = 'icons/obj/doors/Doorint.dmi' - icon_state = "door1" - opacity = 1 - density = TRUE - layer = OPEN_DOOR_LAYER - power_channel = ENVIRON - max_integrity = 350 - armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 70) - CanAtmosPass = ATMOS_PASS_DENSITY - flags_1 = PREVENT_CLICK_UNDER_1 - - interaction_flags_atom = INTERACT_ATOM_UI_INTERACT - - var/secondsElectrified = 0 - var/shockedby - var/visible = TRUE - var/operating = FALSE - var/glass = FALSE - var/welded = FALSE - var/normalspeed = 1 - var/heat_proof = FALSE // For rglass-windowed airlocks and firedoors - var/emergency = FALSE // Emergency access override - var/sub_door = FALSE // true if it's meant to go under another door. - var/closingLayer = CLOSED_DOOR_LAYER - var/autoclose = FALSE //does it automatically close after some time - var/safe = TRUE //whether the door detects things and mobs in its way and reopen or crushes them. - var/locked = FALSE //whether the door is bolted or not. - var/assemblytype //the type of door frame to drop during deconstruction - var/datum/effect_system/spark_spread/spark_system - var/damage_deflection = 10 - var/real_explosion_block //ignore this, just use explosion_block - var/red_alert_access = FALSE //if TRUE, this door will always open on red alert - var/poddoor = FALSE - var/unres_sides = 0 //Unrestricted sides. A bitflag for which direction (if any) can open the door with no access - -/obj/machinery/door/examine(mob/user) - . = ..() - if(red_alert_access) - if(GLOB.security_level >= SEC_LEVEL_RED) - . += "Due to a security threat, its access requirements have been lifted!" - else - . += "In the event of a red alert, its access requirements will automatically lift." - if(!poddoor) - . += "Its maintenance panel is screwed in place." - -/obj/machinery/door/check_access_list(list/access_list) - if(red_alert_access && GLOB.security_level >= SEC_LEVEL_RED) - return TRUE - return ..() - -/obj/machinery/door/Initialize() - . = ..() - set_init_door_layer() - update_freelook_sight() - air_update_turf(1) - GLOB.airlocks += src - spark_system = new /datum/effect_system/spark_spread - spark_system.set_up(2, 1, src) - - //doors only block while dense though so we have to use the proc - real_explosion_block = explosion_block - explosion_block = EXPLOSION_BLOCK_PROC - -/obj/machinery/door/proc/set_init_door_layer() - if(density) - layer = closingLayer - else - layer = initial(layer) - -/obj/machinery/door/power_change() - ..() - update_icon() - -/obj/machinery/door/Destroy() - update_freelook_sight() - GLOB.airlocks -= src - if(spark_system) - qdel(spark_system) - spark_system = null - return ..() - -/obj/machinery/door/Bumped(atom/movable/AM) - if(operating || (obj_flags & EMAGGED)) - return - if(ismob(AM)) - var/mob/B = AM - if((isdrone(B) || iscyborg(B)) && B.stat) - return - if(isliving(AM)) - var/mob/living/M = AM - if(world.time - M.last_bumped <= 10) - return //Can bump-open one airlock per second. This is to prevent shock spam. - M.last_bumped = world.time - if(M.restrained() && !check_access(null)) - return - bumpopen(M) - return - - if(ismecha(AM)) - var/obj/mecha/mecha = AM - if(density) - if(mecha.occupant) - if(world.time - mecha.occupant.last_bumped <= 10) - return - mecha.occupant.last_bumped = world.time - if(mecha.occupant && (src.allowed(mecha.occupant) || src.check_access_list(mecha.operation_req_access))) - open() - else - do_animate("deny") - return - return - -/obj/machinery/door/Move() - var/turf/T = loc - . = ..() - move_update_air(T) - -/obj/machinery/door/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGLASS)) - return !opacity - return !density - -/obj/machinery/door/proc/bumpopen(mob/user) - if(operating) - return - src.add_fingerprint(user) - if(!src.requiresID()) - user = null - - if(density && !(obj_flags & EMAGGED)) - if(allowed(user)) - open() - else - do_animate("deny") - return - -/obj/machinery/door/attack_hand(mob/user) - . = ..() - if(.) - return - return try_to_activate_door(user) - -/obj/machinery/door/attack_tk(mob/user) - if(requiresID() && !allowed(null)) - return - ..() - -/obj/machinery/door/proc/try_to_activate_door(mob/user) - add_fingerprint(user) - if(operating || (obj_flags & EMAGGED)) - return - if(!requiresID()) - user = null //so allowed(user) always succeeds - if(allowed(user)) - if(density) - open() - else - close() - return - if(density) - do_animate("deny") - -/obj/machinery/door/allowed(mob/M) - if(emergency) - return TRUE - if(unrestricted_side(M)) - return TRUE - return ..() - -/obj/machinery/door/proc/unrestricted_side(mob/M) //Allows for specific side of airlocks to be unrestrected (IE, can exit maint freely, but need access to enter) - return get_dir(src, M) & unres_sides - -/obj/machinery/door/proc/try_to_weld(obj/item/weldingtool/W, mob/user) - return - -/obj/machinery/door/proc/try_to_crowbar(obj/item/I, mob/user) - return - -/obj/machinery/door/attackby(obj/item/I, mob/user, params) - if(user.a_intent != INTENT_HARM && (istype(I, /obj/item/crowbar) || istype(I, /obj/item/twohanded/fireaxe))) - try_to_crowbar(I, user) - return 1 - else if(istype(I, /obj/item/weldingtool)) - try_to_weld(I, user) - return 1 - else if(!(I.item_flags & NOBLUDGEON) && user.a_intent != INTENT_HARM) - try_to_activate_door(user) - return 1 - return ..() - -/obj/machinery/door/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < damage_deflection) - return 0 - . = ..() - -/obj/machinery/door/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) - . = ..() - if(. && obj_integrity > 0) - if(damage_amount >= 10 && prob(30)) - spark_system.start() - -/obj/machinery/door/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - switch(damage_type) - if(BRUTE) - if(glass) - playsound(loc, 'sound/effects/glasshit.ogg', 90, 1) - else if(damage_amount) - playsound(loc, 'sound/weapons/smash.ogg', 50, 1) - else - playsound(src, 'sound/weapons/tap.ogg', 50, 1) - if(BURN) - playsound(src.loc, 'sound/items/welder.ogg', 100, 1) - -/obj/machinery/door/emp_act(severity) - . = ..() - if (. & EMP_PROTECT_SELF) - return - if(prob(20/severity) && (istype(src, /obj/machinery/door/airlock) || istype(src, /obj/machinery/door/window)) ) - INVOKE_ASYNC(src, .proc/open) - if(prob(severity*10 - 20)) - if(secondsElectrified == 0) - secondsElectrified = -1 - LAZYADD(shockedby, "\[[TIME_STAMP("hh:mm:ss", FALSE)]\]EM Pulse") - addtimer(CALLBACK(src, .proc/unelectrify), 300) - -/obj/machinery/door/proc/unelectrify() - secondsElectrified = 0 - -/obj/machinery/door/update_icon() - if(density) - icon_state = "door1" - else - icon_state = "door0" - -/obj/machinery/door/proc/do_animate(animation) - switch(animation) - if("opening") - if(panel_open) - flick("o_doorc0", src) - else - flick("doorc0", src) - if("closing") - if(panel_open) - flick("o_doorc1", src) - else - flick("doorc1", src) - if("deny") - if(!stat) - flick("door_deny", src) - - -/obj/machinery/door/proc/open() - if(!density) - return 1 - if(operating) - return - operating = TRUE - do_animate("opening") - set_opacity(0) - sleep(5) - density = FALSE - sleep(5) - layer = initial(layer) - update_icon() - set_opacity(0) - operating = FALSE - air_update_turf(1) - update_freelook_sight() - if(autoclose) - spawn(autoclose) - close() - return 1 - -/obj/machinery/door/proc/close() - if(density) - return TRUE - if(operating || welded) - return - if(safe) - for(var/atom/movable/M in get_turf(src)) - if(M.density && M != src) //something is blocking the door - if(autoclose) - autoclose_in(60) - return - - operating = TRUE - - do_animate("closing") - layer = closingLayer - sleep(5) - density = TRUE - sleep(5) - update_icon() - if(visible && !glass) - set_opacity(1) - operating = FALSE - air_update_turf(1) - update_freelook_sight() - if(safe) - CheckForMobs() - else - crush() - return 1 - -/obj/machinery/door/proc/CheckForMobs() - if(locate(/mob/living) in get_turf(src)) - sleep(1) - open() - -/obj/machinery/door/proc/crush() - for(var/mob/living/L in get_turf(src)) - L.visible_message("[src] closes on [L], crushing [L.p_them()]!", "[src] closes on you and crushes you!") - if(isalien(L)) //For xenos - L.adjustBruteLoss(DOOR_CRUSH_DAMAGE * 1.5) //Xenos go into crit after aproximately the same amount of crushes as humans. - L.emote("roar") - else if(ishuman(L)) //For humans - L.adjustBruteLoss(DOOR_CRUSH_DAMAGE) - L.emote("scream") - L.Knockdown(100) - else if(ismonkey(L)) //For monkeys - L.adjustBruteLoss(DOOR_CRUSH_DAMAGE) - L.Knockdown(100) - else //for simple_animals & borgs - L.adjustBruteLoss(DOOR_CRUSH_DAMAGE) - var/turf/location = get_turf(src) - //add_blood_DNA doesn't work for borgs/xenos, but add_blood_floor does. - if(iscarbon(L)) - var/mob/living/carbon/C = L - C.bleed(DOOR_CRUSH_DAMAGE) - else - L.add_splatter_floor(location) - for(var/obj/mecha/M in get_turf(src)) - M.take_damage(DOOR_CRUSH_DAMAGE) - -/obj/machinery/door/proc/autoclose() - if(!QDELETED(src) && !density && !operating && !locked && !welded && autoclose) - close() - -/obj/machinery/door/proc/autoclose_in(wait) - addtimer(CALLBACK(src, .proc/autoclose), wait, TIMER_UNIQUE | TIMER_NO_HASH_WAIT | TIMER_OVERRIDE) - -/obj/machinery/door/proc/requiresID() - return 1 - -/obj/machinery/door/proc/hasPower() - return !(stat & NOPOWER) - -/obj/machinery/door/proc/update_freelook_sight() - if(!glass && GLOB.cameranet) - GLOB.cameranet.updateVisibility(src, 0) - -/obj/machinery/door/BlockSuperconductivity() // All non-glass airlocks block heat, this is intended. - if(opacity || heat_proof) - return 1 - return 0 - -/obj/machinery/door/morgue - icon = 'icons/obj/doors/doormorgue.dmi' - -/obj/machinery/door/get_dumping_location(obj/item/storage/source,mob/user) - return null - -/obj/machinery/door/proc/lock() - return - -/obj/machinery/door/proc/unlock() - return - -/obj/machinery/door/proc/hostile_lockdown(mob/origin) - if(!stat) //So that only powered doors are closed. - close() //Close ALL the doors! - -/obj/machinery/door/proc/disable_lockdown() - if(!stat) //Opens only powered doors. - open() //Open everything! - -/obj/machinery/door/ex_act(severity, target) - //if it blows up a wall it should blow up a door - ..(severity ? max(1, severity - 1) : 0, target) - -/obj/machinery/door/GetExplosionBlock() - return density ? real_explosion_block : 0 +/obj/machinery/door + name = "door" + desc = "It opens and closes." + icon = 'icons/obj/doors/Doorint.dmi' + icon_state = "door1" + opacity = 1 + density = TRUE + layer = OPEN_DOOR_LAYER + power_channel = ENVIRON + max_integrity = 350 + armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 70) + CanAtmosPass = ATMOS_PASS_DENSITY + flags_1 = PREVENT_CLICK_UNDER_1 + + interaction_flags_atom = INTERACT_ATOM_UI_INTERACT + + var/secondsElectrified = 0 + var/shockedby + var/visible = TRUE + var/operating = FALSE + var/glass = FALSE + var/welded = FALSE + var/normalspeed = 1 + var/heat_proof = FALSE // For rglass-windowed airlocks and firedoors + var/emergency = FALSE // Emergency access override + var/sub_door = FALSE // true if it's meant to go under another door. + var/closingLayer = CLOSED_DOOR_LAYER + var/autoclose = FALSE //does it automatically close after some time + var/safe = TRUE //whether the door detects things and mobs in its way and reopen or crushes them. + var/locked = FALSE //whether the door is bolted or not. + var/assemblytype //the type of door frame to drop during deconstruction + var/datum/effect_system/spark_spread/spark_system + var/damage_deflection = 10 + var/real_explosion_block //ignore this, just use explosion_block + var/red_alert_access = FALSE //if TRUE, this door will always open on red alert + var/poddoor = FALSE + var/unres_sides = 0 //Unrestricted sides. A bitflag for which direction (if any) can open the door with no access + +/obj/machinery/door/examine(mob/user) + . = ..() + if(red_alert_access) + if(GLOB.security_level >= SEC_LEVEL_RED) + . += "Due to a security threat, its access requirements have been lifted!" + else + . += "In the event of a red alert, its access requirements will automatically lift." + if(!poddoor) + . += "Its maintenance panel is screwed in place." + +/obj/machinery/door/check_access_list(list/access_list) + if(red_alert_access && GLOB.security_level >= SEC_LEVEL_RED) + return TRUE + return ..() + +/obj/machinery/door/Initialize() + . = ..() + set_init_door_layer() + update_freelook_sight() + air_update_turf(1) + GLOB.airlocks += src + spark_system = new /datum/effect_system/spark_spread + spark_system.set_up(2, 1, src) + + //doors only block while dense though so we have to use the proc + real_explosion_block = explosion_block + explosion_block = EXPLOSION_BLOCK_PROC + +/obj/machinery/door/proc/set_init_door_layer() + if(density) + layer = closingLayer + else + layer = initial(layer) + +/obj/machinery/door/power_change() + ..() + update_icon() + +/obj/machinery/door/Destroy() + update_freelook_sight() + GLOB.airlocks -= src + if(spark_system) + qdel(spark_system) + spark_system = null + return ..() + +/obj/machinery/door/Bumped(atom/movable/AM) + if(operating || (obj_flags & EMAGGED)) + return + if(ismob(AM)) + var/mob/B = AM + if((isdrone(B) || iscyborg(B)) && B.stat) + return + if(isliving(AM)) + var/mob/living/M = AM + if(world.time - M.last_bumped <= 10) + return //Can bump-open one airlock per second. This is to prevent shock spam. + M.last_bumped = world.time + if(M.restrained() && !check_access(null)) + return + bumpopen(M) + return + + if(ismecha(AM)) + var/obj/mecha/mecha = AM + if(density) + if(mecha.occupant) + if(world.time - mecha.occupant.last_bumped <= 10) + return + mecha.occupant.last_bumped = world.time + if(mecha.occupant && (src.allowed(mecha.occupant) || src.check_access_list(mecha.operation_req_access))) + open() + else + do_animate("deny") + return + return + +/obj/machinery/door/Move() + var/turf/T = loc + . = ..() + move_update_air(T) + +/obj/machinery/door/CanPass(atom/movable/mover, turf/target) + if(istype(mover) && (mover.pass_flags & PASSGLASS)) + return !opacity + return !density + +/obj/machinery/door/proc/bumpopen(mob/user) + if(operating) + return + src.add_fingerprint(user) + if(!src.requiresID()) + user = null + + if(density && !(obj_flags & EMAGGED)) + if(allowed(user)) + open() + else + do_animate("deny") + return + +/obj/machinery/door/attack_hand(mob/user) + . = ..() + if(.) + return + return try_to_activate_door(user) + +/obj/machinery/door/attack_tk(mob/user) + if(requiresID() && !allowed(null)) + return + ..() + +/obj/machinery/door/proc/try_to_activate_door(mob/user) + add_fingerprint(user) + if(operating || (obj_flags & EMAGGED)) + return + if(!requiresID()) + user = null //so allowed(user) always succeeds + if(allowed(user)) + if(density) + open() + else + close() + return + if(density) + do_animate("deny") + +/obj/machinery/door/allowed(mob/M) + if(emergency) + return TRUE + if(unrestricted_side(M)) + return TRUE + return ..() + +/obj/machinery/door/proc/unrestricted_side(mob/M) //Allows for specific side of airlocks to be unrestrected (IE, can exit maint freely, but need access to enter) + return get_dir(src, M) & unres_sides + +/obj/machinery/door/proc/try_to_weld(obj/item/weldingtool/W, mob/user) + return + +/obj/machinery/door/proc/try_to_crowbar(obj/item/I, mob/user) + return + +/obj/machinery/door/attackby(obj/item/I, mob/user, params) + if(user.a_intent != INTENT_HARM && (istype(I, /obj/item/crowbar) || istype(I, /obj/item/twohanded/fireaxe))) + try_to_crowbar(I, user) + return 1 + else if(istype(I, /obj/item/weldingtool)) + try_to_weld(I, user) + return 1 + else if(!(I.item_flags & NOBLUDGEON) && user.a_intent != INTENT_HARM) + try_to_activate_door(user) + return 1 + return ..() + +/obj/machinery/door/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) + if(damage_flag == "melee" && damage_amount < damage_deflection) + return 0 + . = ..() + +/obj/machinery/door/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir) + . = ..() + if(. && obj_integrity > 0) + if(damage_amount >= 10 && prob(30)) + spark_system.start() + +/obj/machinery/door/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) + switch(damage_type) + if(BRUTE) + if(glass) + playsound(loc, 'sound/effects/glasshit.ogg', 90, 1) + else if(damage_amount) + playsound(loc, 'sound/weapons/smash.ogg', 50, 1) + else + playsound(src, 'sound/weapons/tap.ogg', 50, 1) + if(BURN) + playsound(src.loc, 'sound/items/welder.ogg', 100, 1) + +/obj/machinery/door/emp_act(severity) + . = ..() + if (. & EMP_PROTECT_SELF) + return + if(prob(20/severity) && (istype(src, /obj/machinery/door/airlock) || istype(src, /obj/machinery/door/window)) ) + INVOKE_ASYNC(src, .proc/open) + if(prob(severity*10 - 20)) + if(secondsElectrified == 0) + secondsElectrified = -1 + LAZYADD(shockedby, "\[[TIME_STAMP("hh:mm:ss", FALSE)]\]EM Pulse") + addtimer(CALLBACK(src, .proc/unelectrify), 300) + +/obj/machinery/door/proc/unelectrify() + secondsElectrified = 0 + +/obj/machinery/door/update_icon() + if(density) + icon_state = "door1" + else + icon_state = "door0" + +/obj/machinery/door/proc/do_animate(animation) + switch(animation) + if("opening") + if(panel_open) + flick("o_doorc0", src) + else + flick("doorc0", src) + if("closing") + if(panel_open) + flick("o_doorc1", src) + else + flick("doorc1", src) + if("deny") + if(!stat) + flick("door_deny", src) + + +/obj/machinery/door/proc/open() + if(!density) + return 1 + if(operating) + return + operating = TRUE + do_animate("opening") + set_opacity(0) + sleep(5) + density = FALSE + sleep(5) + layer = initial(layer) + update_icon() + set_opacity(0) + operating = FALSE + air_update_turf(1) + update_freelook_sight() + if(autoclose) + spawn(autoclose) + close() + return 1 + +/obj/machinery/door/proc/close() + if(density) + return TRUE + if(operating || welded) + return + if(safe) + for(var/atom/movable/M in get_turf(src)) + if(M.density && M != src) //something is blocking the door + if(autoclose) + autoclose_in(60) + return + + operating = TRUE + + do_animate("closing") + layer = closingLayer + sleep(5) + density = TRUE + sleep(5) + update_icon() + if(visible && !glass) + set_opacity(1) + operating = FALSE + air_update_turf(1) + update_freelook_sight() + if(safe) + CheckForMobs() + else + crush() + return 1 + +/obj/machinery/door/proc/CheckForMobs() + if(locate(/mob/living) in get_turf(src)) + sleep(1) + open() + +/obj/machinery/door/proc/crush() + for(var/mob/living/L in get_turf(src)) + L.visible_message("[src] closes on [L], crushing [L.p_them()]!", "[src] closes on you and crushes you!") + if(isalien(L)) //For xenos + L.adjustBruteLoss(DOOR_CRUSH_DAMAGE * 1.5) //Xenos go into crit after aproximately the same amount of crushes as humans. + L.emote("roar") + else if(ishuman(L)) //For humans + L.adjustBruteLoss(DOOR_CRUSH_DAMAGE) + L.emote("scream") + L.Knockdown(100) + else if(ismonkey(L)) //For monkeys + L.adjustBruteLoss(DOOR_CRUSH_DAMAGE) + L.Knockdown(100) + else //for simple_animals & borgs + L.adjustBruteLoss(DOOR_CRUSH_DAMAGE) + var/turf/location = get_turf(src) + //add_blood_DNA doesn't work for borgs/xenos, but add_blood_floor does. + if(iscarbon(L)) + var/mob/living/carbon/C = L + C.bleed(DOOR_CRUSH_DAMAGE) + else + L.add_splatter_floor(location) + for(var/obj/mecha/M in get_turf(src)) + M.take_damage(DOOR_CRUSH_DAMAGE) + +/obj/machinery/door/proc/autoclose() + if(!QDELETED(src) && !density && !operating && !locked && !welded && autoclose) + close() + +/obj/machinery/door/proc/autoclose_in(wait) + addtimer(CALLBACK(src, .proc/autoclose), wait, TIMER_UNIQUE | TIMER_NO_HASH_WAIT | TIMER_OVERRIDE) + +/obj/machinery/door/proc/requiresID() + return 1 + +/obj/machinery/door/proc/hasPower() + return !(stat & NOPOWER) + +/obj/machinery/door/proc/update_freelook_sight() + if(!glass && GLOB.cameranet) + GLOB.cameranet.updateVisibility(src, 0) + +/obj/machinery/door/BlockSuperconductivity() // All non-glass airlocks block heat, this is intended. + if(opacity || heat_proof) + return 1 + return 0 + +/obj/machinery/door/morgue + icon = 'icons/obj/doors/doormorgue.dmi' + +/obj/machinery/door/get_dumping_location(obj/item/storage/source,mob/user) + return null + +/obj/machinery/door/proc/lock() + return + +/obj/machinery/door/proc/unlock() + return + +/obj/machinery/door/proc/hostile_lockdown(mob/origin) + if(!stat) //So that only powered doors are closed. + close() //Close ALL the doors! + +/obj/machinery/door/proc/disable_lockdown() + if(!stat) //Opens only powered doors. + open() //Open everything! + +/obj/machinery/door/ex_act(severity, target) + //if it blows up a wall it should blow up a door + ..(severity ? max(1, severity - 1) : 0, target) + +/obj/machinery/door/GetExplosionBlock() + return density ? real_explosion_block : 0 diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 39b6c8da1d..0429db5792 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -1,476 +1,476 @@ -#define CONSTRUCTION_COMPLETE 0 //No construction done - functioning as normal -#define CONSTRUCTION_PANEL_OPEN 1 //Maintenance panel is open, still functioning -#define CONSTRUCTION_WIRES_EXPOSED 2 //Cover plate is removed, wires are available -#define CONSTRUCTION_GUTTED 3 //Wires are removed, circuit ready to remove -#define CONSTRUCTION_NOCIRCUIT 4 //Circuit board removed, can safely weld apart - -/obj/machinery/door/firedoor - name = "firelock" - desc = "Apply crowbar." - icon = 'icons/obj/doors/Doorfireglass.dmi' - icon_state = "door_open" - opacity = FALSE - density = FALSE - max_integrity = 300 - resistance_flags = FIRE_PROOF - heat_proof = TRUE - glass = TRUE - sub_door = TRUE - explosion_block = 1 - safe = FALSE - layer = BELOW_OPEN_DOOR_LAYER - closingLayer = CLOSED_FIREDOOR_LAYER - assemblytype = /obj/structure/firelock_frame - armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 70) - interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN - var/nextstate = null - var/boltslocked = TRUE - var/list/affecting_areas - -/obj/machinery/door/firedoor/Initialize() - . = ..() - CalculateAffectingAreas() - -/obj/machinery/door/firedoor/examine(mob/user) - ..() - if(!density) - . += "It is open, but could be pried closed." - else if(!welded) - . += "It is closed, but could be pried open. Deconstruction would require it to be welded shut." - else if(boltslocked) - . += "It is welded shut. The floor bolts have been locked by screws." - else - . += "The bolt locks have been unscrewed, but the bolts themselves are still wrenched to the floor." - -/obj/machinery/door/firedoor/proc/CalculateAffectingAreas() - remove_from_areas() - affecting_areas = get_adjacent_open_areas(src) | get_area(src) - for(var/I in affecting_areas) - var/area/A = I - LAZYADD(A.firedoors, src) - -/obj/machinery/door/firedoor/closed - icon_state = "door_closed" - opacity = TRUE - density = TRUE - -//see also turf/AfterChange for adjacency shennanigans - -/obj/machinery/door/firedoor/proc/remove_from_areas() - if(affecting_areas) - for(var/I in affecting_areas) - var/area/A = I - LAZYREMOVE(A.firedoors, src) - -/obj/machinery/door/firedoor/Destroy() - remove_from_areas() - affecting_areas.Cut() - return ..() - -/obj/machinery/door/firedoor/Bumped(atom/movable/AM) - if(panel_open || operating) - return - if(!density) - return ..() - return FALSE - - -/obj/machinery/door/firedoor/power_change() - if(powered(power_channel)) - stat &= ~NOPOWER - latetoggle() - else - stat |= NOPOWER - -/obj/machinery/door/firedoor/attack_hand(mob/user) - . = ..() - if(.) - return - if(operating || !density) - return - user.changeNext_move(CLICK_CD_MELEE) - - user.visible_message("[user] bangs on \the [src].", - "You bang on \the [src].") - playsound(loc, 'sound/effects/glassknock.ogg', 10, FALSE, frequency = 32000) - -/obj/machinery/door/firedoor/attackby(obj/item/C, mob/user, params) - add_fingerprint(user) - if(operating) - return - - if(welded) - if(istype(C, /obj/item/wrench)) - if(boltslocked) - to_chat(user, "There are screws locking the bolts in place!") - return - C.play_tool_sound(src) - user.visible_message("[user] starts undoing [src]'s bolts...", \ - "You start unfastening [src]'s floor bolts...") - if(!C.use_tool(src, user, 50)) - return - playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) - user.visible_message("[user] unfastens [src]'s bolts.", \ - "You undo [src]'s floor bolts.") - deconstruct(TRUE) - return - if(istype(C, /obj/item/screwdriver)) - user.visible_message("[user] [boltslocked ? "unlocks" : "locks"] [src]'s bolts.", \ - "You [boltslocked ? "unlock" : "lock"] [src]'s floor bolts.") - C.play_tool_sound(src) - boltslocked = !boltslocked - return - - return ..() - -/obj/machinery/door/firedoor/try_to_activate_door(mob/user) - return - -/obj/machinery/door/firedoor/try_to_weld(obj/item/weldingtool/W, mob/user) - if(!W.tool_start_check(user, amount=0)) - return - user.visible_message("[user] starts [welded ? "unwelding" : "welding"] [src].", "You start welding [src].") - if(W.use_tool(src, user, 40, volume=50)) - welded = !welded - to_chat(user, "[user] [welded?"welds":"unwelds"] [src].", "You [welded ? "weld" : "unweld"] [src].") - update_icon() - -/obj/machinery/door/firedoor/try_to_crowbar(obj/item/I, mob/user) - if(welded || operating) - return - - if(density) - open() - else - close() - -/obj/machinery/door/firedoor/attack_ai(mob/user) - add_fingerprint(user) - if(welded || operating || stat & NOPOWER) - return TRUE - if(density) - open() - else - close() - return TRUE - -/obj/machinery/door/firedoor/attack_robot(mob/user) - return attack_ai(user) - -/obj/machinery/door/firedoor/attack_alien(mob/user) - add_fingerprint(user) - if(welded) - to_chat(user, "[src] refuses to budge!") - return - open() - -/obj/machinery/door/firedoor/do_animate(animation) - switch(animation) - if("opening") - flick("door_opening", src) - if("closing") - flick("door_closing", src) - -/obj/machinery/door/firedoor/update_icon() - cut_overlays() - if(density) - icon_state = "door_closed" - if(welded) - add_overlay("welded") - else - icon_state = "door_open" - if(welded) - add_overlay("welded_open") - -/obj/machinery/door/firedoor/open() - . = ..() - latetoggle() - -/obj/machinery/door/firedoor/close() - . = ..() - latetoggle() - -/obj/machinery/door/firedoor/deconstruct(disassembled = TRUE) - if(!(flags_1 & NODECONSTRUCT_1)) - var/obj/structure/firelock_frame/F = new assemblytype(get_turf(src)) - if(disassembled) - F.constructionStep = CONSTRUCTION_PANEL_OPEN - else - F.constructionStep = CONSTRUCTION_WIRES_EXPOSED - F.obj_integrity = F.max_integrity * 0.5 - F.update_icon() - qdel(src) - - -/obj/machinery/door/firedoor/proc/latetoggle() - if(operating || stat & NOPOWER || !nextstate) - return - switch(nextstate) - if(FIREDOOR_OPEN) - nextstate = null - open() - if(FIREDOOR_CLOSED) - nextstate = null - close() - -/obj/machinery/door/firedoor/border_only - icon = 'icons/obj/doors/edge_Doorfire.dmi' - flags_1 = ON_BORDER_1 - CanAtmosPass = ATMOS_PASS_PROC - -/obj/machinery/door/firedoor/border_only/closed - icon_state = "door_closed" - opacity = TRUE - density = TRUE - -/obj/machinery/door/firedoor/border_only/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGLASS)) - return TRUE - if(get_dir(loc, target) == dir) //Make sure looking at appropriate border - return !density - else - return TRUE - -/obj/machinery/door/firedoor/border_only/CheckExit(atom/movable/mover as mob|obj, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGLASS)) - return TRUE - if(get_dir(loc, target) == dir) - return !density - else - return TRUE - -/obj/machinery/door/firedoor/border_only/CanAtmosPass(turf/T) - if(get_dir(loc, T) == dir) - return !density - else - return TRUE - -/obj/machinery/door/firedoor/heavy - name = "heavy firelock" - icon = 'icons/obj/doors/Doorfire.dmi' - glass = FALSE - explosion_block = 2 - assemblytype = /obj/structure/firelock_frame/heavy - max_integrity = 550 - - -/obj/item/electronics/firelock - name = "firelock circuitry" - desc = "A circuit board used in construction of firelocks." - icon_state = "mainboard" - -/obj/structure/firelock_frame - name = "firelock frame" - desc = "A partially completed firelock." - icon = 'icons/obj/doors/Doorfire.dmi' - icon_state = "frame1" - anchored = FALSE - density = TRUE - var/constructionStep = CONSTRUCTION_NOCIRCUIT - var/reinforced = 0 - -/obj/structure/firelock_frame/examine(mob/user) - . = ..() - switch(constructionStep) - if(CONSTRUCTION_PANEL_OPEN) - . += "It is unbolted from the floor. A small loosely connected metal plate is covering the wires." - if(!reinforced) - . += "It could be reinforced with plasteel." - if(CONSTRUCTION_WIRES_EXPOSED) - . += "The maintenance plate has been pried away, and wires are trailing." - if(CONSTRUCTION_GUTTED) - . += "The maintenance panel is missing wires and the circuit board is loosely connected." - if(CONSTRUCTION_NOCIRCUIT) - . += "There are no firelock electronics in the frame. The frame could be cut apart." - -/obj/structure/firelock_frame/update_icon() - ..() - icon_state = "frame[constructionStep]" - -/obj/structure/firelock_frame/attackby(obj/item/C, mob/user) - switch(constructionStep) - if(CONSTRUCTION_PANEL_OPEN) - if(istype(C, /obj/item/crowbar)) - C.play_tool_sound(src) - user.visible_message("[user] starts prying something out from [src]...", \ - "You begin prying out the wire cover...") - if(!C.use_tool(src, user, 50)) - return - if(constructionStep != CONSTRUCTION_PANEL_OPEN) - return - playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) - user.visible_message("[user] pries out a metal plate from [src], exposing the wires.", \ - "You remove the cover plate from [src], exposing the wires.") - constructionStep = CONSTRUCTION_WIRES_EXPOSED - update_icon() - return - if(istype(C, /obj/item/wrench)) - if(locate(/obj/machinery/door/firedoor) in get_turf(src)) - to_chat(user, "There's already a firelock there.") - return - C.play_tool_sound(src) - user.visible_message("[user] starts bolting down [src]...", \ - "You begin bolting [src]...") - if(!C.use_tool(src, user, 30)) - return - if(locate(/obj/machinery/door/firedoor) in get_turf(src)) - return - user.visible_message("[user] finishes the firelock.", \ - "You finish the firelock.") - playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) - if(reinforced) - new /obj/machinery/door/firedoor/heavy(get_turf(src)) - else - new /obj/machinery/door/firedoor(get_turf(src)) - qdel(src) - return - if(istype(C, /obj/item/stack/sheet/plasteel)) - var/obj/item/stack/sheet/plasteel/P = C - if(reinforced) - to_chat(user, "[src] is already reinforced.") - return - if(P.get_amount() < 2) - to_chat(user, "You need more plasteel to reinforce [src].") - return - user.visible_message("[user] begins reinforcing [src]...", \ - "You begin reinforcing [src]...") - playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) - if(do_after(user, 60, target = src)) - if(constructionStep != CONSTRUCTION_PANEL_OPEN || reinforced || P.get_amount() < 2 || !P) - return - user.visible_message("[user] reinforces [src].", \ - "You reinforce [src].") - playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) - P.use(2) - reinforced = 1 - return - - if(CONSTRUCTION_WIRES_EXPOSED) - if(istype(C, /obj/item/wirecutters)) - C.play_tool_sound(src) - user.visible_message("[user] starts cutting the wires from [src]...", \ - "You begin removing [src]'s wires...") - if(!C.use_tool(src, user, 60)) - return - if(constructionStep != CONSTRUCTION_WIRES_EXPOSED) - return - user.visible_message("[user] removes the wires from [src].", \ - "You remove the wiring from [src], exposing the circuit board.") - new/obj/item/stack/cable_coil(get_turf(src), 5) - constructionStep = CONSTRUCTION_GUTTED - update_icon() - return - if(istype(C, /obj/item/crowbar)) - C.play_tool_sound(src) - user.visible_message("[user] starts prying a metal plate into [src]...", \ - "You begin prying the cover plate back onto [src]...") - if(!C.use_tool(src, user, 80)) - return - if(constructionStep != CONSTRUCTION_WIRES_EXPOSED) - return - playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) - user.visible_message("[user] pries the metal plate into [src].", \ - "You pry [src]'s cover plate into place, hiding the wires.") - constructionStep = CONSTRUCTION_PANEL_OPEN - update_icon() - return - if(CONSTRUCTION_GUTTED) - if(istype(C, /obj/item/crowbar)) - user.visible_message("[user] begins removing the circuit board from [src]...", \ - "You begin prying out the circuit board from [src]...") - if(!C.use_tool(src, user, 50, volume=50)) - return - if(constructionStep != CONSTRUCTION_GUTTED) - return - user.visible_message("[user] removes [src]'s circuit board.", \ - "You remove the circuit board from [src].") - new /obj/item/electronics/firelock(drop_location()) - constructionStep = CONSTRUCTION_NOCIRCUIT - update_icon() - return - if(istype(C, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/B = C - if(B.get_amount() < 5) - to_chat(user, "You need more wires to add wiring to [src].") - return - user.visible_message("[user] begins wiring [src]...", \ - "You begin adding wires to [src]...") - playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) - if(do_after(user, 60, target = src)) - if(constructionStep != CONSTRUCTION_GUTTED || B.get_amount() < 5 || !B) - return - user.visible_message("[user] adds wires to [src].", \ - "You wire [src].") - playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) - B.use(5) - constructionStep = CONSTRUCTION_WIRES_EXPOSED - update_icon() - return - if(CONSTRUCTION_NOCIRCUIT) - if(istype(C, /obj/item/weldingtool)) - if(!C.tool_start_check(user, amount=1)) - return - user.visible_message("[user] begins cutting apart [src]'s frame...", \ - "You begin slicing [src] apart...") - - if(C.use_tool(src, user, 40, volume=50, amount=1)) - if(constructionStep != CONSTRUCTION_NOCIRCUIT) - return - user.visible_message("[user] cuts apart [src]!", \ - "You cut [src] into metal.") - var/turf/T = get_turf(src) - new /obj/item/stack/sheet/metal(T, 3) - if(reinforced) - new /obj/item/stack/sheet/plasteel(T, 2) - qdel(src) - return - if(istype(C, /obj/item/electronics/firelock)) - user.visible_message("[user] starts adding [C] to [src]...", \ - "You begin adding a circuit board to [src]...") - playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) - if(!do_after(user, 40, target = src)) - return - if(constructionStep != CONSTRUCTION_NOCIRCUIT) - return - qdel(C) - user.visible_message("[user] adds a circuit to [src].", \ - "You insert and secure [C].") - playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) - constructionStep = CONSTRUCTION_GUTTED - update_icon() - return - if(istype(C, /obj/item/electroadaptive_pseudocircuit)) - var/obj/item/electroadaptive_pseudocircuit/P = C - if(!P.adapt_circuit(user, 30)) - return - user.visible_message("[user] fabricates a circuit and places it into [src].", \ - "You adapt a firelock circuit and slot it into the assembly.") - constructionStep = CONSTRUCTION_GUTTED - update_icon() - return - return ..() - -/obj/structure/firelock_frame/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) - if((constructionStep == CONSTRUCTION_NOCIRCUIT) && (the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS)) - return list("mode" = RCD_UPGRADE_SIMPLE_CIRCUITS, "delay" = 20, "cost" = 1) - return FALSE - -/obj/structure/firelock_frame/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - switch(passed_mode) - if(RCD_UPGRADE_SIMPLE_CIRCUITS) - user.visible_message("[user] fabricates a circuit and places it into [src].", \ - "You adapt a firelock circuit and slot it into the assembly.") - constructionStep = CONSTRUCTION_GUTTED - update_icon() - return TRUE - return FALSE - -/obj/structure/firelock_frame/heavy - name = "heavy firelock frame" - reinforced = TRUE - -#undef CONSTRUCTION_COMPLETE -#undef CONSTRUCTION_PANEL_OPEN -#undef CONSTRUCTION_WIRES_EXPOSED -#undef CONSTRUCTION_GUTTED -#undef CONSTRUCTION_NOCIRCUIT +#define CONSTRUCTION_COMPLETE 0 //No construction done - functioning as normal +#define CONSTRUCTION_PANEL_OPEN 1 //Maintenance panel is open, still functioning +#define CONSTRUCTION_WIRES_EXPOSED 2 //Cover plate is removed, wires are available +#define CONSTRUCTION_GUTTED 3 //Wires are removed, circuit ready to remove +#define CONSTRUCTION_NOCIRCUIT 4 //Circuit board removed, can safely weld apart + +/obj/machinery/door/firedoor + name = "firelock" + desc = "Apply crowbar." + icon = 'icons/obj/doors/Doorfireglass.dmi' + icon_state = "door_open" + opacity = FALSE + density = FALSE + max_integrity = 300 + resistance_flags = FIRE_PROOF + heat_proof = TRUE + glass = TRUE + sub_door = TRUE + explosion_block = 1 + safe = FALSE + layer = BELOW_OPEN_DOOR_LAYER + closingLayer = CLOSED_FIREDOOR_LAYER + assemblytype = /obj/structure/firelock_frame + armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 70) + interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN + var/nextstate = null + var/boltslocked = TRUE + var/list/affecting_areas + +/obj/machinery/door/firedoor/Initialize() + . = ..() + CalculateAffectingAreas() + +/obj/machinery/door/firedoor/examine(mob/user) + ..() + if(!density) + . += "It is open, but could be pried closed." + else if(!welded) + . += "It is closed, but could be pried open. Deconstruction would require it to be welded shut." + else if(boltslocked) + . += "It is welded shut. The floor bolts have been locked by screws." + else + . += "The bolt locks have been unscrewed, but the bolts themselves are still wrenched to the floor." + +/obj/machinery/door/firedoor/proc/CalculateAffectingAreas() + remove_from_areas() + affecting_areas = get_adjacent_open_areas(src) | get_area(src) + for(var/I in affecting_areas) + var/area/A = I + LAZYADD(A.firedoors, src) + +/obj/machinery/door/firedoor/closed + icon_state = "door_closed" + opacity = TRUE + density = TRUE + +//see also turf/AfterChange for adjacency shennanigans + +/obj/machinery/door/firedoor/proc/remove_from_areas() + if(affecting_areas) + for(var/I in affecting_areas) + var/area/A = I + LAZYREMOVE(A.firedoors, src) + +/obj/machinery/door/firedoor/Destroy() + remove_from_areas() + affecting_areas.Cut() + return ..() + +/obj/machinery/door/firedoor/Bumped(atom/movable/AM) + if(panel_open || operating) + return + if(!density) + return ..() + return FALSE + + +/obj/machinery/door/firedoor/power_change() + if(powered(power_channel)) + stat &= ~NOPOWER + latetoggle() + else + stat |= NOPOWER + +/obj/machinery/door/firedoor/attack_hand(mob/user) + . = ..() + if(.) + return + if(operating || !density) + return + user.changeNext_move(CLICK_CD_MELEE) + + user.visible_message("[user] bangs on \the [src].", + "You bang on \the [src].") + playsound(loc, 'sound/effects/glassknock.ogg', 10, FALSE, frequency = 32000) + +/obj/machinery/door/firedoor/attackby(obj/item/C, mob/user, params) + add_fingerprint(user) + if(operating) + return + + if(welded) + if(istype(C, /obj/item/wrench)) + if(boltslocked) + to_chat(user, "There are screws locking the bolts in place!") + return + C.play_tool_sound(src) + user.visible_message("[user] starts undoing [src]'s bolts...", \ + "You start unfastening [src]'s floor bolts...") + if(!C.use_tool(src, user, 50)) + return + playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) + user.visible_message("[user] unfastens [src]'s bolts.", \ + "You undo [src]'s floor bolts.") + deconstruct(TRUE) + return + if(istype(C, /obj/item/screwdriver)) + user.visible_message("[user] [boltslocked ? "unlocks" : "locks"] [src]'s bolts.", \ + "You [boltslocked ? "unlock" : "lock"] [src]'s floor bolts.") + C.play_tool_sound(src) + boltslocked = !boltslocked + return + + return ..() + +/obj/machinery/door/firedoor/try_to_activate_door(mob/user) + return + +/obj/machinery/door/firedoor/try_to_weld(obj/item/weldingtool/W, mob/user) + if(!W.tool_start_check(user, amount=0)) + return + user.visible_message("[user] starts [welded ? "unwelding" : "welding"] [src].", "You start welding [src].") + if(W.use_tool(src, user, 40, volume=50)) + welded = !welded + to_chat(user, "[user] [welded?"welds":"unwelds"] [src].", "You [welded ? "weld" : "unweld"] [src].") + update_icon() + +/obj/machinery/door/firedoor/try_to_crowbar(obj/item/I, mob/user) + if(welded || operating) + return + + if(density) + open() + else + close() + +/obj/machinery/door/firedoor/attack_ai(mob/user) + add_fingerprint(user) + if(welded || operating || stat & NOPOWER) + return TRUE + if(density) + open() + else + close() + return TRUE + +/obj/machinery/door/firedoor/attack_robot(mob/user) + return attack_ai(user) + +/obj/machinery/door/firedoor/attack_alien(mob/user) + add_fingerprint(user) + if(welded) + to_chat(user, "[src] refuses to budge!") + return + open() + +/obj/machinery/door/firedoor/do_animate(animation) + switch(animation) + if("opening") + flick("door_opening", src) + if("closing") + flick("door_closing", src) + +/obj/machinery/door/firedoor/update_icon() + cut_overlays() + if(density) + icon_state = "door_closed" + if(welded) + add_overlay("welded") + else + icon_state = "door_open" + if(welded) + add_overlay("welded_open") + +/obj/machinery/door/firedoor/open() + . = ..() + latetoggle() + +/obj/machinery/door/firedoor/close() + . = ..() + latetoggle() + +/obj/machinery/door/firedoor/deconstruct(disassembled = TRUE) + if(!(flags_1 & NODECONSTRUCT_1)) + var/obj/structure/firelock_frame/F = new assemblytype(get_turf(src)) + if(disassembled) + F.constructionStep = CONSTRUCTION_PANEL_OPEN + else + F.constructionStep = CONSTRUCTION_WIRES_EXPOSED + F.obj_integrity = F.max_integrity * 0.5 + F.update_icon() + qdel(src) + + +/obj/machinery/door/firedoor/proc/latetoggle() + if(operating || stat & NOPOWER || !nextstate) + return + switch(nextstate) + if(FIREDOOR_OPEN) + nextstate = null + open() + if(FIREDOOR_CLOSED) + nextstate = null + close() + +/obj/machinery/door/firedoor/border_only + icon = 'icons/obj/doors/edge_Doorfire.dmi' + flags_1 = ON_BORDER_1 + CanAtmosPass = ATMOS_PASS_PROC + +/obj/machinery/door/firedoor/border_only/closed + icon_state = "door_closed" + opacity = TRUE + density = TRUE + +/obj/machinery/door/firedoor/border_only/CanPass(atom/movable/mover, turf/target) + if(istype(mover) && (mover.pass_flags & PASSGLASS)) + return TRUE + if(get_dir(loc, target) == dir) //Make sure looking at appropriate border + return !density + else + return TRUE + +/obj/machinery/door/firedoor/border_only/CheckExit(atom/movable/mover as mob|obj, turf/target) + if(istype(mover) && (mover.pass_flags & PASSGLASS)) + return TRUE + if(get_dir(loc, target) == dir) + return !density + else + return TRUE + +/obj/machinery/door/firedoor/border_only/CanAtmosPass(turf/T) + if(get_dir(loc, T) == dir) + return !density + else + return TRUE + +/obj/machinery/door/firedoor/heavy + name = "heavy firelock" + icon = 'icons/obj/doors/Doorfire.dmi' + glass = FALSE + explosion_block = 2 + assemblytype = /obj/structure/firelock_frame/heavy + max_integrity = 550 + + +/obj/item/electronics/firelock + name = "firelock circuitry" + desc = "A circuit board used in construction of firelocks." + icon_state = "mainboard" + +/obj/structure/firelock_frame + name = "firelock frame" + desc = "A partially completed firelock." + icon = 'icons/obj/doors/Doorfire.dmi' + icon_state = "frame1" + anchored = FALSE + density = TRUE + var/constructionStep = CONSTRUCTION_NOCIRCUIT + var/reinforced = 0 + +/obj/structure/firelock_frame/examine(mob/user) + . = ..() + switch(constructionStep) + if(CONSTRUCTION_PANEL_OPEN) + . += "It is unbolted from the floor. A small loosely connected metal plate is covering the wires." + if(!reinforced) + . += "It could be reinforced with plasteel." + if(CONSTRUCTION_WIRES_EXPOSED) + . += "The maintenance plate has been pried away, and wires are trailing." + if(CONSTRUCTION_GUTTED) + . += "The maintenance panel is missing wires and the circuit board is loosely connected." + if(CONSTRUCTION_NOCIRCUIT) + . += "There are no firelock electronics in the frame. The frame could be cut apart." + +/obj/structure/firelock_frame/update_icon() + ..() + icon_state = "frame[constructionStep]" + +/obj/structure/firelock_frame/attackby(obj/item/C, mob/user) + switch(constructionStep) + if(CONSTRUCTION_PANEL_OPEN) + if(istype(C, /obj/item/crowbar)) + C.play_tool_sound(src) + user.visible_message("[user] starts prying something out from [src]...", \ + "You begin prying out the wire cover...") + if(!C.use_tool(src, user, 50)) + return + if(constructionStep != CONSTRUCTION_PANEL_OPEN) + return + playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) + user.visible_message("[user] pries out a metal plate from [src], exposing the wires.", \ + "You remove the cover plate from [src], exposing the wires.") + constructionStep = CONSTRUCTION_WIRES_EXPOSED + update_icon() + return + if(istype(C, /obj/item/wrench)) + if(locate(/obj/machinery/door/firedoor) in get_turf(src)) + to_chat(user, "There's already a firelock there.") + return + C.play_tool_sound(src) + user.visible_message("[user] starts bolting down [src]...", \ + "You begin bolting [src]...") + if(!C.use_tool(src, user, 30)) + return + if(locate(/obj/machinery/door/firedoor) in get_turf(src)) + return + user.visible_message("[user] finishes the firelock.", \ + "You finish the firelock.") + playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) + if(reinforced) + new /obj/machinery/door/firedoor/heavy(get_turf(src)) + else + new /obj/machinery/door/firedoor(get_turf(src)) + qdel(src) + return + if(istype(C, /obj/item/stack/sheet/plasteel)) + var/obj/item/stack/sheet/plasteel/P = C + if(reinforced) + to_chat(user, "[src] is already reinforced.") + return + if(P.get_amount() < 2) + to_chat(user, "You need more plasteel to reinforce [src].") + return + user.visible_message("[user] begins reinforcing [src]...", \ + "You begin reinforcing [src]...") + playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) + if(do_after(user, 60, target = src)) + if(constructionStep != CONSTRUCTION_PANEL_OPEN || reinforced || P.get_amount() < 2 || !P) + return + user.visible_message("[user] reinforces [src].", \ + "You reinforce [src].") + playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) + P.use(2) + reinforced = 1 + return + + if(CONSTRUCTION_WIRES_EXPOSED) + if(istype(C, /obj/item/wirecutters)) + C.play_tool_sound(src) + user.visible_message("[user] starts cutting the wires from [src]...", \ + "You begin removing [src]'s wires...") + if(!C.use_tool(src, user, 60)) + return + if(constructionStep != CONSTRUCTION_WIRES_EXPOSED) + return + user.visible_message("[user] removes the wires from [src].", \ + "You remove the wiring from [src], exposing the circuit board.") + new/obj/item/stack/cable_coil(get_turf(src), 5) + constructionStep = CONSTRUCTION_GUTTED + update_icon() + return + if(istype(C, /obj/item/crowbar)) + C.play_tool_sound(src) + user.visible_message("[user] starts prying a metal plate into [src]...", \ + "You begin prying the cover plate back onto [src]...") + if(!C.use_tool(src, user, 80)) + return + if(constructionStep != CONSTRUCTION_WIRES_EXPOSED) + return + playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) + user.visible_message("[user] pries the metal plate into [src].", \ + "You pry [src]'s cover plate into place, hiding the wires.") + constructionStep = CONSTRUCTION_PANEL_OPEN + update_icon() + return + if(CONSTRUCTION_GUTTED) + if(istype(C, /obj/item/crowbar)) + user.visible_message("[user] begins removing the circuit board from [src]...", \ + "You begin prying out the circuit board from [src]...") + if(!C.use_tool(src, user, 50, volume=50)) + return + if(constructionStep != CONSTRUCTION_GUTTED) + return + user.visible_message("[user] removes [src]'s circuit board.", \ + "You remove the circuit board from [src].") + new /obj/item/electronics/firelock(drop_location()) + constructionStep = CONSTRUCTION_NOCIRCUIT + update_icon() + return + if(istype(C, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/B = C + if(B.get_amount() < 5) + to_chat(user, "You need more wires to add wiring to [src].") + return + user.visible_message("[user] begins wiring [src]...", \ + "You begin adding wires to [src]...") + playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) + if(do_after(user, 60, target = src)) + if(constructionStep != CONSTRUCTION_GUTTED || B.get_amount() < 5 || !B) + return + user.visible_message("[user] adds wires to [src].", \ + "You wire [src].") + playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) + B.use(5) + constructionStep = CONSTRUCTION_WIRES_EXPOSED + update_icon() + return + if(CONSTRUCTION_NOCIRCUIT) + if(istype(C, /obj/item/weldingtool)) + if(!C.tool_start_check(user, amount=1)) + return + user.visible_message("[user] begins cutting apart [src]'s frame...", \ + "You begin slicing [src] apart...") + + if(C.use_tool(src, user, 40, volume=50, amount=1)) + if(constructionStep != CONSTRUCTION_NOCIRCUIT) + return + user.visible_message("[user] cuts apart [src]!", \ + "You cut [src] into metal.") + var/turf/T = get_turf(src) + new /obj/item/stack/sheet/metal(T, 3) + if(reinforced) + new /obj/item/stack/sheet/plasteel(T, 2) + qdel(src) + return + if(istype(C, /obj/item/electronics/firelock)) + user.visible_message("[user] starts adding [C] to [src]...", \ + "You begin adding a circuit board to [src]...") + playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) + if(!do_after(user, 40, target = src)) + return + if(constructionStep != CONSTRUCTION_NOCIRCUIT) + return + qdel(C) + user.visible_message("[user] adds a circuit to [src].", \ + "You insert and secure [C].") + playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1) + constructionStep = CONSTRUCTION_GUTTED + update_icon() + return + if(istype(C, /obj/item/electroadaptive_pseudocircuit)) + var/obj/item/electroadaptive_pseudocircuit/P = C + if(!P.adapt_circuit(user, 30)) + return + user.visible_message("[user] fabricates a circuit and places it into [src].", \ + "You adapt a firelock circuit and slot it into the assembly.") + constructionStep = CONSTRUCTION_GUTTED + update_icon() + return + return ..() + +/obj/structure/firelock_frame/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) + if((constructionStep == CONSTRUCTION_NOCIRCUIT) && (the_rcd.upgrade & RCD_UPGRADE_SIMPLE_CIRCUITS)) + return list("mode" = RCD_UPGRADE_SIMPLE_CIRCUITS, "delay" = 20, "cost" = 1) + return FALSE + +/obj/structure/firelock_frame/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) + switch(passed_mode) + if(RCD_UPGRADE_SIMPLE_CIRCUITS) + user.visible_message("[user] fabricates a circuit and places it into [src].", \ + "You adapt a firelock circuit and slot it into the assembly.") + constructionStep = CONSTRUCTION_GUTTED + update_icon() + return TRUE + return FALSE + +/obj/structure/firelock_frame/heavy + name = "heavy firelock frame" + reinforced = TRUE + +#undef CONSTRUCTION_COMPLETE +#undef CONSTRUCTION_PANEL_OPEN +#undef CONSTRUCTION_WIRES_EXPOSED +#undef CONSTRUCTION_GUTTED +#undef CONSTRUCTION_NOCIRCUIT diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index ebc1e94e97..af95ee230c 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -1,91 +1,91 @@ -/obj/machinery/door/poddoor - name = "blast door" - desc = "A heavy duty blast door that opens mechanically." - icon = 'icons/obj/doors/blastdoor.dmi' - icon_state = "closed" - var/id = 1 - layer = BLASTDOOR_LAYER - closingLayer = CLOSED_BLASTDOOR_LAYER - sub_door = TRUE - explosion_block = 3 - heat_proof = TRUE - safe = FALSE - max_integrity = 600 - armor = list("melee" = 50, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 70) - resistance_flags = FIRE_PROOF - damage_deflection = 70 - poddoor = TRUE - -/obj/machinery/door/poddoor/preopen - icon_state = "open" - density = FALSE - opacity = 0 - -/obj/machinery/door/poddoor/ert - desc = "A heavy duty blast door that only opens for dire emergencies." - -//special poddoors that open when emergency shuttle docks at centcom -/obj/machinery/door/poddoor/shuttledock - var/checkdir = 4 //door won't open if turf in this dir is `turftype` - var/turftype = /turf/open/space - -/obj/machinery/door/poddoor/shuttledock/proc/check() - var/turf/T = get_step(src, checkdir) - if(!istype(T, turftype)) - INVOKE_ASYNC(src, .proc/open) - else - INVOKE_ASYNC(src, .proc/close) - -/obj/machinery/door/poddoor/incinerator_toxmix - name = "combustion chamber vent" - id = INCINERATOR_TOXMIX_VENT - -/obj/machinery/door/poddoor/incinerator_atmos_main - name = "turbine vent" - id = INCINERATOR_ATMOS_MAINVENT - -/obj/machinery/door/poddoor/incinerator_atmos_aux - name = "combustion chamber vent" - id = INCINERATOR_ATMOS_AUXVENT - -/obj/machinery/door/poddoor/incinerator_syndicatelava_main - name = "turbine vent" - id = INCINERATOR_SYNDICATELAVA_MAINVENT - -/obj/machinery/door/poddoor/incinerator_syndicatelava_aux - name = "combustion chamber vent" - id = INCINERATOR_SYNDICATELAVA_AUXVENT - -/obj/machinery/door/poddoor/Bumped(atom/movable/AM) - if(density) - return 0 - else - return ..() - -//"BLAST" doors are obviously stronger than regular doors when it comes to BLASTS. -/obj/machinery/door/poddoor/ex_act(severity, target) - if(severity == 3) - return - ..() - -/obj/machinery/door/poddoor/do_animate(animation) - switch(animation) - if("opening") - flick("opening", src) - playsound(src, 'sound/machines/blastdoor.ogg', 30, 1) - if("closing") - flick("closing", src) - playsound(src, 'sound/machines/blastdoor.ogg', 30, 1) - -/obj/machinery/door/poddoor/update_icon() - if(density) - icon_state = "closed" - else - icon_state = "open" - -/obj/machinery/door/poddoor/try_to_activate_door(mob/user) - return - -/obj/machinery/door/poddoor/try_to_crowbar(obj/item/I, mob/user) - if(stat & NOPOWER) - open(1) +/obj/machinery/door/poddoor + name = "blast door" + desc = "A heavy duty blast door that opens mechanically." + icon = 'icons/obj/doors/blastdoor.dmi' + icon_state = "closed" + var/id = 1 + layer = BLASTDOOR_LAYER + closingLayer = CLOSED_BLASTDOOR_LAYER + sub_door = TRUE + explosion_block = 3 + heat_proof = TRUE + safe = FALSE + max_integrity = 600 + armor = list("melee" = 50, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 70) + resistance_flags = FIRE_PROOF + damage_deflection = 70 + poddoor = TRUE + +/obj/machinery/door/poddoor/preopen + icon_state = "open" + density = FALSE + opacity = 0 + +/obj/machinery/door/poddoor/ert + desc = "A heavy duty blast door that only opens for dire emergencies." + +//special poddoors that open when emergency shuttle docks at centcom +/obj/machinery/door/poddoor/shuttledock + var/checkdir = 4 //door won't open if turf in this dir is `turftype` + var/turftype = /turf/open/space + +/obj/machinery/door/poddoor/shuttledock/proc/check() + var/turf/T = get_step(src, checkdir) + if(!istype(T, turftype)) + INVOKE_ASYNC(src, .proc/open) + else + INVOKE_ASYNC(src, .proc/close) + +/obj/machinery/door/poddoor/incinerator_toxmix + name = "combustion chamber vent" + id = INCINERATOR_TOXMIX_VENT + +/obj/machinery/door/poddoor/incinerator_atmos_main + name = "turbine vent" + id = INCINERATOR_ATMOS_MAINVENT + +/obj/machinery/door/poddoor/incinerator_atmos_aux + name = "combustion chamber vent" + id = INCINERATOR_ATMOS_AUXVENT + +/obj/machinery/door/poddoor/incinerator_syndicatelava_main + name = "turbine vent" + id = INCINERATOR_SYNDICATELAVA_MAINVENT + +/obj/machinery/door/poddoor/incinerator_syndicatelava_aux + name = "combustion chamber vent" + id = INCINERATOR_SYNDICATELAVA_AUXVENT + +/obj/machinery/door/poddoor/Bumped(atom/movable/AM) + if(density) + return 0 + else + return ..() + +//"BLAST" doors are obviously stronger than regular doors when it comes to BLASTS. +/obj/machinery/door/poddoor/ex_act(severity, target) + if(severity == 3) + return + ..() + +/obj/machinery/door/poddoor/do_animate(animation) + switch(animation) + if("opening") + flick("opening", src) + playsound(src, 'sound/machines/blastdoor.ogg', 30, 1) + if("closing") + flick("closing", src) + playsound(src, 'sound/machines/blastdoor.ogg', 30, 1) + +/obj/machinery/door/poddoor/update_icon() + if(density) + icon_state = "closed" + else + icon_state = "open" + +/obj/machinery/door/poddoor/try_to_activate_door(mob/user) + return + +/obj/machinery/door/poddoor/try_to_crowbar(obj/item/I, mob/user) + if(stat & NOPOWER) + open(1) diff --git a/code/game/machinery/doors/shutters.dm b/code/game/machinery/doors/shutters.dm index 7ee9891c4c..bd58649b97 100644 --- a/code/game/machinery/doors/shutters.dm +++ b/code/game/machinery/doors/shutters.dm @@ -1,13 +1,13 @@ -/obj/machinery/door/poddoor/shutters - gender = PLURAL - name = "shutters" - desc = "Heavy duty metal shutters that open mechanically." - icon = 'icons/obj/doors/shutters.dmi' - layer = SHUTTER_LAYER - closingLayer = SHUTTER_LAYER - damage_deflection = 20 - -/obj/machinery/door/poddoor/shutters/preopen - icon_state = "open" - density = FALSE - opacity = 0 +/obj/machinery/door/poddoor/shutters + gender = PLURAL + name = "shutters" + desc = "Heavy duty metal shutters that open mechanically." + icon = 'icons/obj/doors/shutters.dmi' + layer = SHUTTER_LAYER + closingLayer = SHUTTER_LAYER + damage_deflection = 20 + +/obj/machinery/door/poddoor/shutters/preopen + icon_state = "open" + density = FALSE + opacity = 0 diff --git a/code/game/machinery/doors/unpowered.dm b/code/game/machinery/doors/unpowered.dm index 702f700617..828624adb4 100644 --- a/code/game/machinery/doors/unpowered.dm +++ b/code/game/machinery/doors/unpowered.dm @@ -1,22 +1,22 @@ -/obj/machinery/door/unpowered - -/obj/machinery/door/unpowered/Bumped(atom/movable/AM) - if(src.locked) - return - ..() - return - - -/obj/machinery/door/unpowered/attackby(obj/item/I, mob/user, params) - if(locked) - return - else - return ..() - -/obj/machinery/door/unpowered/shuttle - icon = 'icons/turf/shuttle.dmi' - name = "door" - icon_state = "door1" - opacity = 1 - density = TRUE +/obj/machinery/door/unpowered + +/obj/machinery/door/unpowered/Bumped(atom/movable/AM) + if(src.locked) + return + ..() + return + + +/obj/machinery/door/unpowered/attackby(obj/item/I, mob/user, params) + if(locked) + return + else + return ..() + +/obj/machinery/door/unpowered/shuttle + icon = 'icons/turf/shuttle.dmi' + name = "door" + icon_state = "door1" + opacity = 1 + density = TRUE explosion_block = 1 \ No newline at end of file diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 933bb4f42a..bd9b7325fb 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -1,535 +1,535 @@ -/obj/machinery/door/window - name = "interior door" - desc = "A strong door." - icon = 'icons/obj/doors/windoor.dmi' - icon_state = "left" - layer = ABOVE_WINDOW_LAYER - closingLayer = ABOVE_WINDOW_LAYER - resistance_flags = ACID_PROOF - var/base_state = "left" - max_integrity = 150 //If you change this, consider changing ../door/window/brigdoor/ max_integrity at the bottom of this .dm file - integrity_failure = 0 - armor = list("melee" = 20, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 70, "acid" = 100) - visible = FALSE - flags_1 = ON_BORDER_1 - opacity = 0 - CanAtmosPass = ATMOS_PASS_PROC - interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN - var/obj/item/electronics/airlock/electronics = null - var/reinf = 0 - var/shards = 2 - var/rods = 2 - var/cable = 1 - var/list/debris = list() - -/obj/machinery/door/window/Initialize(mapload, set_dir) - . = ..() - if(set_dir) - setDir(set_dir) - if(src.req_access && src.req_access.len) - src.icon_state = "[src.icon_state]" - src.base_state = src.icon_state - for(var/i in 1 to shards) - debris += new /obj/item/shard(src) - if(rods) - debris += new /obj/item/stack/rods(src, rods) - if(cable) - debris += new /obj/item/stack/cable_coil(src, cable) - -/obj/machinery/door/window/ComponentInitialize() - . = ..() - AddComponent(/datum/component/ntnet_interface) - -/obj/machinery/door/window/Destroy() - density = FALSE - QDEL_LIST(debris) - if(obj_integrity == 0) - playsound(src, "shatter", 70, 1) - electronics = null - return ..() - -/obj/machinery/door/window/update_icon() - if(density) - icon_state = base_state - else - icon_state = "[src.base_state]open" - -/obj/machinery/door/window/proc/open_and_close() - open() - if(src.check_access(null)) - sleep(50) - else //secure doors close faster - sleep(20) - close() - -/obj/machinery/door/window/Bumped(atom/movable/AM) - if( operating || !src.density ) - return - if (!( ismob(AM) )) - if(ismecha(AM)) - var/obj/mecha/mecha = AM - if(mecha.occupant && src.allowed(mecha.occupant)) - open_and_close() - else - do_animate("deny") - return - if (!( SSticker )) - return - var/mob/M = AM - if(M.restrained() || ((isdrone(M) || iscyborg(M)) && M.stat)) - return - bumpopen(M) - -/obj/machinery/door/window/bumpopen(mob/user) - if( operating || !src.density ) - return - src.add_fingerprint(user) - if(!src.requiresID()) - user = null - - if(allowed(user)) - open_and_close() - else - do_animate("deny") - return - -/obj/machinery/door/window/CanPass(atom/movable/mover, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGLASS)) - return 1 - if(get_dir(loc, target) == dir) //Make sure looking at appropriate border - return !density - if(istype(mover, /obj/structure/window)) - var/obj/structure/window/W = mover - if(!valid_window_location(loc, W.ini_dir)) - return FALSE - else if(istype(mover, /obj/structure/windoor_assembly)) - var/obj/structure/windoor_assembly/W = mover - if(!valid_window_location(loc, W.ini_dir)) - return FALSE - else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir)) - return FALSE - else - return 1 - -/obj/machinery/door/window/CanAtmosPass(turf/T) - if(get_dir(loc, T) == dir) - return !density - else - return 1 - -//used in the AStar algorithm to determinate if the turf the door is on is passable -/obj/machinery/door/window/CanAStarPass(obj/item/card/id/ID, to_dir) - return !density || (dir != to_dir) || (check_access(ID) && hasPower()) - -/obj/machinery/door/window/CheckExit(atom/movable/mover as mob|obj, turf/target) - if(istype(mover) && (mover.pass_flags & PASSGLASS)) - return 1 - if(get_dir(loc, target) == dir) - return !density - else - return 1 - -/obj/machinery/door/window/open(forced=0) - if (src.operating == 1) //doors can still open when emag-disabled - return 0 - if(!forced) - if(!hasPower()) - return 0 - if(forced < 2) - if(obj_flags & EMAGGED) - return 0 - if(!src.operating) //in case of emag - operating = TRUE - do_animate("opening") - playsound(src.loc, 'sound/machines/windowdoor.ogg', 100, 1) - src.icon_state ="[src.base_state]open" - sleep(10) - - density = FALSE -// src.sd_set_opacity(0) //TODO: why is this here? Opaque windoors? ~Carn - air_update_turf(1) - update_freelook_sight() - - if(operating == 1) //emag again - operating = FALSE - return 1 - -/obj/machinery/door/window/close(forced=0) - if (src.operating) - return 0 - if(!forced) - if(!hasPower()) - return 0 - if(forced < 2) - if(obj_flags & EMAGGED) - return 0 - operating = TRUE - do_animate("closing") - playsound(src.loc, 'sound/machines/windowdoor.ogg', 100, 1) - src.icon_state = src.base_state - - density = TRUE - air_update_turf(1) - update_freelook_sight() - sleep(10) - - operating = FALSE - return 1 - -/obj/machinery/door/window/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - switch(damage_type) - if(BRUTE) - playsound(loc, 'sound/effects/glasshit.ogg', 90, 1) - if(BURN) - playsound(src.loc, 'sound/items/welder.ogg', 100, 1) - - -/obj/machinery/door/window/deconstruct(disassembled = TRUE) - if(!(flags_1 & NODECONSTRUCT_1) && !disassembled) - for(var/obj/fragment in debris) - fragment.forceMove(get_turf(src)) - transfer_fingerprints_to(fragment) - debris -= fragment - qdel(src) - -/obj/machinery/door/window/narsie_act() - add_atom_colour("#7D1919", FIXED_COLOUR_PRIORITY) - -/obj/machinery/door/window/ratvar_act() - var/obj/machinery/door/window/clockwork/C = new(loc, dir) - C.name = name - qdel(src) - -/obj/machinery/door/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - if(exposed_temperature > T0C + (reinf ? 1600 : 800)) - take_damage(round(exposed_volume / 200), BURN, 0, 0) - ..() - -/obj/machinery/door/window/emag_act(mob/user) - . = ..() - if(operating || !density || obj_flags & EMAGGED) - return - obj_flags |= EMAGGED - operating = TRUE - flick("[src.base_state]spark", src) - playsound(src, "sparks", 75, 1) - addtimer(CALLBACK(src, .proc/open_windows_me), 6) - return TRUE - -/obj/machinery/door/window/proc/open_windows_me() - operating = FALSE - desc += "
      Its access panel is smoking slightly." - open(2) - -/obj/machinery/door/window/attackby(obj/item/I, mob/living/user, params) - - if(operating) - return - - add_fingerprint(user) - if(!(flags_1&NODECONSTRUCT_1)) - if(istype(I, /obj/item/screwdriver)) - if(density || operating) - to_chat(user, "You need to open the door to access the maintenance panel!") - return - I.play_tool_sound(src) - panel_open = !panel_open - to_chat(user, "You [panel_open ? "open":"close"] the maintenance panel of the [src.name].") - return - - if(istype(I, /obj/item/crowbar)) - if(panel_open && !density && !operating) - user.visible_message("[user] removes the electronics from the [src.name].", \ - "You start to remove electronics from the [src.name]...") - if(I.use_tool(src, user, 40, volume=50)) - if(panel_open && !density && !operating && src.loc) - var/obj/structure/windoor_assembly/WA = new /obj/structure/windoor_assembly(src.loc) - switch(base_state) - if("left") - WA.facing = "l" - if("right") - WA.facing = "r" - if("leftsecure") - WA.facing = "l" - WA.secure = TRUE - if("rightsecure") - WA.facing = "r" - WA.secure = TRUE - WA.setAnchored(TRUE) - WA.state= "02" - WA.setDir(src.dir) - WA.ini_dir = src.dir - WA.update_icon() - WA.created_name = src.name - - if(obj_flags & EMAGGED) - to_chat(user, "You discard the damaged electronics.") - qdel(src) - return - - to_chat(user, "You remove the airlock electronics.") - - var/obj/item/electronics/airlock/ae - if(!electronics) - ae = new/obj/item/electronics/airlock( src.loc ) - if(req_one_access) - ae.one_access = 1 - ae.accesses = src.req_one_access - else - ae.accesses = src.req_access - else - ae = electronics - electronics = null - ae.forceMove(drop_location()) - - qdel(src) - return - return ..() - -/obj/machinery/door/window/interact(mob/user) //for sillycones - try_to_activate_door(user) - -/obj/machinery/door/window/try_to_crowbar(obj/item/I, mob/user) - if(!hasPower()) - if(density) - open(2) - else - close(2) - else - to_chat(user, "The door's motors resist your efforts to force it!") - -/obj/machinery/door/window/do_animate(animation) - switch(animation) - if("opening") - flick("[src.base_state]opening", src) - if("closing") - flick("[src.base_state]closing", src) - if("deny") - flick("[src.base_state]deny", src) - -/obj/machinery/door/window/check_access_ntnet(datum/netdata/data) - return !requiresID() || ..() - -/obj/machinery/door/window/ntnet_receive(datum/netdata/data) - // Check if the airlock is powered. - if(!hasPower()) - return - - // Check packet access level. - if(!check_access_ntnet(data)) - return - - // Handle received packet. - var/command = lowertext(data.data["data"]) - var/command_value = lowertext(data.data["data_secondary"]) - switch(command) - if("open") - if(command_value == "on" && !density) - return - - if(command_value == "off" && density) - return - - if(density) - INVOKE_ASYNC(src, .proc/open) - else - INVOKE_ASYNC(src, .proc/close) - if("touch") - INVOKE_ASYNC(src, .proc/open_and_close) - -/obj/machinery/door/window/brigdoor - name = "secure door" - icon_state = "leftsecure" - base_state = "leftsecure" - var/id = null - max_integrity = 300 //Stronger doors for prison (regular window door health is 200) - reinf = 1 - explosion_block = 1 - -/obj/machinery/door/window/brigdoor/security/cell - name = "cell door" - desc = "For keeping in criminal scum." - req_access = list(ACCESS_BRIG) - -/obj/machinery/door/window/brigdoor/security/holding - name = "holding cell door" - req_one_access = list(ACCESS_SEC_DOORS, ACCESS_LAWYER) //love for the lawyer - -/obj/machinery/door/window/clockwork - name = "brass windoor" - desc = "A thin door with translucent brass paneling." - icon_state = "clockwork" - base_state = "clockwork" - shards = 0 - rods = 0 - resistance_flags = FIRE_PROOF | ACID_PROOF - var/made_glow = FALSE - -/obj/machinery/door/window/clockwork/Initialize(mapload, set_dir) - . = ..() - for(var/i in 1 to 2) - debris += new/obj/item/clockwork/alloy_shards/medium/gear_bit/large(src) - change_construction_value(2) - -/obj/machinery/door/window/clockwork/setDir(direct) - if(!made_glow) - var/obj/effect/E = new /obj/effect/temp_visual/ratvar/door/window(get_turf(src)) - E.setDir(direct) - made_glow = TRUE - ..() - -/obj/machinery/door/window/clockwork/Destroy() - change_construction_value(-2) - return ..() - -/obj/machinery/door/window/clockwork/emp_act(severity) - if(prob(80/severity)) - open() - -/obj/machinery/door/window/clockwork/ratvar_act() - if(GLOB.ratvar_awakens) - obj_integrity = max_integrity - -/obj/machinery/door/window/clockwork/hasPower() - return TRUE //yup that's power all right - -/obj/machinery/door/window/clockwork/narsie_act() - take_damage(rand(30, 60), BRUTE) - if(src) - var/previouscolor = color - color = "#960000" - animate(src, color = previouscolor, time = 8) - addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8) - -/obj/machinery/door/window/clockwork/allowed(mob/M) - if(is_servant_of_ratvar(M)) - return 1 - return 0 - -/obj/machinery/door/window/northleft - dir = NORTH - -/obj/machinery/door/window/eastleft - dir = EAST - -/obj/machinery/door/window/westleft - dir = WEST - -/obj/machinery/door/window/southleft - dir = SOUTH - -/obj/machinery/door/window/northright - dir = NORTH - icon_state = "right" - base_state = "right" - -/obj/machinery/door/window/eastright - dir = EAST - icon_state = "right" - base_state = "right" - -/obj/machinery/door/window/westright - dir = WEST - icon_state = "right" - base_state = "right" - -/obj/machinery/door/window/southright - dir = SOUTH - icon_state = "right" - base_state = "right" - -/obj/machinery/door/window/brigdoor/northleft - dir = NORTH - -/obj/machinery/door/window/brigdoor/eastleft - dir = EAST - -/obj/machinery/door/window/brigdoor/westleft - dir = WEST - -/obj/machinery/door/window/brigdoor/southleft - dir = SOUTH - -/obj/machinery/door/window/brigdoor/northright - dir = NORTH - icon_state = "rightsecure" - base_state = "rightsecure" - -/obj/machinery/door/window/brigdoor/eastright - dir = EAST - icon_state = "rightsecure" - base_state = "rightsecure" - -/obj/machinery/door/window/brigdoor/westright - dir = WEST - icon_state = "rightsecure" - base_state = "rightsecure" - -/obj/machinery/door/window/brigdoor/southright - dir = SOUTH - icon_state = "rightsecure" - base_state = "rightsecure" - -/obj/machinery/door/window/brigdoor/security/cell/northleft - dir = NORTH - -/obj/machinery/door/window/brigdoor/security/cell/eastleft - dir = EAST - -/obj/machinery/door/window/brigdoor/security/cell/westleft - dir = WEST - -/obj/machinery/door/window/brigdoor/security/cell/southleft - dir = SOUTH - -/obj/machinery/door/window/brigdoor/security/cell/northright - dir = NORTH - icon_state = "rightsecure" - base_state = "rightsecure" - -/obj/machinery/door/window/brigdoor/security/cell/eastright - dir = EAST - icon_state = "rightsecure" - base_state = "rightsecure" - -/obj/machinery/door/window/brigdoor/security/cell/westright - dir = WEST - icon_state = "rightsecure" - base_state = "rightsecure" - -/obj/machinery/door/window/brigdoor/security/cell/southright - dir = SOUTH - icon_state = "rightsecure" - base_state = "rightsecure" - -/obj/machinery/door/window/brigdoor/security/holding/northleft - dir = NORTH - -/obj/machinery/door/window/brigdoor/security/holding/eastleft - dir = EAST - -/obj/machinery/door/window/brigdoor/security/holding/westleft - dir = WEST - -/obj/machinery/door/window/brigdoor/security/holding/southleft - dir = SOUTH - -/obj/machinery/door/window/brigdoor/security/holding/northright - dir = NORTH - icon_state = "rightsecure" - base_state = "rightsecure" - -/obj/machinery/door/window/brigdoor/security/holding/eastright - dir = EAST - icon_state = "rightsecure" - base_state = "rightsecure" - -/obj/machinery/door/window/brigdoor/security/holding/westright - dir = WEST - icon_state = "rightsecure" - base_state = "rightsecure" - -/obj/machinery/door/window/brigdoor/security/holding/southright - dir = SOUTH - icon_state = "rightsecure" - base_state = "rightsecure" +/obj/machinery/door/window + name = "interior door" + desc = "A strong door." + icon = 'icons/obj/doors/windoor.dmi' + icon_state = "left" + layer = ABOVE_WINDOW_LAYER + closingLayer = ABOVE_WINDOW_LAYER + resistance_flags = ACID_PROOF + var/base_state = "left" + max_integrity = 150 //If you change this, consider changing ../door/window/brigdoor/ max_integrity at the bottom of this .dm file + integrity_failure = 0 + armor = list("melee" = 20, "bullet" = 50, "laser" = 50, "energy" = 50, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 70, "acid" = 100) + visible = FALSE + flags_1 = ON_BORDER_1 + opacity = 0 + CanAtmosPass = ATMOS_PASS_PROC + interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN + var/obj/item/electronics/airlock/electronics = null + var/reinf = 0 + var/shards = 2 + var/rods = 2 + var/cable = 1 + var/list/debris = list() + +/obj/machinery/door/window/Initialize(mapload, set_dir) + . = ..() + if(set_dir) + setDir(set_dir) + if(src.req_access && src.req_access.len) + src.icon_state = "[src.icon_state]" + src.base_state = src.icon_state + for(var/i in 1 to shards) + debris += new /obj/item/shard(src) + if(rods) + debris += new /obj/item/stack/rods(src, rods) + if(cable) + debris += new /obj/item/stack/cable_coil(src, cable) + +/obj/machinery/door/window/ComponentInitialize() + . = ..() + AddComponent(/datum/component/ntnet_interface) + +/obj/machinery/door/window/Destroy() + density = FALSE + QDEL_LIST(debris) + if(obj_integrity == 0) + playsound(src, "shatter", 70, 1) + electronics = null + return ..() + +/obj/machinery/door/window/update_icon() + if(density) + icon_state = base_state + else + icon_state = "[src.base_state]open" + +/obj/machinery/door/window/proc/open_and_close() + open() + if(src.check_access(null)) + sleep(50) + else //secure doors close faster + sleep(20) + close() + +/obj/machinery/door/window/Bumped(atom/movable/AM) + if( operating || !src.density ) + return + if (!( ismob(AM) )) + if(ismecha(AM)) + var/obj/mecha/mecha = AM + if(mecha.occupant && src.allowed(mecha.occupant)) + open_and_close() + else + do_animate("deny") + return + if (!( SSticker )) + return + var/mob/M = AM + if(M.restrained() || ((isdrone(M) || iscyborg(M)) && M.stat)) + return + bumpopen(M) + +/obj/machinery/door/window/bumpopen(mob/user) + if( operating || !src.density ) + return + src.add_fingerprint(user) + if(!src.requiresID()) + user = null + + if(allowed(user)) + open_and_close() + else + do_animate("deny") + return + +/obj/machinery/door/window/CanPass(atom/movable/mover, turf/target) + if(istype(mover) && (mover.pass_flags & PASSGLASS)) + return 1 + if(get_dir(loc, target) == dir) //Make sure looking at appropriate border + return !density + if(istype(mover, /obj/structure/window)) + var/obj/structure/window/W = mover + if(!valid_window_location(loc, W.ini_dir)) + return FALSE + else if(istype(mover, /obj/structure/windoor_assembly)) + var/obj/structure/windoor_assembly/W = mover + if(!valid_window_location(loc, W.ini_dir)) + return FALSE + else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir)) + return FALSE + else + return 1 + +/obj/machinery/door/window/CanAtmosPass(turf/T) + if(get_dir(loc, T) == dir) + return !density + else + return 1 + +//used in the AStar algorithm to determinate if the turf the door is on is passable +/obj/machinery/door/window/CanAStarPass(obj/item/card/id/ID, to_dir) + return !density || (dir != to_dir) || (check_access(ID) && hasPower()) + +/obj/machinery/door/window/CheckExit(atom/movable/mover as mob|obj, turf/target) + if(istype(mover) && (mover.pass_flags & PASSGLASS)) + return 1 + if(get_dir(loc, target) == dir) + return !density + else + return 1 + +/obj/machinery/door/window/open(forced=0) + if (src.operating == 1) //doors can still open when emag-disabled + return 0 + if(!forced) + if(!hasPower()) + return 0 + if(forced < 2) + if(obj_flags & EMAGGED) + return 0 + if(!src.operating) //in case of emag + operating = TRUE + do_animate("opening") + playsound(src.loc, 'sound/machines/windowdoor.ogg', 100, 1) + src.icon_state ="[src.base_state]open" + sleep(10) + + density = FALSE +// src.sd_set_opacity(0) //TODO: why is this here? Opaque windoors? ~Carn + air_update_turf(1) + update_freelook_sight() + + if(operating == 1) //emag again + operating = FALSE + return 1 + +/obj/machinery/door/window/close(forced=0) + if (src.operating) + return 0 + if(!forced) + if(!hasPower()) + return 0 + if(forced < 2) + if(obj_flags & EMAGGED) + return 0 + operating = TRUE + do_animate("closing") + playsound(src.loc, 'sound/machines/windowdoor.ogg', 100, 1) + src.icon_state = src.base_state + + density = TRUE + air_update_turf(1) + update_freelook_sight() + sleep(10) + + operating = FALSE + return 1 + +/obj/machinery/door/window/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) + switch(damage_type) + if(BRUTE) + playsound(loc, 'sound/effects/glasshit.ogg', 90, 1) + if(BURN) + playsound(src.loc, 'sound/items/welder.ogg', 100, 1) + + +/obj/machinery/door/window/deconstruct(disassembled = TRUE) + if(!(flags_1 & NODECONSTRUCT_1) && !disassembled) + for(var/obj/fragment in debris) + fragment.forceMove(get_turf(src)) + transfer_fingerprints_to(fragment) + debris -= fragment + qdel(src) + +/obj/machinery/door/window/narsie_act() + add_atom_colour("#7D1919", FIXED_COLOUR_PRIORITY) + +/obj/machinery/door/window/ratvar_act() + var/obj/machinery/door/window/clockwork/C = new(loc, dir) + C.name = name + qdel(src) + +/obj/machinery/door/window/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) + if(exposed_temperature > T0C + (reinf ? 1600 : 800)) + take_damage(round(exposed_volume / 200), BURN, 0, 0) + ..() + +/obj/machinery/door/window/emag_act(mob/user) + . = ..() + if(operating || !density || obj_flags & EMAGGED) + return + obj_flags |= EMAGGED + operating = TRUE + flick("[src.base_state]spark", src) + playsound(src, "sparks", 75, 1) + addtimer(CALLBACK(src, .proc/open_windows_me), 6) + return TRUE + +/obj/machinery/door/window/proc/open_windows_me() + operating = FALSE + desc += "
      Its access panel is smoking slightly." + open(2) + +/obj/machinery/door/window/attackby(obj/item/I, mob/living/user, params) + + if(operating) + return + + add_fingerprint(user) + if(!(flags_1&NODECONSTRUCT_1)) + if(istype(I, /obj/item/screwdriver)) + if(density || operating) + to_chat(user, "You need to open the door to access the maintenance panel!") + return + I.play_tool_sound(src) + panel_open = !panel_open + to_chat(user, "You [panel_open ? "open":"close"] the maintenance panel of the [src.name].") + return + + if(istype(I, /obj/item/crowbar)) + if(panel_open && !density && !operating) + user.visible_message("[user] removes the electronics from the [src.name].", \ + "You start to remove electronics from the [src.name]...") + if(I.use_tool(src, user, 40, volume=50)) + if(panel_open && !density && !operating && src.loc) + var/obj/structure/windoor_assembly/WA = new /obj/structure/windoor_assembly(src.loc) + switch(base_state) + if("left") + WA.facing = "l" + if("right") + WA.facing = "r" + if("leftsecure") + WA.facing = "l" + WA.secure = TRUE + if("rightsecure") + WA.facing = "r" + WA.secure = TRUE + WA.setAnchored(TRUE) + WA.state= "02" + WA.setDir(src.dir) + WA.ini_dir = src.dir + WA.update_icon() + WA.created_name = src.name + + if(obj_flags & EMAGGED) + to_chat(user, "You discard the damaged electronics.") + qdel(src) + return + + to_chat(user, "You remove the airlock electronics.") + + var/obj/item/electronics/airlock/ae + if(!electronics) + ae = new/obj/item/electronics/airlock( src.loc ) + if(req_one_access) + ae.one_access = 1 + ae.accesses = src.req_one_access + else + ae.accesses = src.req_access + else + ae = electronics + electronics = null + ae.forceMove(drop_location()) + + qdel(src) + return + return ..() + +/obj/machinery/door/window/interact(mob/user) //for sillycones + try_to_activate_door(user) + +/obj/machinery/door/window/try_to_crowbar(obj/item/I, mob/user) + if(!hasPower()) + if(density) + open(2) + else + close(2) + else + to_chat(user, "The door's motors resist your efforts to force it!") + +/obj/machinery/door/window/do_animate(animation) + switch(animation) + if("opening") + flick("[src.base_state]opening", src) + if("closing") + flick("[src.base_state]closing", src) + if("deny") + flick("[src.base_state]deny", src) + +/obj/machinery/door/window/check_access_ntnet(datum/netdata/data) + return !requiresID() || ..() + +/obj/machinery/door/window/ntnet_receive(datum/netdata/data) + // Check if the airlock is powered. + if(!hasPower()) + return + + // Check packet access level. + if(!check_access_ntnet(data)) + return + + // Handle received packet. + var/command = lowertext(data.data["data"]) + var/command_value = lowertext(data.data["data_secondary"]) + switch(command) + if("open") + if(command_value == "on" && !density) + return + + if(command_value == "off" && density) + return + + if(density) + INVOKE_ASYNC(src, .proc/open) + else + INVOKE_ASYNC(src, .proc/close) + if("touch") + INVOKE_ASYNC(src, .proc/open_and_close) + +/obj/machinery/door/window/brigdoor + name = "secure door" + icon_state = "leftsecure" + base_state = "leftsecure" + var/id = null + max_integrity = 300 //Stronger doors for prison (regular window door health is 200) + reinf = 1 + explosion_block = 1 + +/obj/machinery/door/window/brigdoor/security/cell + name = "cell door" + desc = "For keeping in criminal scum." + req_access = list(ACCESS_BRIG) + +/obj/machinery/door/window/brigdoor/security/holding + name = "holding cell door" + req_one_access = list(ACCESS_SEC_DOORS, ACCESS_LAWYER) //love for the lawyer + +/obj/machinery/door/window/clockwork + name = "brass windoor" + desc = "A thin door with translucent brass paneling." + icon_state = "clockwork" + base_state = "clockwork" + shards = 0 + rods = 0 + resistance_flags = FIRE_PROOF | ACID_PROOF + var/made_glow = FALSE + +/obj/machinery/door/window/clockwork/Initialize(mapload, set_dir) + . = ..() + for(var/i in 1 to 2) + debris += new/obj/item/clockwork/alloy_shards/medium/gear_bit/large(src) + change_construction_value(2) + +/obj/machinery/door/window/clockwork/setDir(direct) + if(!made_glow) + var/obj/effect/E = new /obj/effect/temp_visual/ratvar/door/window(get_turf(src)) + E.setDir(direct) + made_glow = TRUE + ..() + +/obj/machinery/door/window/clockwork/Destroy() + change_construction_value(-2) + return ..() + +/obj/machinery/door/window/clockwork/emp_act(severity) + if(prob(80/severity)) + open() + +/obj/machinery/door/window/clockwork/ratvar_act() + if(GLOB.ratvar_awakens) + obj_integrity = max_integrity + +/obj/machinery/door/window/clockwork/hasPower() + return TRUE //yup that's power all right + +/obj/machinery/door/window/clockwork/narsie_act() + take_damage(rand(30, 60), BRUTE) + if(src) + var/previouscolor = color + color = "#960000" + animate(src, color = previouscolor, time = 8) + addtimer(CALLBACK(src, /atom/proc/update_atom_colour), 8) + +/obj/machinery/door/window/clockwork/allowed(mob/M) + if(is_servant_of_ratvar(M)) + return 1 + return 0 + +/obj/machinery/door/window/northleft + dir = NORTH + +/obj/machinery/door/window/eastleft + dir = EAST + +/obj/machinery/door/window/westleft + dir = WEST + +/obj/machinery/door/window/southleft + dir = SOUTH + +/obj/machinery/door/window/northright + dir = NORTH + icon_state = "right" + base_state = "right" + +/obj/machinery/door/window/eastright + dir = EAST + icon_state = "right" + base_state = "right" + +/obj/machinery/door/window/westright + dir = WEST + icon_state = "right" + base_state = "right" + +/obj/machinery/door/window/southright + dir = SOUTH + icon_state = "right" + base_state = "right" + +/obj/machinery/door/window/brigdoor/northleft + dir = NORTH + +/obj/machinery/door/window/brigdoor/eastleft + dir = EAST + +/obj/machinery/door/window/brigdoor/westleft + dir = WEST + +/obj/machinery/door/window/brigdoor/southleft + dir = SOUTH + +/obj/machinery/door/window/brigdoor/northright + dir = NORTH + icon_state = "rightsecure" + base_state = "rightsecure" + +/obj/machinery/door/window/brigdoor/eastright + dir = EAST + icon_state = "rightsecure" + base_state = "rightsecure" + +/obj/machinery/door/window/brigdoor/westright + dir = WEST + icon_state = "rightsecure" + base_state = "rightsecure" + +/obj/machinery/door/window/brigdoor/southright + dir = SOUTH + icon_state = "rightsecure" + base_state = "rightsecure" + +/obj/machinery/door/window/brigdoor/security/cell/northleft + dir = NORTH + +/obj/machinery/door/window/brigdoor/security/cell/eastleft + dir = EAST + +/obj/machinery/door/window/brigdoor/security/cell/westleft + dir = WEST + +/obj/machinery/door/window/brigdoor/security/cell/southleft + dir = SOUTH + +/obj/machinery/door/window/brigdoor/security/cell/northright + dir = NORTH + icon_state = "rightsecure" + base_state = "rightsecure" + +/obj/machinery/door/window/brigdoor/security/cell/eastright + dir = EAST + icon_state = "rightsecure" + base_state = "rightsecure" + +/obj/machinery/door/window/brigdoor/security/cell/westright + dir = WEST + icon_state = "rightsecure" + base_state = "rightsecure" + +/obj/machinery/door/window/brigdoor/security/cell/southright + dir = SOUTH + icon_state = "rightsecure" + base_state = "rightsecure" + +/obj/machinery/door/window/brigdoor/security/holding/northleft + dir = NORTH + +/obj/machinery/door/window/brigdoor/security/holding/eastleft + dir = EAST + +/obj/machinery/door/window/brigdoor/security/holding/westleft + dir = WEST + +/obj/machinery/door/window/brigdoor/security/holding/southleft + dir = SOUTH + +/obj/machinery/door/window/brigdoor/security/holding/northright + dir = NORTH + icon_state = "rightsecure" + base_state = "rightsecure" + +/obj/machinery/door/window/brigdoor/security/holding/eastright + dir = EAST + icon_state = "rightsecure" + base_state = "rightsecure" + +/obj/machinery/door/window/brigdoor/security/holding/westright + dir = WEST + icon_state = "rightsecure" + base_state = "rightsecure" + +/obj/machinery/door/window/brigdoor/security/holding/southright + dir = SOUTH + icon_state = "rightsecure" + base_state = "rightsecure" diff --git a/code/game/machinery/doppler_array.dm b/code/game/machinery/doppler_array.dm index 65f7602215..db806ef3ac 100644 --- a/code/game/machinery/doppler_array.dm +++ b/code/game/machinery/doppler_array.dm @@ -1,188 +1,188 @@ -GLOBAL_LIST_EMPTY(doppler_arrays) - -/obj/machinery/doppler_array - name = "tachyon-doppler array" - desc = "A highly precise directional sensor array which measures the release of quants from decaying tachyons. The doppler shifting of the mirror-image formed by these quants can reveal the size, location and temporal affects of energetic disturbances within a large radius ahead of the array.\n" - icon = 'icons/obj/machines/research.dmi' - icon_state = "tdoppler" - density = TRUE - var/integrated = FALSE - var/list_limit = 100 - var/cooldown = 10 - var/next_announce = 0 - var/max_dist = 150 - verb_say = "states coldly" - var/list/message_log = list() - -/obj/machinery/doppler_array/Initialize() - . = ..() - GLOB.doppler_arrays += src - -/obj/machinery/doppler_array/ComponentInitialize() - . = ..() - AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE,null,null,CALLBACK(src,.proc/rot_message)) - -/obj/machinery/doppler_array/Destroy() - GLOB.doppler_arrays -= src - return ..() - -/obj/machinery/doppler_array/ui_interact(mob/user) - . = ..() - if(stat) - return FALSE - - var/list/dat = list() - for(var/i in 1 to LAZYLEN(message_log)) - dat += "Log recording #[i]: [message_log[i]]

      " - dat += "Delete logs
      " - dat += "
      " - dat += "(Refresh)
      " - dat += "" - var/datum/browser/popup = new(user, "computer", name, 400, 500) - popup.set_content(dat.Join(" ")) - popup.open() - -/obj/machinery/doppler_array/Topic(href, href_list) - if(..()) - return - if(href_list["delete_log"]) - LAZYCLEARLIST(message_log) - if(href_list["refresh"]) - updateUsrDialog() - - updateUsrDialog() - return - -/obj/machinery/doppler_array/attackby(obj/item/I, mob/user, params) - if(istype(I, /obj/item/wrench)) - if(!anchored && !isinspace()) - anchored = TRUE - power_change() - to_chat(user, "You fasten [src].") - else if(anchored) - anchored = FALSE - power_change() - to_chat(user, "You unfasten [src].") - I.play_tool_sound(src) - else - return ..() - -/obj/machinery/doppler_array/proc/rot_message(mob/user) - to_chat(user, "You adjust [src]'s dish to face to the [dir2text(dir)].") - playsound(src, 'sound/items/screwdriver2.ogg', 50, 1) - -/obj/machinery/doppler_array/proc/sense_explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, - took, orig_dev_range, orig_heavy_range, orig_light_range) - if(stat & NOPOWER) - return FALSE - var/turf/zone = get_turf(src) - if(zone.z != epicenter.z) - return FALSE - - if(next_announce > world.time) - return FALSE - next_announce = world.time + cooldown - - var/distance = get_dist(epicenter, zone) - var/direct = get_dir(zone, epicenter) - - if(distance > max_dist) - return FALSE - if(!(direct & dir) && !integrated) - return FALSE - - - var/list/messages = list("Explosive disturbance detected.", \ - "Epicenter at: grid ([epicenter.x],[epicenter.y]). Temporal displacement of tachyons: [took] seconds.", \ - "Factual: Epicenter radius: [devastation_range]. Outer radius: [heavy_impact_range]. Shockwave radius: [light_impact_range].") - - // If the bomb was capped, say its theoretical size. - if(devastation_range < orig_dev_range || heavy_impact_range < orig_heavy_range || light_impact_range < orig_light_range) - messages += "Theoretical: Epicenter radius: [orig_dev_range]. Outer radius: [orig_heavy_range]. Shockwave radius: [orig_light_range]." - - if(integrated) - var/obj/item/clothing/head/helmet/space/hardsuit/helm = loc - if(!helm || !istype(helm, /obj/item/clothing/head/helmet/space/hardsuit)) - return FALSE - helm.display_visor_message("Explosion detected! Epicenter: [devastation_range], Outer: [heavy_impact_range], Shock: [light_impact_range]") - else - for(var/message in messages) - say(message) - if(LAZYLEN(message_log) > list_limit) - say("Storage buffer is full! Clearing buffers...") - LAZYCLEARLIST(message_log) - LAZYADD(message_log, messages.Join(" ")) - return TRUE - -/obj/machinery/doppler_array/examine(mob/user) - . = ..() - . += "Its dish is facing to the [dir2text(dir)]." - -/obj/machinery/doppler_array/process() - return PROCESS_KILL - -/obj/machinery/doppler_array/power_change() - if(stat & BROKEN) - icon_state = "[initial(icon_state)]-broken" - else - if(powered() && anchored) - icon_state = initial(icon_state) - stat &= ~NOPOWER - else - icon_state = "[initial(icon_state)]-off" - stat |= NOPOWER - -//Portable version, built into EOD equipment. It simply provides an explosion's three damage levels. -/obj/machinery/doppler_array/integrated - name = "integrated tachyon-doppler module" - integrated = TRUE - max_dist = 21 //Should detect most explosions in hearing range. - use_power = NO_POWER_USE - -/obj/machinery/doppler_array/research - name = "tachyon-doppler research array" - desc = "A specialized tachyon-doppler bomb detection array that uses the results of the highest yield of explosions for research." - var/datum/techweb/linked_techweb - -/obj/machinery/doppler_array/research/sense_explosion(turf/epicenter, dev, heavy, light, time, orig_dev, orig_heavy, orig_light) //probably needs a way to ignore admin explosives later on - . = ..() - if(!.) - return FALSE - if(!istype(linked_techweb)) - say("Warning: No linked research system!") - return - - var/point_gain = 0 - - /*****The Point Calculator*****/ - - if(orig_light < 10) - say("Explosion not large enough for research calculations.") - return - else if(orig_light < 4500) - point_gain = (83300 * orig_light) / (orig_light + 3000) - else - point_gain = TECHWEB_BOMB_POINTCAP - - /*****The Point Capper*****/ - if(point_gain > linked_techweb.largest_bomb_value) - if(point_gain <= TECHWEB_BOMB_POINTCAP || linked_techweb.largest_bomb_value < TECHWEB_BOMB_POINTCAP) - var/old_tech_largest_bomb_value = linked_techweb.largest_bomb_value //held so we can pull old before we do math - linked_techweb.largest_bomb_value = point_gain - point_gain -= old_tech_largest_bomb_value - point_gain = min(point_gain,TECHWEB_BOMB_POINTCAP) - else - linked_techweb.largest_bomb_value = TECHWEB_BOMB_POINTCAP - point_gain = 1000 - - linked_techweb.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, point_gain) - say("Gained [point_gain] points from explosion dataset.") - - else //you've made smaller bombs - say("Data already captured. Aborting.") - return - - -/obj/machinery/doppler_array/research/science/Initialize() - . = ..() +GLOBAL_LIST_EMPTY(doppler_arrays) + +/obj/machinery/doppler_array + name = "tachyon-doppler array" + desc = "A highly precise directional sensor array which measures the release of quants from decaying tachyons. The doppler shifting of the mirror-image formed by these quants can reveal the size, location and temporal affects of energetic disturbances within a large radius ahead of the array.\n" + icon = 'icons/obj/machines/research.dmi' + icon_state = "tdoppler" + density = TRUE + var/integrated = FALSE + var/list_limit = 100 + var/cooldown = 10 + var/next_announce = 0 + var/max_dist = 150 + verb_say = "states coldly" + var/list/message_log = list() + +/obj/machinery/doppler_array/Initialize() + . = ..() + GLOB.doppler_arrays += src + +/obj/machinery/doppler_array/ComponentInitialize() + . = ..() + AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE,null,null,CALLBACK(src,.proc/rot_message)) + +/obj/machinery/doppler_array/Destroy() + GLOB.doppler_arrays -= src + return ..() + +/obj/machinery/doppler_array/ui_interact(mob/user) + . = ..() + if(stat) + return FALSE + + var/list/dat = list() + for(var/i in 1 to LAZYLEN(message_log)) + dat += "Log recording #[i]: [message_log[i]]

      " + dat += "Delete logs
      " + dat += "
      " + dat += "(Refresh)
      " + dat += "" + var/datum/browser/popup = new(user, "computer", name, 400, 500) + popup.set_content(dat.Join(" ")) + popup.open() + +/obj/machinery/doppler_array/Topic(href, href_list) + if(..()) + return + if(href_list["delete_log"]) + LAZYCLEARLIST(message_log) + if(href_list["refresh"]) + updateUsrDialog() + + updateUsrDialog() + return + +/obj/machinery/doppler_array/attackby(obj/item/I, mob/user, params) + if(istype(I, /obj/item/wrench)) + if(!anchored && !isinspace()) + anchored = TRUE + power_change() + to_chat(user, "You fasten [src].") + else if(anchored) + anchored = FALSE + power_change() + to_chat(user, "You unfasten [src].") + I.play_tool_sound(src) + else + return ..() + +/obj/machinery/doppler_array/proc/rot_message(mob/user) + to_chat(user, "You adjust [src]'s dish to face to the [dir2text(dir)].") + playsound(src, 'sound/items/screwdriver2.ogg', 50, 1) + +/obj/machinery/doppler_array/proc/sense_explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, + took, orig_dev_range, orig_heavy_range, orig_light_range) + if(stat & NOPOWER) + return FALSE + var/turf/zone = get_turf(src) + if(zone.z != epicenter.z) + return FALSE + + if(next_announce > world.time) + return FALSE + next_announce = world.time + cooldown + + var/distance = get_dist(epicenter, zone) + var/direct = get_dir(zone, epicenter) + + if(distance > max_dist) + return FALSE + if(!(direct & dir) && !integrated) + return FALSE + + + var/list/messages = list("Explosive disturbance detected.", \ + "Epicenter at: grid ([epicenter.x],[epicenter.y]). Temporal displacement of tachyons: [took] seconds.", \ + "Factual: Epicenter radius: [devastation_range]. Outer radius: [heavy_impact_range]. Shockwave radius: [light_impact_range].") + + // If the bomb was capped, say its theoretical size. + if(devastation_range < orig_dev_range || heavy_impact_range < orig_heavy_range || light_impact_range < orig_light_range) + messages += "Theoretical: Epicenter radius: [orig_dev_range]. Outer radius: [orig_heavy_range]. Shockwave radius: [orig_light_range]." + + if(integrated) + var/obj/item/clothing/head/helmet/space/hardsuit/helm = loc + if(!helm || !istype(helm, /obj/item/clothing/head/helmet/space/hardsuit)) + return FALSE + helm.display_visor_message("Explosion detected! Epicenter: [devastation_range], Outer: [heavy_impact_range], Shock: [light_impact_range]") + else + for(var/message in messages) + say(message) + if(LAZYLEN(message_log) > list_limit) + say("Storage buffer is full! Clearing buffers...") + LAZYCLEARLIST(message_log) + LAZYADD(message_log, messages.Join(" ")) + return TRUE + +/obj/machinery/doppler_array/examine(mob/user) + . = ..() + . += "Its dish is facing to the [dir2text(dir)]." + +/obj/machinery/doppler_array/process() + return PROCESS_KILL + +/obj/machinery/doppler_array/power_change() + if(stat & BROKEN) + icon_state = "[initial(icon_state)]-broken" + else + if(powered() && anchored) + icon_state = initial(icon_state) + stat &= ~NOPOWER + else + icon_state = "[initial(icon_state)]-off" + stat |= NOPOWER + +//Portable version, built into EOD equipment. It simply provides an explosion's three damage levels. +/obj/machinery/doppler_array/integrated + name = "integrated tachyon-doppler module" + integrated = TRUE + max_dist = 21 //Should detect most explosions in hearing range. + use_power = NO_POWER_USE + +/obj/machinery/doppler_array/research + name = "tachyon-doppler research array" + desc = "A specialized tachyon-doppler bomb detection array that uses the results of the highest yield of explosions for research." + var/datum/techweb/linked_techweb + +/obj/machinery/doppler_array/research/sense_explosion(turf/epicenter, dev, heavy, light, time, orig_dev, orig_heavy, orig_light) //probably needs a way to ignore admin explosives later on + . = ..() + if(!.) + return FALSE + if(!istype(linked_techweb)) + say("Warning: No linked research system!") + return + + var/point_gain = 0 + + /*****The Point Calculator*****/ + + if(orig_light < 10) + say("Explosion not large enough for research calculations.") + return + else if(orig_light < 4500) + point_gain = (83300 * orig_light) / (orig_light + 3000) + else + point_gain = TECHWEB_BOMB_POINTCAP + + /*****The Point Capper*****/ + if(point_gain > linked_techweb.largest_bomb_value) + if(point_gain <= TECHWEB_BOMB_POINTCAP || linked_techweb.largest_bomb_value < TECHWEB_BOMB_POINTCAP) + var/old_tech_largest_bomb_value = linked_techweb.largest_bomb_value //held so we can pull old before we do math + linked_techweb.largest_bomb_value = point_gain + point_gain -= old_tech_largest_bomb_value + point_gain = min(point_gain,TECHWEB_BOMB_POINTCAP) + else + linked_techweb.largest_bomb_value = TECHWEB_BOMB_POINTCAP + point_gain = 1000 + + linked_techweb.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, point_gain) + say("Gained [point_gain] points from explosion dataset.") + + else //you've made smaller bombs + say("Data already captured. Aborting.") + return + + +/obj/machinery/doppler_array/research/science/Initialize() + . = ..() linked_techweb = SSresearch.science_tech \ No newline at end of file diff --git a/code/game/machinery/embedded_controller/access_controller.dm b/code/game/machinery/embedded_controller/access_controller.dm index 3b9322d207..ad49abb398 100644 --- a/code/game/machinery/embedded_controller/access_controller.dm +++ b/code/game/machinery/embedded_controller/access_controller.dm @@ -1,315 +1,315 @@ -#define CLOSING 1 -#define OPENING 2 -#define CYCLE 3 -#define CYCLE_EXTERIOR 4 -#define CYCLE_INTERIOR 5 - -/obj/machinery/doorButtons - power_channel = ENVIRON - use_power = IDLE_POWER_USE - idle_power_usage = 2 - active_power_usage = 4 - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - var/idSelf - -/obj/machinery/doorButtons/attackby(obj/O, mob/user) - return attack_hand(user) - -/obj/machinery/doorButtons/proc/findObjsByTag() - return - -/obj/machinery/doorButtons/Initialize() - ..() - return INITIALIZE_HINT_LATELOAD - -/obj/machinery/doorButtons/LateInitialize() - findObjsByTag() - -/obj/machinery/doorButtons/emag_act(mob/user) - . = ..() - if(obj_flags & EMAGGED) - return - obj_flags |= EMAGGED - req_access = list() - req_one_access = list() - playsound(src, "sparks", 100, 1) - to_chat(user, "You short out the access controller.") - return TRUE - -/obj/machinery/doorButtons/proc/removeMe() - - -/obj/machinery/doorButtons/access_button - icon = 'icons/obj/airlock_machines.dmi' - icon_state = "access_button_standby" - name = "access button" - desc = "A button used for the explicit purpose of opening an airlock." - var/idDoor - var/obj/machinery/door/airlock/door - var/obj/machinery/doorButtons/airlock_controller/controller - var/busy - -/obj/machinery/doorButtons/access_button/findObjsByTag() - for(var/obj/machinery/doorButtons/airlock_controller/A in GLOB.machines) - if(A.idSelf == idSelf) - controller = A - break - for(var/obj/machinery/door/airlock/I in GLOB.machines) - if(I.id_tag == idDoor) - door = I - break - -/obj/machinery/doorButtons/access_button/interact(mob/user) - if(busy) - return - if(!allowed(user)) - to_chat(user, "Access denied.") - return - if(controller && !controller.busy && door) - if(controller.stat & NOPOWER) - return - busy = TRUE - update_icon() - if(door.density) - if(!controller.exteriorAirlock || !controller.interiorAirlock) - controller.onlyOpen(door) - else - if(controller.exteriorAirlock.density && controller.interiorAirlock.density) - controller.onlyOpen(door) - else - controller.cycleClose(door) - else - controller.onlyClose(door) - sleep(20) - busy = FALSE - update_icon() - -/obj/machinery/doorButtons/access_button/update_icon() - if(stat & NOPOWER) - icon_state = "access_button_off" - else - if(busy) - icon_state = "access_button_cycle" - else - icon_state = "access_button_standby" - -/obj/machinery/doorButtons/access_button/power_change() - ..() - update_icon() - -/obj/machinery/doorButtons/access_button/removeMe(obj/O) - if(O == door) - door = null - - - -/obj/machinery/doorButtons/airlock_controller - icon = 'icons/obj/airlock_machines.dmi' - icon_state = "access_control_standby" - name = "access console" - desc = "A small console that can cycle opening between two airlocks." - var/obj/machinery/door/airlock/interiorAirlock - var/obj/machinery/door/airlock/exteriorAirlock - var/idInterior - var/idExterior - var/busy - var/lostPower - -/obj/machinery/doorButtons/airlock_controller/removeMe(obj/O) - if(O == interiorAirlock) - interiorAirlock = null - else if(O == exteriorAirlock) - exteriorAirlock = null - -/obj/machinery/doorButtons/airlock_controller/Destroy() - for(var/obj/machinery/doorButtons/access_button/A in GLOB.machines) - if(A.controller == src) - A.controller = null - return ..() - -/obj/machinery/doorButtons/airlock_controller/Topic(href, href_list) - if(..()) - return - if(busy) - return - if(!allowed(usr)) - to_chat(usr, "Access denied.") - return - switch(href_list["command"]) - if("close_exterior") - onlyClose(exteriorAirlock) - if("close_interior") - onlyClose(interiorAirlock) - if("cycle_exterior") - cycleClose(exteriorAirlock) - if("cycle_interior") - cycleClose(interiorAirlock) - if("open_exterior") - onlyOpen(exteriorAirlock) - if("open_interior") - onlyOpen(interiorAirlock) - -/obj/machinery/doorButtons/airlock_controller/proc/onlyOpen(obj/machinery/door/airlock/A) - if(A) - busy = CLOSING - update_icon() - openDoor(A) - -/obj/machinery/doorButtons/airlock_controller/proc/onlyClose(obj/machinery/door/airlock/A) - if(A) - busy = CLOSING - closeDoor(A) - -/obj/machinery/doorButtons/airlock_controller/proc/closeDoor(obj/machinery/door/airlock/A) - set waitfor = FALSE - if(A.density) - goIdle() - return 0 - update_icon() - A.unbolt() - . = 1 - if(A && A.close()) - if(stat & NOPOWER || lostPower || !A || QDELETED(A)) - goIdle(1) - return - A.bolt() - if(busy == CLOSING) - goIdle(1) - else - goIdle(1) - -/obj/machinery/doorButtons/airlock_controller/proc/cycleClose(obj/machinery/door/airlock/A) - if(!A || !exteriorAirlock || !interiorAirlock) - return - if(exteriorAirlock.density == interiorAirlock.density || !A.density) - return - busy = CYCLE - update_icon() - if(A == interiorAirlock) - if(closeDoor(exteriorAirlock)) - busy = CYCLE_INTERIOR - else - if(closeDoor(interiorAirlock)) - busy = CYCLE_EXTERIOR - -/obj/machinery/doorButtons/airlock_controller/proc/cycleOpen(obj/machinery/door/airlock/A) - if(!A) - goIdle(1) - if(A == exteriorAirlock) - if(interiorAirlock) - if(!interiorAirlock.density || !interiorAirlock.locked) - return - else - if(exteriorAirlock) - if(!exteriorAirlock.density || !exteriorAirlock.locked) - return - if(busy != OPENING) - busy = OPENING - openDoor(A) - -/obj/machinery/doorButtons/airlock_controller/proc/openDoor(obj/machinery/door/airlock/A) - if(exteriorAirlock && interiorAirlock && (!exteriorAirlock.density || !interiorAirlock.density)) - goIdle(1) - return - A.unbolt() - spawn() - if(A && A.open()) - if(stat | (NOPOWER) && !lostPower && A && !QDELETED(A)) - A.bolt() - goIdle(1) - -/obj/machinery/doorButtons/airlock_controller/proc/goIdle(update) - lostPower = 0 - busy = FALSE - if(update) - update_icon() - updateUsrDialog() - -/obj/machinery/doorButtons/airlock_controller/process() - if(stat & NOPOWER) - return - if(busy == CYCLE_EXTERIOR) - cycleOpen(exteriorAirlock) - else if(busy == CYCLE_INTERIOR) - cycleOpen(interiorAirlock) - -/obj/machinery/doorButtons/airlock_controller/power_change() - ..() - if(stat & NOPOWER) - lostPower = 1 - else - if(!busy) - lostPower = 0 - update_icon() - -/obj/machinery/doorButtons/airlock_controller/findObjsByTag() - for(var/obj/machinery/door/airlock/A in GLOB.machines) - if(A.id_tag == idInterior) - interiorAirlock = A - else if(A.id_tag == idExterior) - exteriorAirlock = A - -/obj/machinery/doorButtons/airlock_controller/update_icon() - if(stat & NOPOWER) - icon_state = "access_control_off" - return - if(busy || lostPower) - icon_state = "access_control_process" - else - icon_state = "access_control_standby" - -/obj/machinery/doorButtons/airlock_controller/ui_interact(mob/user) - var/datum/browser/popup = new(user, "computer", name) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.set_content(returnText()) - popup.open() - -/obj/machinery/doorButtons/airlock_controller/proc/returnText() - var/output - if(!exteriorAirlock && !interiorAirlock) - return "ERROR ERROR ERROR ERROR" - if(lostPower) - output = "Initializing..." - else - if(!exteriorAirlock || !interiorAirlock) - if(!exteriorAirlock) - if(interiorAirlock.density) - output = "Open Interior Airlock
      " - else - output = "Close Interior Airlock
      " - else - if(exteriorAirlock.density) - output = "Open Exterior Airlock
      " - else - output = "Close Exterior Airlock
      " - else - if(exteriorAirlock.density) - if(interiorAirlock.density) - output = {"Open Exterior Airlock
      - Open Interior Airlock
      "} - else - output = {"Cycle to Exterior Airlock
      - Close Interior Airlock
      "} - else - if(interiorAirlock.density) - output = {"Close Exterior Airlock
      - Cycle to Interior Airlock
      "} - else - output = {"Close Exterior Airlock
      - Close Interior Airlock
      "} - - - output = {"Access Control Console
      - [output]
      "} - if(exteriorAirlock) - output += "Exterior Door: [exteriorAirlock.density ? "closed" : "open"]
      " - if(interiorAirlock) - output += "Interior Door: [interiorAirlock.density ? "closed" : "open"]
      " - - return output - -#undef CLOSING -#undef OPENING -#undef CYCLE -#undef CYCLE_EXTERIOR -#undef CYCLE_INTERIOR +#define CLOSING 1 +#define OPENING 2 +#define CYCLE 3 +#define CYCLE_EXTERIOR 4 +#define CYCLE_INTERIOR 5 + +/obj/machinery/doorButtons + power_channel = ENVIRON + use_power = IDLE_POWER_USE + idle_power_usage = 2 + active_power_usage = 4 + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + var/idSelf + +/obj/machinery/doorButtons/attackby(obj/O, mob/user) + return attack_hand(user) + +/obj/machinery/doorButtons/proc/findObjsByTag() + return + +/obj/machinery/doorButtons/Initialize() + ..() + return INITIALIZE_HINT_LATELOAD + +/obj/machinery/doorButtons/LateInitialize() + findObjsByTag() + +/obj/machinery/doorButtons/emag_act(mob/user) + . = ..() + if(obj_flags & EMAGGED) + return + obj_flags |= EMAGGED + req_access = list() + req_one_access = list() + playsound(src, "sparks", 100, 1) + to_chat(user, "You short out the access controller.") + return TRUE + +/obj/machinery/doorButtons/proc/removeMe() + + +/obj/machinery/doorButtons/access_button + icon = 'icons/obj/airlock_machines.dmi' + icon_state = "access_button_standby" + name = "access button" + desc = "A button used for the explicit purpose of opening an airlock." + var/idDoor + var/obj/machinery/door/airlock/door + var/obj/machinery/doorButtons/airlock_controller/controller + var/busy + +/obj/machinery/doorButtons/access_button/findObjsByTag() + for(var/obj/machinery/doorButtons/airlock_controller/A in GLOB.machines) + if(A.idSelf == idSelf) + controller = A + break + for(var/obj/machinery/door/airlock/I in GLOB.machines) + if(I.id_tag == idDoor) + door = I + break + +/obj/machinery/doorButtons/access_button/interact(mob/user) + if(busy) + return + if(!allowed(user)) + to_chat(user, "Access denied.") + return + if(controller && !controller.busy && door) + if(controller.stat & NOPOWER) + return + busy = TRUE + update_icon() + if(door.density) + if(!controller.exteriorAirlock || !controller.interiorAirlock) + controller.onlyOpen(door) + else + if(controller.exteriorAirlock.density && controller.interiorAirlock.density) + controller.onlyOpen(door) + else + controller.cycleClose(door) + else + controller.onlyClose(door) + sleep(20) + busy = FALSE + update_icon() + +/obj/machinery/doorButtons/access_button/update_icon() + if(stat & NOPOWER) + icon_state = "access_button_off" + else + if(busy) + icon_state = "access_button_cycle" + else + icon_state = "access_button_standby" + +/obj/machinery/doorButtons/access_button/power_change() + ..() + update_icon() + +/obj/machinery/doorButtons/access_button/removeMe(obj/O) + if(O == door) + door = null + + + +/obj/machinery/doorButtons/airlock_controller + icon = 'icons/obj/airlock_machines.dmi' + icon_state = "access_control_standby" + name = "access console" + desc = "A small console that can cycle opening between two airlocks." + var/obj/machinery/door/airlock/interiorAirlock + var/obj/machinery/door/airlock/exteriorAirlock + var/idInterior + var/idExterior + var/busy + var/lostPower + +/obj/machinery/doorButtons/airlock_controller/removeMe(obj/O) + if(O == interiorAirlock) + interiorAirlock = null + else if(O == exteriorAirlock) + exteriorAirlock = null + +/obj/machinery/doorButtons/airlock_controller/Destroy() + for(var/obj/machinery/doorButtons/access_button/A in GLOB.machines) + if(A.controller == src) + A.controller = null + return ..() + +/obj/machinery/doorButtons/airlock_controller/Topic(href, href_list) + if(..()) + return + if(busy) + return + if(!allowed(usr)) + to_chat(usr, "Access denied.") + return + switch(href_list["command"]) + if("close_exterior") + onlyClose(exteriorAirlock) + if("close_interior") + onlyClose(interiorAirlock) + if("cycle_exterior") + cycleClose(exteriorAirlock) + if("cycle_interior") + cycleClose(interiorAirlock) + if("open_exterior") + onlyOpen(exteriorAirlock) + if("open_interior") + onlyOpen(interiorAirlock) + +/obj/machinery/doorButtons/airlock_controller/proc/onlyOpen(obj/machinery/door/airlock/A) + if(A) + busy = CLOSING + update_icon() + openDoor(A) + +/obj/machinery/doorButtons/airlock_controller/proc/onlyClose(obj/machinery/door/airlock/A) + if(A) + busy = CLOSING + closeDoor(A) + +/obj/machinery/doorButtons/airlock_controller/proc/closeDoor(obj/machinery/door/airlock/A) + set waitfor = FALSE + if(A.density) + goIdle() + return 0 + update_icon() + A.unbolt() + . = 1 + if(A && A.close()) + if(stat & NOPOWER || lostPower || !A || QDELETED(A)) + goIdle(1) + return + A.bolt() + if(busy == CLOSING) + goIdle(1) + else + goIdle(1) + +/obj/machinery/doorButtons/airlock_controller/proc/cycleClose(obj/machinery/door/airlock/A) + if(!A || !exteriorAirlock || !interiorAirlock) + return + if(exteriorAirlock.density == interiorAirlock.density || !A.density) + return + busy = CYCLE + update_icon() + if(A == interiorAirlock) + if(closeDoor(exteriorAirlock)) + busy = CYCLE_INTERIOR + else + if(closeDoor(interiorAirlock)) + busy = CYCLE_EXTERIOR + +/obj/machinery/doorButtons/airlock_controller/proc/cycleOpen(obj/machinery/door/airlock/A) + if(!A) + goIdle(1) + if(A == exteriorAirlock) + if(interiorAirlock) + if(!interiorAirlock.density || !interiorAirlock.locked) + return + else + if(exteriorAirlock) + if(!exteriorAirlock.density || !exteriorAirlock.locked) + return + if(busy != OPENING) + busy = OPENING + openDoor(A) + +/obj/machinery/doorButtons/airlock_controller/proc/openDoor(obj/machinery/door/airlock/A) + if(exteriorAirlock && interiorAirlock && (!exteriorAirlock.density || !interiorAirlock.density)) + goIdle(1) + return + A.unbolt() + spawn() + if(A && A.open()) + if(stat | (NOPOWER) && !lostPower && A && !QDELETED(A)) + A.bolt() + goIdle(1) + +/obj/machinery/doorButtons/airlock_controller/proc/goIdle(update) + lostPower = 0 + busy = FALSE + if(update) + update_icon() + updateUsrDialog() + +/obj/machinery/doorButtons/airlock_controller/process() + if(stat & NOPOWER) + return + if(busy == CYCLE_EXTERIOR) + cycleOpen(exteriorAirlock) + else if(busy == CYCLE_INTERIOR) + cycleOpen(interiorAirlock) + +/obj/machinery/doorButtons/airlock_controller/power_change() + ..() + if(stat & NOPOWER) + lostPower = 1 + else + if(!busy) + lostPower = 0 + update_icon() + +/obj/machinery/doorButtons/airlock_controller/findObjsByTag() + for(var/obj/machinery/door/airlock/A in GLOB.machines) + if(A.id_tag == idInterior) + interiorAirlock = A + else if(A.id_tag == idExterior) + exteriorAirlock = A + +/obj/machinery/doorButtons/airlock_controller/update_icon() + if(stat & NOPOWER) + icon_state = "access_control_off" + return + if(busy || lostPower) + icon_state = "access_control_process" + else + icon_state = "access_control_standby" + +/obj/machinery/doorButtons/airlock_controller/ui_interact(mob/user) + var/datum/browser/popup = new(user, "computer", name) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.set_content(returnText()) + popup.open() + +/obj/machinery/doorButtons/airlock_controller/proc/returnText() + var/output + if(!exteriorAirlock && !interiorAirlock) + return "ERROR ERROR ERROR ERROR" + if(lostPower) + output = "Initializing..." + else + if(!exteriorAirlock || !interiorAirlock) + if(!exteriorAirlock) + if(interiorAirlock.density) + output = "Open Interior Airlock
      " + else + output = "Close Interior Airlock
      " + else + if(exteriorAirlock.density) + output = "Open Exterior Airlock
      " + else + output = "Close Exterior Airlock
      " + else + if(exteriorAirlock.density) + if(interiorAirlock.density) + output = {"Open Exterior Airlock
      + Open Interior Airlock
      "} + else + output = {"Cycle to Exterior Airlock
      + Close Interior Airlock
      "} + else + if(interiorAirlock.density) + output = {"Close Exterior Airlock
      + Cycle to Interior Airlock
      "} + else + output = {"Close Exterior Airlock
      + Close Interior Airlock
      "} + + + output = {"Access Control Console
      + [output]
      "} + if(exteriorAirlock) + output += "Exterior Door: [exteriorAirlock.density ? "closed" : "open"]
      " + if(interiorAirlock) + output += "Interior Door: [interiorAirlock.density ? "closed" : "open"]
      " + + return output + +#undef CLOSING +#undef OPENING +#undef CYCLE +#undef CYCLE_EXTERIOR +#undef CYCLE_INTERIOR diff --git a/code/game/machinery/embedded_controller/airlock_controller.dm b/code/game/machinery/embedded_controller/airlock_controller.dm index 0036b41804..9f1ebe67a9 100644 --- a/code/game/machinery/embedded_controller/airlock_controller.dm +++ b/code/game/machinery/embedded_controller/airlock_controller.dm @@ -1,315 +1,315 @@ -//States for airlock_control -#define AIRLOCK_STATE_INOPEN -2 -#define AIRLOCK_STATE_PRESSURIZE -1 -#define AIRLOCK_STATE_CLOSED 0 -#define AIRLOCK_STATE_DEPRESSURIZE 1 -#define AIRLOCK_STATE_OUTOPEN 2 - -/datum/computer/file/embedded_program/airlock_controller - var/id_tag - var/exterior_door_tag //Burn chamber facing door - var/interior_door_tag //Station facing door - var/airpump_tag //See: dp_vent_pump.dm - var/sensor_tag //See: /obj/machinery/airlock_sensor - var/sanitize_external //Before the interior airlock opens, do we first drain all gases inside the chamber and then repressurize? - - state = AIRLOCK_STATE_CLOSED - var/target_state = AIRLOCK_STATE_CLOSED - var/sensor_pressure = null - -/datum/computer/file/embedded_program/airlock_controller/receive_signal(datum/signal/signal) - var/receive_tag = signal.data["tag"] - if(!receive_tag) - return - - if(receive_tag==sensor_tag) - if(signal.data["pressure"]) - sensor_pressure = text2num(signal.data["pressure"]) - - else if(receive_tag==exterior_door_tag) - memory["exterior_status"] = signal.data["door_status"] - - else if(receive_tag==interior_door_tag) - memory["interior_status"] = signal.data["door_status"] - - else if(receive_tag==airpump_tag) - if(signal.data["power"]) - memory["pump_status"] = signal.data["direction"] - else - memory["pump_status"] = "off" - - else if(receive_tag==id_tag) - switch(signal.data["command"]) - if("cycle") - if(state < AIRLOCK_STATE_CLOSED) - target_state = AIRLOCK_STATE_OUTOPEN - else - target_state = AIRLOCK_STATE_INOPEN - -/datum/computer/file/embedded_program/airlock_controller/receive_user_command(command) - switch(command) - if("cycle_closed") - target_state = AIRLOCK_STATE_CLOSED - if("cycle_exterior") - target_state = AIRLOCK_STATE_OUTOPEN - if("cycle_interior") - target_state = AIRLOCK_STATE_INOPEN - if("abort") - target_state = AIRLOCK_STATE_CLOSED - -/datum/computer/file/embedded_program/airlock_controller/process() - var/process_again = 1 - while(process_again) - process_again = 0 - switch(state) - if(AIRLOCK_STATE_INOPEN) // state -2 - if(target_state > state) - if(memory["interior_status"] == "closed") - state = AIRLOCK_STATE_CLOSED - process_again = 1 - else - post_signal(new /datum/signal(list( - "tag" = interior_door_tag, - "command" = "secure_close" - ))) - else - if(memory["pump_status"] != "off") - post_signal(new /datum/signal(list( - "tag" = airpump_tag, - "power" = 0, - "sigtype" = "command" - ))) - - if(AIRLOCK_STATE_PRESSURIZE) - if(target_state < state) - if(sensor_pressure >= ONE_ATMOSPHERE*0.95) - if(memory["interior_status"] == "open") - state = AIRLOCK_STATE_INOPEN - process_again = 1 - else - post_signal(new /datum/signal(list( - "tag" = interior_door_tag, - "command" = "secure_open" - ))) - else - var/datum/signal/signal = new(list( - "tag" = airpump_tag, - "sigtype" = "command" - )) - if(memory["pump_status"] == "siphon") - signal.data["stabilize"] = 1 - else if(memory["pump_status"] != "release") - signal.data["power"] = 1 - post_signal(signal) - else if(target_state > state) - state = AIRLOCK_STATE_CLOSED - process_again = 1 - - if(AIRLOCK_STATE_CLOSED) - if(target_state > state) - if(memory["interior_status"] == "closed") - state = AIRLOCK_STATE_DEPRESSURIZE - process_again = 1 - else - post_signal(new /datum/signal(list( - "tag" = interior_door_tag, - "command" = "secure_close" - ))) - else if(target_state < state) - if(memory["exterior_status"] == "closed") - state = AIRLOCK_STATE_PRESSURIZE - process_again = 1 - else - post_signal(new /datum/signal(list( - "tag" = exterior_door_tag, - "command" = "secure_close" - ))) - - else - if(memory["pump_status"] != "off") - post_signal(new /datum/signal(list( - "tag" = airpump_tag, - "power" = 0, - "sigtype" = "command" - ))) - - if(AIRLOCK_STATE_DEPRESSURIZE) - var/target_pressure = ONE_ATMOSPHERE*0.05 - if(sanitize_external) - target_pressure = ONE_ATMOSPHERE*0.01 - - if(sensor_pressure <= target_pressure) - if(target_state > state) - if(memory["exterior_status"] == "open") - state = AIRLOCK_STATE_OUTOPEN - else - post_signal(new /datum/signal(list( - "tag" = exterior_door_tag, - "command" = "secure_open" - ))) - else if(target_state < state) - state = AIRLOCK_STATE_CLOSED - process_again = 1 - else if((target_state < state) && !sanitize_external) - state = AIRLOCK_STATE_CLOSED - process_again = 1 - else - var/datum/signal/signal = new(list( - "tag" = airpump_tag, - "sigtype" = "command" - )) - if(memory["pump_status"] == "release") - signal.data["purge"] = 1 - else if(memory["pump_status"] != "siphon") - signal.data["power"] = 1 - post_signal(signal) - - if(AIRLOCK_STATE_OUTOPEN) //state 2 - if(target_state < state) - if(memory["exterior_status"] == "closed") - if(sanitize_external) - state = AIRLOCK_STATE_DEPRESSURIZE - process_again = 1 - else - state = AIRLOCK_STATE_CLOSED - process_again = 1 - else - post_signal(new /datum/signal(list( - "tag" = exterior_door_tag, - "command" = "secure_close" - ))) - else - if(memory["pump_status"] != "off") - post_signal(new /datum/signal(list( - "tag" = airpump_tag, - "power" = 0, - "sigtype" = "command" - ))) - - memory["sensor_pressure"] = sensor_pressure - memory["processing"] = state != target_state - //sensor_pressure = null //not sure if we can comment this out. Uncomment in case of problems -rastaf0 - - return 1 - - -/obj/machinery/embedded_controller/radio/airlock_controller - icon = 'icons/obj/airlock_machines.dmi' - icon_state = "airlock_control_standby" - - name = "airlock console" - density = FALSE - - frequency = FREQ_AIRLOCK_CONTROL - power_channel = ENVIRON - - // Setup parameters only - var/id_tag - var/exterior_door_tag - var/interior_door_tag - var/airpump_tag - var/sensor_tag - var/sanitize_external - -/obj/machinery/embedded_controller/radio/airlock_controller/incinerator_toxmix - name = "Incinerator Access Console" - airpump_tag = INCINERATOR_TOXMIX_DP_VENTPUMP - exterior_door_tag = INCINERATOR_TOXMIX_AIRLOCK_EXTERIOR - id_tag = INCINERATOR_TOXMIX_AIRLOCK_CONTROLLER - interior_door_tag = INCINERATOR_TOXMIX_AIRLOCK_INTERIOR - sanitize_external = TRUE - sensor_tag = INCINERATOR_TOXMIX_AIRLOCK_SENSOR - -/obj/machinery/embedded_controller/radio/airlock_controller/incinerator_atmos - name = "Incinerator Access Console" - airpump_tag = INCINERATOR_ATMOS_DP_VENTPUMP - exterior_door_tag = INCINERATOR_ATMOS_AIRLOCK_EXTERIOR - id_tag = INCINERATOR_ATMOS_AIRLOCK_CONTROLLER - interior_door_tag = INCINERATOR_ATMOS_AIRLOCK_INTERIOR - sanitize_external = TRUE - sensor_tag = INCINERATOR_ATMOS_AIRLOCK_SENSOR - -/obj/machinery/embedded_controller/radio/airlock_controller/incinerator_syndicatelava - name = "Incinerator Access Console" - airpump_tag = INCINERATOR_SYNDICATELAVA_DP_VENTPUMP - exterior_door_tag = INCINERATOR_SYNDICATELAVA_AIRLOCK_EXTERIOR - id_tag = INCINERATOR_SYNDICATELAVA_AIRLOCK_CONTROLLER - interior_door_tag = INCINERATOR_SYNDICATELAVA_AIRLOCK_INTERIOR - sanitize_external = TRUE - sensor_tag = INCINERATOR_SYNDICATELAVA_AIRLOCK_SENSOR - -/obj/machinery/embedded_controller/radio/airlock_controller/Initialize(mapload) - . = ..() - if(!mapload) - return - - var/datum/computer/file/embedded_program/airlock_controller/new_prog = new - - new_prog.id_tag = id_tag - new_prog.exterior_door_tag = exterior_door_tag - new_prog.interior_door_tag = interior_door_tag - new_prog.airpump_tag = airpump_tag - new_prog.sensor_tag = sensor_tag - new_prog.sanitize_external = sanitize_external - - new_prog.master = src - program = new_prog - -/obj/machinery/embedded_controller/radio/airlock_controller/update_icon() - if(on && program) - if(program.memory["processing"]) - icon_state = "airlock_control_process" - else - icon_state = "airlock_control_standby" - else - icon_state = "airlock_control_off" - - -/obj/machinery/embedded_controller/radio/airlock_controller/return_text() - var/state_options = null - - var/state = 0 - var/sensor_pressure = "----" - var/exterior_status = "----" - var/interior_status = "----" - var/pump_status = "----" - var/current_status = "Inactive
       " - if(program) - state = program.state - sensor_pressure = program.memory["sensor_pressure"] ? program.memory["sensor_pressure"] : "----" - exterior_status = program.memory["exterior_status"] ? program.memory["exterior_status"] : "----" - interior_status = program.memory["interior_status"] ? program.memory["interior_status"] : "----" - pump_status = program.memory["pump_status"] ? program.memory["pump_status"] : "----" - - switch(state) - if(AIRLOCK_STATE_INOPEN) - state_options = {"Close Interior Airlock
      -Cycle to Exterior Airlock
      "} - current_status = "Interior Airlock Open
      Chamber Pressurized" - if(AIRLOCK_STATE_PRESSURIZE) - state_options = "Abort Cycling
      " - current_status = "Cycling to Interior Airlock
      Chamber Pressurizing" - if(AIRLOCK_STATE_CLOSED) - state_options = {"Open Interior Airlock
      -Open Exterior Airlock
      "} - if(AIRLOCK_STATE_DEPRESSURIZE) - state_options = "Abort Cycling
      " - current_status = "Cycling to Exterior Airlock
      Chamber Depressurizing" - if(AIRLOCK_STATE_OUTOPEN) - state_options = {"Cycle to Interior Airlock
      -Close Exterior Airlock
      "} - current_status = "Exterior Airlock Open
      Chamber Depressurized" - - var/output = {"

      Airlock Status

      -
      -
      Current Status:
      [current_status]
      -
       
      -
      \> Chamber Pressure:
      [sensor_pressure] kPa
      -
      \> Control Pump:
      [pump_status]
      -
      \> Interior Door:
      [interior_status]
      -
      \> Exterior Door:
      [exterior_status]
      -
      -
      -[state_options]"} - +//States for airlock_control +#define AIRLOCK_STATE_INOPEN -2 +#define AIRLOCK_STATE_PRESSURIZE -1 +#define AIRLOCK_STATE_CLOSED 0 +#define AIRLOCK_STATE_DEPRESSURIZE 1 +#define AIRLOCK_STATE_OUTOPEN 2 + +/datum/computer/file/embedded_program/airlock_controller + var/id_tag + var/exterior_door_tag //Burn chamber facing door + var/interior_door_tag //Station facing door + var/airpump_tag //See: dp_vent_pump.dm + var/sensor_tag //See: /obj/machinery/airlock_sensor + var/sanitize_external //Before the interior airlock opens, do we first drain all gases inside the chamber and then repressurize? + + state = AIRLOCK_STATE_CLOSED + var/target_state = AIRLOCK_STATE_CLOSED + var/sensor_pressure = null + +/datum/computer/file/embedded_program/airlock_controller/receive_signal(datum/signal/signal) + var/receive_tag = signal.data["tag"] + if(!receive_tag) + return + + if(receive_tag==sensor_tag) + if(signal.data["pressure"]) + sensor_pressure = text2num(signal.data["pressure"]) + + else if(receive_tag==exterior_door_tag) + memory["exterior_status"] = signal.data["door_status"] + + else if(receive_tag==interior_door_tag) + memory["interior_status"] = signal.data["door_status"] + + else if(receive_tag==airpump_tag) + if(signal.data["power"]) + memory["pump_status"] = signal.data["direction"] + else + memory["pump_status"] = "off" + + else if(receive_tag==id_tag) + switch(signal.data["command"]) + if("cycle") + if(state < AIRLOCK_STATE_CLOSED) + target_state = AIRLOCK_STATE_OUTOPEN + else + target_state = AIRLOCK_STATE_INOPEN + +/datum/computer/file/embedded_program/airlock_controller/receive_user_command(command) + switch(command) + if("cycle_closed") + target_state = AIRLOCK_STATE_CLOSED + if("cycle_exterior") + target_state = AIRLOCK_STATE_OUTOPEN + if("cycle_interior") + target_state = AIRLOCK_STATE_INOPEN + if("abort") + target_state = AIRLOCK_STATE_CLOSED + +/datum/computer/file/embedded_program/airlock_controller/process() + var/process_again = 1 + while(process_again) + process_again = 0 + switch(state) + if(AIRLOCK_STATE_INOPEN) // state -2 + if(target_state > state) + if(memory["interior_status"] == "closed") + state = AIRLOCK_STATE_CLOSED + process_again = 1 + else + post_signal(new /datum/signal(list( + "tag" = interior_door_tag, + "command" = "secure_close" + ))) + else + if(memory["pump_status"] != "off") + post_signal(new /datum/signal(list( + "tag" = airpump_tag, + "power" = 0, + "sigtype" = "command" + ))) + + if(AIRLOCK_STATE_PRESSURIZE) + if(target_state < state) + if(sensor_pressure >= ONE_ATMOSPHERE*0.95) + if(memory["interior_status"] == "open") + state = AIRLOCK_STATE_INOPEN + process_again = 1 + else + post_signal(new /datum/signal(list( + "tag" = interior_door_tag, + "command" = "secure_open" + ))) + else + var/datum/signal/signal = new(list( + "tag" = airpump_tag, + "sigtype" = "command" + )) + if(memory["pump_status"] == "siphon") + signal.data["stabilize"] = 1 + else if(memory["pump_status"] != "release") + signal.data["power"] = 1 + post_signal(signal) + else if(target_state > state) + state = AIRLOCK_STATE_CLOSED + process_again = 1 + + if(AIRLOCK_STATE_CLOSED) + if(target_state > state) + if(memory["interior_status"] == "closed") + state = AIRLOCK_STATE_DEPRESSURIZE + process_again = 1 + else + post_signal(new /datum/signal(list( + "tag" = interior_door_tag, + "command" = "secure_close" + ))) + else if(target_state < state) + if(memory["exterior_status"] == "closed") + state = AIRLOCK_STATE_PRESSURIZE + process_again = 1 + else + post_signal(new /datum/signal(list( + "tag" = exterior_door_tag, + "command" = "secure_close" + ))) + + else + if(memory["pump_status"] != "off") + post_signal(new /datum/signal(list( + "tag" = airpump_tag, + "power" = 0, + "sigtype" = "command" + ))) + + if(AIRLOCK_STATE_DEPRESSURIZE) + var/target_pressure = ONE_ATMOSPHERE*0.05 + if(sanitize_external) + target_pressure = ONE_ATMOSPHERE*0.01 + + if(sensor_pressure <= target_pressure) + if(target_state > state) + if(memory["exterior_status"] == "open") + state = AIRLOCK_STATE_OUTOPEN + else + post_signal(new /datum/signal(list( + "tag" = exterior_door_tag, + "command" = "secure_open" + ))) + else if(target_state < state) + state = AIRLOCK_STATE_CLOSED + process_again = 1 + else if((target_state < state) && !sanitize_external) + state = AIRLOCK_STATE_CLOSED + process_again = 1 + else + var/datum/signal/signal = new(list( + "tag" = airpump_tag, + "sigtype" = "command" + )) + if(memory["pump_status"] == "release") + signal.data["purge"] = 1 + else if(memory["pump_status"] != "siphon") + signal.data["power"] = 1 + post_signal(signal) + + if(AIRLOCK_STATE_OUTOPEN) //state 2 + if(target_state < state) + if(memory["exterior_status"] == "closed") + if(sanitize_external) + state = AIRLOCK_STATE_DEPRESSURIZE + process_again = 1 + else + state = AIRLOCK_STATE_CLOSED + process_again = 1 + else + post_signal(new /datum/signal(list( + "tag" = exterior_door_tag, + "command" = "secure_close" + ))) + else + if(memory["pump_status"] != "off") + post_signal(new /datum/signal(list( + "tag" = airpump_tag, + "power" = 0, + "sigtype" = "command" + ))) + + memory["sensor_pressure"] = sensor_pressure + memory["processing"] = state != target_state + //sensor_pressure = null //not sure if we can comment this out. Uncomment in case of problems -rastaf0 + + return 1 + + +/obj/machinery/embedded_controller/radio/airlock_controller + icon = 'icons/obj/airlock_machines.dmi' + icon_state = "airlock_control_standby" + + name = "airlock console" + density = FALSE + + frequency = FREQ_AIRLOCK_CONTROL + power_channel = ENVIRON + + // Setup parameters only + var/id_tag + var/exterior_door_tag + var/interior_door_tag + var/airpump_tag + var/sensor_tag + var/sanitize_external + +/obj/machinery/embedded_controller/radio/airlock_controller/incinerator_toxmix + name = "Incinerator Access Console" + airpump_tag = INCINERATOR_TOXMIX_DP_VENTPUMP + exterior_door_tag = INCINERATOR_TOXMIX_AIRLOCK_EXTERIOR + id_tag = INCINERATOR_TOXMIX_AIRLOCK_CONTROLLER + interior_door_tag = INCINERATOR_TOXMIX_AIRLOCK_INTERIOR + sanitize_external = TRUE + sensor_tag = INCINERATOR_TOXMIX_AIRLOCK_SENSOR + +/obj/machinery/embedded_controller/radio/airlock_controller/incinerator_atmos + name = "Incinerator Access Console" + airpump_tag = INCINERATOR_ATMOS_DP_VENTPUMP + exterior_door_tag = INCINERATOR_ATMOS_AIRLOCK_EXTERIOR + id_tag = INCINERATOR_ATMOS_AIRLOCK_CONTROLLER + interior_door_tag = INCINERATOR_ATMOS_AIRLOCK_INTERIOR + sanitize_external = TRUE + sensor_tag = INCINERATOR_ATMOS_AIRLOCK_SENSOR + +/obj/machinery/embedded_controller/radio/airlock_controller/incinerator_syndicatelava + name = "Incinerator Access Console" + airpump_tag = INCINERATOR_SYNDICATELAVA_DP_VENTPUMP + exterior_door_tag = INCINERATOR_SYNDICATELAVA_AIRLOCK_EXTERIOR + id_tag = INCINERATOR_SYNDICATELAVA_AIRLOCK_CONTROLLER + interior_door_tag = INCINERATOR_SYNDICATELAVA_AIRLOCK_INTERIOR + sanitize_external = TRUE + sensor_tag = INCINERATOR_SYNDICATELAVA_AIRLOCK_SENSOR + +/obj/machinery/embedded_controller/radio/airlock_controller/Initialize(mapload) + . = ..() + if(!mapload) + return + + var/datum/computer/file/embedded_program/airlock_controller/new_prog = new + + new_prog.id_tag = id_tag + new_prog.exterior_door_tag = exterior_door_tag + new_prog.interior_door_tag = interior_door_tag + new_prog.airpump_tag = airpump_tag + new_prog.sensor_tag = sensor_tag + new_prog.sanitize_external = sanitize_external + + new_prog.master = src + program = new_prog + +/obj/machinery/embedded_controller/radio/airlock_controller/update_icon() + if(on && program) + if(program.memory["processing"]) + icon_state = "airlock_control_process" + else + icon_state = "airlock_control_standby" + else + icon_state = "airlock_control_off" + + +/obj/machinery/embedded_controller/radio/airlock_controller/return_text() + var/state_options = null + + var/state = 0 + var/sensor_pressure = "----" + var/exterior_status = "----" + var/interior_status = "----" + var/pump_status = "----" + var/current_status = "Inactive
       " + if(program) + state = program.state + sensor_pressure = program.memory["sensor_pressure"] ? program.memory["sensor_pressure"] : "----" + exterior_status = program.memory["exterior_status"] ? program.memory["exterior_status"] : "----" + interior_status = program.memory["interior_status"] ? program.memory["interior_status"] : "----" + pump_status = program.memory["pump_status"] ? program.memory["pump_status"] : "----" + + switch(state) + if(AIRLOCK_STATE_INOPEN) + state_options = {"Close Interior Airlock
      +Cycle to Exterior Airlock
      "} + current_status = "Interior Airlock Open
      Chamber Pressurized" + if(AIRLOCK_STATE_PRESSURIZE) + state_options = "Abort Cycling
      " + current_status = "Cycling to Interior Airlock
      Chamber Pressurizing" + if(AIRLOCK_STATE_CLOSED) + state_options = {"Open Interior Airlock
      +Open Exterior Airlock
      "} + if(AIRLOCK_STATE_DEPRESSURIZE) + state_options = "Abort Cycling
      " + current_status = "Cycling to Exterior Airlock
      Chamber Depressurizing" + if(AIRLOCK_STATE_OUTOPEN) + state_options = {"Cycle to Interior Airlock
      +Close Exterior Airlock
      "} + current_status = "Exterior Airlock Open
      Chamber Depressurized" + + var/output = {"

      Airlock Status

      +
      +
      Current Status:
      [current_status]
      +
       
      +
      \> Chamber Pressure:
      [sensor_pressure] kPa
      +
      \> Control Pump:
      [pump_status]
      +
      \> Interior Door:
      [interior_status]
      +
      \> Exterior Door:
      [exterior_status]
      +
      +
      +[state_options]"} + return output \ No newline at end of file diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index 063cfa6805..f1a2ef9acc 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -1,87 +1,87 @@ -/datum/computer/file/embedded_program - var/list/memory = list() - var/state - var/obj/machinery/embedded_controller/master - -/datum/computer/file/embedded_program/proc/post_signal(datum/signal/signal, comm_line) - if(master) - master.post_signal(signal, comm_line) - else - qdel(signal) - -/datum/computer/file/embedded_program/proc/receive_user_command(command) - -/datum/computer/file/embedded_program/proc/receive_signal(datum/signal/signal) - return null - -/datum/computer/file/embedded_program/process() - return 0 - -/obj/machinery/embedded_controller - var/datum/computer/file/embedded_program/program - - name = "embedded controller" - density = FALSE - - var/on = TRUE - -/obj/machinery/embedded_controller/ui_interact(mob/user) - . = ..() - user.set_machine(src) - var/datum/browser/popup = new(user, "computer", name) // Set up the popup browser window - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.set_content(return_text()) - popup.open() - -/obj/machinery/embedded_controller/update_icon() - -/obj/machinery/embedded_controller/proc/return_text() - -/obj/machinery/embedded_controller/proc/post_signal(datum/signal/signal, comm_line) - return 0 - -/obj/machinery/embedded_controller/receive_signal(datum/signal/signal) - if(istype(signal) && program) - program.receive_signal(signal) - -/obj/machinery/embedded_controller/Topic(href, href_list) - if(..()) - return 0 - - if(program) - program.receive_user_command(href_list["command"]) - addtimer(CALLBACK(program, /datum/computer/file/embedded_program.proc/process), 5) - - usr.set_machine(src) - addtimer(CALLBACK(src, .proc/updateDialog), 5) - -/obj/machinery/embedded_controller/process() - if(program) - program.process() - - update_icon() - src.updateDialog() - -/obj/machinery/embedded_controller/radio - var/frequency - var/datum/radio_frequency/radio_connection - -/obj/machinery/embedded_controller/radio/Destroy() - SSradio.remove_object(src,frequency) - return ..() - -/obj/machinery/embedded_controller/radio/Initialize() - . = ..() - set_frequency(frequency) - -/obj/machinery/embedded_controller/radio/post_signal(datum/signal/signal) - signal.transmission_method = TRANSMISSION_RADIO - if(radio_connection) - return radio_connection.post_signal(src, signal) - else - signal = null - -/obj/machinery/embedded_controller/radio/proc/set_frequency(new_frequency) - SSradio.remove_object(src, frequency) - frequency = new_frequency - radio_connection = SSradio.add_object(src, frequency) +/datum/computer/file/embedded_program + var/list/memory = list() + var/state + var/obj/machinery/embedded_controller/master + +/datum/computer/file/embedded_program/proc/post_signal(datum/signal/signal, comm_line) + if(master) + master.post_signal(signal, comm_line) + else + qdel(signal) + +/datum/computer/file/embedded_program/proc/receive_user_command(command) + +/datum/computer/file/embedded_program/proc/receive_signal(datum/signal/signal) + return null + +/datum/computer/file/embedded_program/process() + return 0 + +/obj/machinery/embedded_controller + var/datum/computer/file/embedded_program/program + + name = "embedded controller" + density = FALSE + + var/on = TRUE + +/obj/machinery/embedded_controller/ui_interact(mob/user) + . = ..() + user.set_machine(src) + var/datum/browser/popup = new(user, "computer", name) // Set up the popup browser window + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.set_content(return_text()) + popup.open() + +/obj/machinery/embedded_controller/update_icon() + +/obj/machinery/embedded_controller/proc/return_text() + +/obj/machinery/embedded_controller/proc/post_signal(datum/signal/signal, comm_line) + return 0 + +/obj/machinery/embedded_controller/receive_signal(datum/signal/signal) + if(istype(signal) && program) + program.receive_signal(signal) + +/obj/machinery/embedded_controller/Topic(href, href_list) + if(..()) + return 0 + + if(program) + program.receive_user_command(href_list["command"]) + addtimer(CALLBACK(program, /datum/computer/file/embedded_program.proc/process), 5) + + usr.set_machine(src) + addtimer(CALLBACK(src, .proc/updateDialog), 5) + +/obj/machinery/embedded_controller/process() + if(program) + program.process() + + update_icon() + src.updateDialog() + +/obj/machinery/embedded_controller/radio + var/frequency + var/datum/radio_frequency/radio_connection + +/obj/machinery/embedded_controller/radio/Destroy() + SSradio.remove_object(src,frequency) + return ..() + +/obj/machinery/embedded_controller/radio/Initialize() + . = ..() + set_frequency(frequency) + +/obj/machinery/embedded_controller/radio/post_signal(datum/signal/signal) + signal.transmission_method = TRANSMISSION_RADIO + if(radio_connection) + return radio_connection.post_signal(src, signal) + else + signal = null + +/obj/machinery/embedded_controller/radio/proc/set_frequency(new_frequency) + SSradio.remove_object(src, frequency) + frequency = new_frequency + radio_connection = SSradio.add_object(src, frequency) diff --git a/code/game/machinery/embedded_controller/simple_vent_controller.dm b/code/game/machinery/embedded_controller/simple_vent_controller.dm index 9901d51074..33be1e3f79 100644 --- a/code/game/machinery/embedded_controller/simple_vent_controller.dm +++ b/code/game/machinery/embedded_controller/simple_vent_controller.dm @@ -1,72 +1,72 @@ -/datum/computer/file/embedded_program/simple_vent_controller - - var/airpump_tag - -/datum/computer/file/embedded_program/simple_vent_controller/receive_user_command(command) - switch(command) - if("vent_inactive") - post_signal(new /datum/signal(list( - "tag" = airpump_tag, - "sigtype" = "command", - "power" = 0 - ))) - - if("vent_pump") - post_signal(new /datum/signal(list( - "tag" = airpump_tag, - "sigtype" = "command", - "stabilize" = 1, - "power" = 1 - ))) - - if("vent_clear") - post_signal(new /datum/signal(list( - "tag" = airpump_tag, - "sigtype" = "command", - "purge" = 1, - "power" = 1 - ))) - -/datum/computer/file/embedded_program/simple_vent_controller/process() - return 0 - - -/obj/machinery/embedded_controller/radio/simple_vent_controller - icon = 'icons/obj/airlock_machines.dmi' - icon_state = "airlock_control_standby" - - name = "vent controller" - density = FALSE - - frequency = FREQ_ATMOS_CONTROL - power_channel = ENVIRON - - // Setup parameters only - var/airpump_tag - -/obj/machinery/embedded_controller/radio/simple_vent_controller/Initialize(mapload) - . = ..() - if(!mapload) - return - var/datum/computer/file/embedded_program/simple_vent_controller/new_prog = new - - new_prog.airpump_tag = airpump_tag - new_prog.master = src - program = new_prog - -/obj/machinery/embedded_controller/radio/simple_vent_controller/update_icon() - if(on && program) - icon_state = "airlock_control_standby" - else - icon_state = "airlock_control_off" - - -/obj/machinery/embedded_controller/radio/simple_vent_controller/return_text() - var/state_options = null - state_options = {"Deactivate Vent
      -Activate Vent / Pump
      -Activate Vent / Clear
      "} - var/output = {"Vent Control Console
      -[state_options]
      "} - - return output +/datum/computer/file/embedded_program/simple_vent_controller + + var/airpump_tag + +/datum/computer/file/embedded_program/simple_vent_controller/receive_user_command(command) + switch(command) + if("vent_inactive") + post_signal(new /datum/signal(list( + "tag" = airpump_tag, + "sigtype" = "command", + "power" = 0 + ))) + + if("vent_pump") + post_signal(new /datum/signal(list( + "tag" = airpump_tag, + "sigtype" = "command", + "stabilize" = 1, + "power" = 1 + ))) + + if("vent_clear") + post_signal(new /datum/signal(list( + "tag" = airpump_tag, + "sigtype" = "command", + "purge" = 1, + "power" = 1 + ))) + +/datum/computer/file/embedded_program/simple_vent_controller/process() + return 0 + + +/obj/machinery/embedded_controller/radio/simple_vent_controller + icon = 'icons/obj/airlock_machines.dmi' + icon_state = "airlock_control_standby" + + name = "vent controller" + density = FALSE + + frequency = FREQ_ATMOS_CONTROL + power_channel = ENVIRON + + // Setup parameters only + var/airpump_tag + +/obj/machinery/embedded_controller/radio/simple_vent_controller/Initialize(mapload) + . = ..() + if(!mapload) + return + var/datum/computer/file/embedded_program/simple_vent_controller/new_prog = new + + new_prog.airpump_tag = airpump_tag + new_prog.master = src + program = new_prog + +/obj/machinery/embedded_controller/radio/simple_vent_controller/update_icon() + if(on && program) + icon_state = "airlock_control_standby" + else + icon_state = "airlock_control_off" + + +/obj/machinery/embedded_controller/radio/simple_vent_controller/return_text() + var/state_options = null + state_options = {"Deactivate Vent
      +Activate Vent / Pump
      +Activate Vent / Clear
      "} + var/output = {"Vent Control Console
      +[state_options]
      "} + + return output diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index def530a14d..6f89ce0d45 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -1,205 +1,205 @@ -// It is a gizmo that flashes a small area - -/obj/machinery/flasher - name = "mounted flash" - desc = "A wall-mounted flashbulb device." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "mflash1" - max_integrity = 250 - integrity_failure = 100 - light_color = LIGHT_COLOR_WHITE - light_power = FLASH_LIGHT_POWER - var/obj/item/assembly/flash/handheld/bulb - var/id = null - var/range = 2 //this is roughly the size of brig cell - var/last_flash = 0 //Don't want it getting spammed like regular flashes - var/strength = 100 //How knocked down targets are when flashed. - var/base_state = "mflash" - -/obj/machinery/flasher/portable //Portable version of the flasher. Only flashes when anchored - name = "portable flasher" - desc = "A portable flashing device. Wrench to activate and deactivate. Cannot detect slow movements." - icon_state = "pflash1-p" - strength = 80 - anchored = FALSE - base_state = "pflash" - density = TRUE - -/obj/machinery/flasher/Initialize(mapload, ndir = 0, built = 0) - . = ..() // ..() is EXTREMELY IMPORTANT, never forget to add it - if(built) - setDir(ndir) - pixel_x = (dir & 3)? 0 : (dir == 4 ? -28 : 28) - pixel_y = (dir & 3)? (dir ==1 ? -28 : 28) : 0 - else - bulb = new(src) - -/obj/machinery/flasher/Destroy() - QDEL_NULL(bulb) - return ..() - -/obj/machinery/flasher/power_change() - if (powered() && anchored && bulb) - stat &= ~NOPOWER - if(bulb.crit_fail) - icon_state = "[base_state]1-p" - else - icon_state = "[base_state]1" - else - stat |= NOPOWER - icon_state = "[base_state]1-p" - -//Don't want to render prison breaks impossible -/obj/machinery/flasher/attackby(obj/item/W, mob/user, params) - add_fingerprint(user) - if (istype(W, /obj/item/wirecutters)) - if (bulb) - user.visible_message("[user] begins to disconnect [src]'s flashbulb.", "You begin to disconnect [src]'s flashbulb...") - if(W.use_tool(src, user, 30, volume=50) && bulb) - user.visible_message("[user] has disconnected [src]'s flashbulb!", "You disconnect [src]'s flashbulb.") - bulb.forceMove(loc) - bulb = null - power_change() - - else if (istype(W, /obj/item/assembly/flash/handheld)) - if (!bulb) - if(!user.transferItemToLoc(W, src)) - return - user.visible_message("[user] installs [W] into [src].", "You install [W] into [src].") - bulb = W - power_change() - else - to_chat(user, "A flashbulb is already installed in [src]!") - - else if (istype(W, /obj/item/wrench)) - if(!bulb) - to_chat(user, "You start unsecuring the flasher frame...") - if(W.use_tool(src, user, 40, volume=50)) - to_chat(user, "You unsecure the flasher frame.") - deconstruct(TRUE) - else - to_chat(user, "Remove a flashbulb from [src] first!") - else - return ..() - -//Let the AI trigger them directly. -/obj/machinery/flasher/attack_ai() - if (anchored) - return flash() - -/obj/machinery/flasher/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) - if(damage_flag == "melee" && damage_amount < 10) //any melee attack below 10 dmg does nothing - return 0 - . = ..() - -/obj/machinery/flasher/proc/flash() - if (!powered() || !bulb) - return - - if (bulb.crit_fail || (last_flash && world.time < src.last_flash + 150)) - return - - if(!bulb.flash_recharge(30)) //Bulb can burn out if it's used too often too fast - power_change() - return - - playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1) - flick("[base_state]_flash", src) - flash_lighting_fx(FLASH_LIGHT_RANGE, light_power, light_color) - last_flash = world.time - use_power(1000) - - var/flashed = FALSE - for (var/mob/living/L in viewers(src, null)) - if (get_dist(src, L) > range) - continue - - if(L.flash_act(affect_silicon = 1)) - L.Knockdown(strength) - flashed = TRUE - - if(flashed) - bulb.times_used++ - - return 1 - - -/obj/machinery/flasher/emp_act(severity) - . = ..() - if(!(stat & (BROKEN|NOPOWER)) && !(. & EMP_PROTECT_SELF)) - if(bulb && prob(75/severity)) - flash() - bulb.burn_out() - power_change() - -/obj/machinery/flasher/obj_break(damage_flag) - if(!(flags_1 & NODECONSTRUCT_1)) - if(!(stat & BROKEN)) - stat |= BROKEN - if(bulb) - bulb.burn_out() - power_change() - -/obj/machinery/flasher/deconstruct(disassembled = TRUE) - if(!(flags_1 & NODECONSTRUCT_1)) - if(bulb) - bulb.forceMove(loc) - bulb = null - if(disassembled) - var/obj/item/wallframe/flasher/F = new(get_turf(src)) - transfer_fingerprints_to(F) - F.id = id - playsound(loc, 'sound/items/deconstruct.ogg', 50, 1) - else - new /obj/item/stack/sheet/metal (loc, 2) - qdel(src) - -/obj/machinery/flasher/portable/Initialize() - . = ..() - proximity_monitor = new(src, 0) - -/obj/machinery/flasher/portable/HasProximity(atom/movable/AM) - if (last_flash && world.time < last_flash + 150) - return - - if(istype(AM, /mob/living/carbon)) - var/mob/living/carbon/M = AM - if (M.m_intent != MOVE_INTENT_WALK && anchored) - flash() - -/obj/machinery/flasher/portable/attackby(obj/item/W, mob/user, params) - if (istype(W, /obj/item/wrench)) - W.play_tool_sound(src, 100) - - if (!anchored && !isinspace()) - to_chat(user, "[src] is now secured.") - add_overlay("[base_state]-s") - setAnchored(TRUE) - power_change() - proximity_monitor.SetRange(range) - else - to_chat(user, "[src] can now be moved.") - cut_overlays() - setAnchored(FALSE) - power_change() - proximity_monitor.SetRange(0) - - else - return ..() - -/obj/item/wallframe/flasher - name = "mounted flash frame" - desc = "Used for building wall-mounted flashers." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "mflash_frame" - result_path = /obj/machinery/flasher - var/id = null - -/obj/item/wallframe/flasher/examine(mob/user) - . = ..() - . += "Its channel ID is '[id]'." - -/obj/item/wallframe/flasher/after_attach(var/obj/O) - ..() - var/obj/machinery/flasher/F = O - F.id = id +// It is a gizmo that flashes a small area + +/obj/machinery/flasher + name = "mounted flash" + desc = "A wall-mounted flashbulb device." + icon = 'icons/obj/stationobjs.dmi' + icon_state = "mflash1" + max_integrity = 250 + integrity_failure = 100 + light_color = LIGHT_COLOR_WHITE + light_power = FLASH_LIGHT_POWER + var/obj/item/assembly/flash/handheld/bulb + var/id = null + var/range = 2 //this is roughly the size of brig cell + var/last_flash = 0 //Don't want it getting spammed like regular flashes + var/strength = 100 //How knocked down targets are when flashed. + var/base_state = "mflash" + +/obj/machinery/flasher/portable //Portable version of the flasher. Only flashes when anchored + name = "portable flasher" + desc = "A portable flashing device. Wrench to activate and deactivate. Cannot detect slow movements." + icon_state = "pflash1-p" + strength = 80 + anchored = FALSE + base_state = "pflash" + density = TRUE + +/obj/machinery/flasher/Initialize(mapload, ndir = 0, built = 0) + . = ..() // ..() is EXTREMELY IMPORTANT, never forget to add it + if(built) + setDir(ndir) + pixel_x = (dir & 3)? 0 : (dir == 4 ? -28 : 28) + pixel_y = (dir & 3)? (dir ==1 ? -28 : 28) : 0 + else + bulb = new(src) + +/obj/machinery/flasher/Destroy() + QDEL_NULL(bulb) + return ..() + +/obj/machinery/flasher/power_change() + if (powered() && anchored && bulb) + stat &= ~NOPOWER + if(bulb.crit_fail) + icon_state = "[base_state]1-p" + else + icon_state = "[base_state]1" + else + stat |= NOPOWER + icon_state = "[base_state]1-p" + +//Don't want to render prison breaks impossible +/obj/machinery/flasher/attackby(obj/item/W, mob/user, params) + add_fingerprint(user) + if (istype(W, /obj/item/wirecutters)) + if (bulb) + user.visible_message("[user] begins to disconnect [src]'s flashbulb.", "You begin to disconnect [src]'s flashbulb...") + if(W.use_tool(src, user, 30, volume=50) && bulb) + user.visible_message("[user] has disconnected [src]'s flashbulb!", "You disconnect [src]'s flashbulb.") + bulb.forceMove(loc) + bulb = null + power_change() + + else if (istype(W, /obj/item/assembly/flash/handheld)) + if (!bulb) + if(!user.transferItemToLoc(W, src)) + return + user.visible_message("[user] installs [W] into [src].", "You install [W] into [src].") + bulb = W + power_change() + else + to_chat(user, "A flashbulb is already installed in [src]!") + + else if (istype(W, /obj/item/wrench)) + if(!bulb) + to_chat(user, "You start unsecuring the flasher frame...") + if(W.use_tool(src, user, 40, volume=50)) + to_chat(user, "You unsecure the flasher frame.") + deconstruct(TRUE) + else + to_chat(user, "Remove a flashbulb from [src] first!") + else + return ..() + +//Let the AI trigger them directly. +/obj/machinery/flasher/attack_ai() + if (anchored) + return flash() + +/obj/machinery/flasher/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir) + if(damage_flag == "melee" && damage_amount < 10) //any melee attack below 10 dmg does nothing + return 0 + . = ..() + +/obj/machinery/flasher/proc/flash() + if (!powered() || !bulb) + return + + if (bulb.crit_fail || (last_flash && world.time < src.last_flash + 150)) + return + + if(!bulb.flash_recharge(30)) //Bulb can burn out if it's used too often too fast + power_change() + return + + playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1) + flick("[base_state]_flash", src) + flash_lighting_fx(FLASH_LIGHT_RANGE, light_power, light_color) + last_flash = world.time + use_power(1000) + + var/flashed = FALSE + for (var/mob/living/L in viewers(src, null)) + if (get_dist(src, L) > range) + continue + + if(L.flash_act(affect_silicon = 1)) + L.Knockdown(strength) + flashed = TRUE + + if(flashed) + bulb.times_used++ + + return 1 + + +/obj/machinery/flasher/emp_act(severity) + . = ..() + if(!(stat & (BROKEN|NOPOWER)) && !(. & EMP_PROTECT_SELF)) + if(bulb && prob(75/severity)) + flash() + bulb.burn_out() + power_change() + +/obj/machinery/flasher/obj_break(damage_flag) + if(!(flags_1 & NODECONSTRUCT_1)) + if(!(stat & BROKEN)) + stat |= BROKEN + if(bulb) + bulb.burn_out() + power_change() + +/obj/machinery/flasher/deconstruct(disassembled = TRUE) + if(!(flags_1 & NODECONSTRUCT_1)) + if(bulb) + bulb.forceMove(loc) + bulb = null + if(disassembled) + var/obj/item/wallframe/flasher/F = new(get_turf(src)) + transfer_fingerprints_to(F) + F.id = id + playsound(loc, 'sound/items/deconstruct.ogg', 50, 1) + else + new /obj/item/stack/sheet/metal (loc, 2) + qdel(src) + +/obj/machinery/flasher/portable/Initialize() + . = ..() + proximity_monitor = new(src, 0) + +/obj/machinery/flasher/portable/HasProximity(atom/movable/AM) + if (last_flash && world.time < last_flash + 150) + return + + if(istype(AM, /mob/living/carbon)) + var/mob/living/carbon/M = AM + if (M.m_intent != MOVE_INTENT_WALK && anchored) + flash() + +/obj/machinery/flasher/portable/attackby(obj/item/W, mob/user, params) + if (istype(W, /obj/item/wrench)) + W.play_tool_sound(src, 100) + + if (!anchored && !isinspace()) + to_chat(user, "[src] is now secured.") + add_overlay("[base_state]-s") + setAnchored(TRUE) + power_change() + proximity_monitor.SetRange(range) + else + to_chat(user, "[src] can now be moved.") + cut_overlays() + setAnchored(FALSE) + power_change() + proximity_monitor.SetRange(0) + + else + return ..() + +/obj/item/wallframe/flasher + name = "mounted flash frame" + desc = "Used for building wall-mounted flashers." + icon = 'icons/obj/stationobjs.dmi' + icon_state = "mflash_frame" + result_path = /obj/machinery/flasher + var/id = null + +/obj/item/wallframe/flasher/examine(mob/user) + . = ..() + . += "Its channel ID is '[id]'." + +/obj/item/wallframe/flasher/after_attach(var/obj/O) + ..() + var/obj/machinery/flasher/F = O + F.id = id diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index b1783ba940..40fc52d6a1 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -1,700 +1,700 @@ -/* Holograms! - * Contains: - * Holopad - * Hologram - * Other stuff - */ - -/* -Revised. Original based on space ninja hologram code. Which is also mine. /N -How it works: -AI clicks on holopad in camera view. View centers on holopad. -AI clicks again on the holopad to display a hologram. Hologram stays as long as AI is looking at the pad and it (the hologram) is in range of the pad. -AI can use the directional keys to move the hologram around, provided the above conditions are met and the AI in question is the holopad's master. -Any number of AIs can use a holopad. /Lo6 -AI may cancel the hologram at any time by clicking on the holopad once more. - -Possible to do for anyone motivated enough: - Give an AI variable for different hologram icons. - Itegrate EMP effect to disable the unit. -*/ - - -/* - * Holopad - */ - -GLOBAL_LIST_EMPTY(network_holopads) - -#define HOLOPAD_PASSIVE_POWER_USAGE 1 -#define HOLOGRAM_POWER_USAGE 2 - -/obj/machinery/holopad - name = "holopad" - desc = "It's a floor-mounted device for projecting holographic images." - icon_state = "holopad0" - layer = LOW_OBJ_LAYER - plane = FLOOR_PLANE - flags_1 = HEAR_1 - use_power = IDLE_POWER_USE - idle_power_usage = 5 - active_power_usage = 100 - max_integrity = 300 - armor = list("melee" = 50, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0) - circuit = /obj/item/circuitboard/machine/holopad - var/list/masters //List of living mobs that use the holopad - var/list/holorays //Holoray-mob link. - var/last_request = 0 //to prevent request spam. ~Carn - var/holo_range = 5 // Change to change how far the AI can move away from the holopad before deactivating. - var/temp = "" - var/list/holo_calls //array of /datum/holocalls - var/datum/holocall/outgoing_call //do not modify the datums only check and call the public procs - var/obj/item/disk/holodisk/disk //Record disk - var/replay_mode = FALSE //currently replaying a recording - var/loop_mode = FALSE //currently looping a recording - var/record_mode = FALSE //currently recording - var/record_start = 0 //recording start time - var/record_user //user that inititiated the recording - var/obj/effect/overlay/holo_pad_hologram/replay_holo //replay hologram - var/static/force_answer_call = FALSE //Calls will be automatically answered after a couple rings, here for debugging - var/obj/effect/overlay/holoray/ray - var/ringing = FALSE - var/offset = FALSE - var/on_network = TRUE - -/obj/machinery/holopad/tutorial - resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - flags_1 = NODECONSTRUCT_1 - on_network = FALSE - var/proximity_range = 1 - -/obj/machinery/holopad/tutorial/Initialize(mapload) - . = ..() - if(proximity_range) - proximity_monitor = new(src, proximity_range) - if(mapload) - var/obj/item/disk/holodisk/new_disk = locate(/obj/item/disk/holodisk) in src.loc - if(new_disk && !disk) - new_disk.forceMove(src) - disk = new_disk - -/obj/machinery/holopad/tutorial/attack_hand(mob/user) - if(!istype(user)) - return - if(user.incapacitated() || !is_operational()) - return - if(replay_mode) - replay_stop() - else if(disk && disk.record) - replay_start() - -/obj/machinery/holopad/tutorial/HasProximity(atom/movable/AM) - if (!isliving(AM)) - return - if(!replay_mode && (disk && disk.record)) - replay_start() - -/obj/machinery/holopad/Initialize() - . = ..() - if(on_network) - GLOB.network_holopads += src - -/obj/machinery/holopad/Destroy() - if(outgoing_call) - outgoing_call.ConnectionFailure(src) - - for(var/I in holo_calls) - var/datum/holocall/HC = I - HC.ConnectionFailure(src) - - for (var/I in masters) - clear_holo(I) - - if(replay_mode) - replay_stop() - if(record_mode) - record_stop() - - QDEL_NULL(disk) - - GLOB.network_holopads -= src - return ..() - -/obj/machinery/holopad/power_change() - if (powered()) - stat &= ~NOPOWER - else - stat |= NOPOWER - if(replay_mode) - replay_stop() - if(record_mode) - record_stop() - if(outgoing_call) - outgoing_call.ConnectionFailure(src) - -/obj/machinery/holopad/obj_break() - . = ..() - if(outgoing_call) - outgoing_call.ConnectionFailure(src) - -/obj/machinery/holopad/RefreshParts() - var/holograph_range = 4 - for(var/obj/item/stock_parts/capacitor/B in component_parts) - holograph_range += 1 * B.rating - holo_range = holograph_range - -/obj/machinery/holopad/attackby(obj/item/P, mob/user, params) - if(default_deconstruction_screwdriver(user, "holopad_open", "holopad0", P)) - return - - if(default_pry_open(P)) - return - - if(default_unfasten_wrench(user, P)) - return - - if(default_deconstruction_crowbar(P)) - return - - if(istype(P,/obj/item/disk/holodisk)) - if(disk) - to_chat(user,"There's already a disk inside [src]") - return - if (!user.transferItemToLoc(P,src)) - return - to_chat(user,"You insert [P] into [src]") - disk = P - updateDialog() - return - - return ..() - - -/obj/machinery/holopad/ui_interact(mob/living/carbon/human/user) //Carn: Hologram requests. - . = ..() - if(!istype(user)) - return - - if(outgoing_call || user.incapacitated() || !is_operational()) - return - - user.set_machine(src) - var/dat - if(temp) - dat = temp - else - if(on_network) - dat += "Request an AI's presence
      " - dat += "Call another holopad
      " - if(disk) - if(disk.record) - //Replay - dat += "Replay disk recording
      " - dat += "Loop disk recording
      " - //Clear - dat += "Clear disk recording
      " - else - //Record - dat += "Start new recording
      " - //Eject - dat += "Eject disk
      " - - if(LAZYLEN(holo_calls)) - dat += "=====================================================
      " - - if(on_network) - var/one_answered_call = FALSE - var/one_unanswered_call = FALSE - for(var/I in holo_calls) - var/datum/holocall/HC = I - if(HC.connected_holopad != src) - dat += "Answer call from [get_area(HC.calling_holopad)]
      " - one_unanswered_call = TRUE - else - one_answered_call = TRUE - - if(one_answered_call && one_unanswered_call) - dat += "=====================================================
      " - //we loop twice for formatting - for(var/I in holo_calls) - var/datum/holocall/HC = I - if(HC.connected_holopad == src) - dat += "Disconnect call from [HC.user]
      " - - - var/datum/browser/popup = new(user, "holopad", name, 300, 175) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - -//Stop ringing the AI!! -/obj/machinery/holopad/proc/hangup_all_calls() - for(var/I in holo_calls) - var/datum/holocall/HC = I - HC.Disconnect(src) - -/obj/machinery/holopad/Topic(href, href_list) - if(..() || isAI(usr)) - return - add_fingerprint(usr) - if(!is_operational()) - return - if (href_list["AIrequest"]) - if(last_request + 200 < world.time) - last_request = world.time - temp = "You requested an AI's presence.
      " - temp += "Main Menu" - var/area/area = get_area(src) - for(var/mob/living/silicon/ai/AI in GLOB.silicon_mobs) - if(!AI.client) - continue - to_chat(AI, "Your presence is requested at \the [area].") - else - temp = "A request for AI presence was already sent recently.
      " - temp += "Main Menu" - - else if(href_list["Holocall"]) - if(outgoing_call) - return - - temp = "You must stand on the holopad to make a call!
      " - temp += "Main Menu" - if(usr.loc == loc) - var/list/callnames = list() - for(var/I in GLOB.network_holopads) - var/area/A = get_area(I) - if(A) - LAZYADD(callnames[A], I) - callnames -= get_area(src) - - var/result = input(usr, "Choose an area to call", "Holocall") as null|anything in callnames - if(QDELETED(usr) || !result || outgoing_call) - return - - if(usr.loc == loc) - temp = "Dialing...
      " - temp += "Main Menu" - new /datum/holocall(usr, src, callnames[result]) - - else if(href_list["connectcall"]) - var/datum/holocall/call_to_connect = locate(href_list["connectcall"]) - if(!QDELETED(call_to_connect)) - call_to_connect.Answer(src) - temp = "" - - else if(href_list["disconnectcall"]) - var/datum/holocall/call_to_disconnect = locate(href_list["disconnectcall"]) - if(!QDELETED(call_to_disconnect)) - call_to_disconnect.Disconnect(src) - temp = "" - - else if(href_list["mainmenu"]) - temp = "" - if(outgoing_call) - outgoing_call.Disconnect() - - else if(href_list["disk_eject"]) - if(disk && !replay_mode) - disk.forceMove(drop_location()) - disk = null - - else if(href_list["replay_stop"]) - replay_stop() - else if(href_list["replay_start"]) - replay_start() - else if(href_list["loop_start"]) - loop_mode = TRUE - replay_start() - else if(href_list["record_start"]) - record_start(usr) - else if(href_list["record_stop"]) - record_stop() - else if(href_list["record_clear"]) - record_clear() - else if(href_list["offset"]) - offset++ - if (offset > 4) - offset = FALSE - var/turf/new_turf - if (!offset) - new_turf = get_turf(src) - else - new_turf = get_step(src, GLOB.cardinals[offset]) - replay_holo.forceMove(new_turf) - updateDialog() - -//do not allow AIs to answer calls or people will use it to meta the AI sattelite -/obj/machinery/holopad/attack_ai(mob/living/silicon/ai/user) - if (!istype(user)) - return - if (!on_network) - return - /*There are pretty much only three ways to interact here. - I don't need to check for client since they're clicking on an object. - This may change in the future but for now will suffice.*/ - if(user.eyeobj.loc != src.loc)//Set client eye on the object if it's not already. - user.eyeobj.setLoc(get_turf(src)) - else if(!LAZYLEN(masters) || !masters[user])//If there is no hologram, possibly make one. - activate_holo(user) - else//If there is a hologram, remove it. - clear_holo(user) - -/obj/machinery/holopad/process() - if(LAZYLEN(masters)) - for(var/I in masters) - var/mob/living/master = I - var/mob/living/silicon/ai/AI = master - if(!istype(AI)) - AI = null - - if(!is_operational() || !validate_user(master)) - clear_holo(master) - - if(outgoing_call) - outgoing_call.Check() - - ringing = FALSE - - for(var/I in holo_calls) - var/datum/holocall/HC = I - if(HC.connected_holopad != src) - if(force_answer_call && world.time > (HC.call_start_time + (HOLOPAD_MAX_DIAL_TIME / 2))) - HC.Answer(src) - break - if(outgoing_call) - HC.Disconnect(src)//can't answer calls while calling - else - playsound(src, 'sound/machines/twobeep.ogg', 100) //bring, bring! - ringing = TRUE - - update_icon() - -/obj/machinery/holopad/proc/activate_holo(mob/living/user) - var/mob/living/silicon/ai/AI = user - if(!istype(AI)) - AI = null - - if(is_operational() && (!AI || AI.eyeobj.loc == loc))//If the projector has power and client eye is on it - if (AI && istype(AI.current, /obj/machinery/holopad)) - to_chat(user, "ERROR: \black Image feed in progress.") - return - - var/obj/effect/overlay/holo_pad_hologram/Hologram = new(loc)//Spawn a blank effect at the location. - if(AI) - Hologram.icon = AI.holo_icon - else //make it like real life - Hologram.icon = user.icon - Hologram.icon_state = user.icon_state - Hologram.copy_overlays(user, TRUE) - //codersprite some holo effects here - Hologram.alpha = 100 - Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY) - Hologram.Impersonation = user - - Hologram.copy_known_languages_from(user,replace = TRUE) - Hologram.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it. - Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. - Hologram.setAnchored(TRUE)//So space wind cannot drag it. - Hologram.name = "[user.name] (Hologram)"//If someone decides to right click. - Hologram.set_light(2) //hologram lighting - move_hologram() - - set_holo(user, Hologram) - visible_message("A holographic image of [user] flickers to life before your eyes!") - - return Hologram - else - to_chat(user, "ERROR: Unable to project hologram.") - -/*This is the proc for special two-way communication between AI and holopad/people talking near holopad. -For the other part of the code, check silicon say.dm. Particularly robot talk.*/ -/obj/machinery/holopad/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source) - . = ..() - if(speaker && LAZYLEN(masters) && !radio_freq)//Master is mostly a safety in case lag hits or something. Radio_freq so AIs dont hear holopad stuff through radios. - for(var/mob/living/silicon/ai/master in masters) - if(masters[master] && speaker != master) - master.relay_speech(message, speaker, message_language, raw_message, radio_freq, spans, message_mode) - - for(var/I in holo_calls) - var/datum/holocall/HC = I - if(HC.connected_holopad == src && speaker != HC.hologram) - HC.user.Hear(message, speaker, message_language, raw_message, radio_freq, spans, message_mode, source) - - if(outgoing_call && speaker == outgoing_call.user) - outgoing_call.hologram.say(raw_message) - - if(record_mode && speaker == record_user) - record_message(speaker,raw_message,message_language) - -/obj/machinery/holopad/proc/SetLightsAndPower() - var/total_users = LAZYLEN(masters) + LAZYLEN(holo_calls) - use_power = total_users > 0 ? ACTIVE_POWER_USE : IDLE_POWER_USE - active_power_usage = HOLOPAD_PASSIVE_POWER_USAGE + (HOLOGRAM_POWER_USAGE * total_users) - if(total_users || replay_mode) - set_light(2) - else - set_light(0) - update_icon() - -/obj/machinery/holopad/update_icon() - var/total_users = LAZYLEN(masters) + LAZYLEN(holo_calls) - if(ringing) - icon_state = "holopad_ringing" - else if(total_users || replay_mode) - icon_state = "holopad1" - else - icon_state = "holopad0" - -/obj/machinery/holopad/proc/set_holo(mob/living/user, var/obj/effect/overlay/holo_pad_hologram/h) - LAZYSET(masters, user, h) - LAZYSET(holorays, user, new /obj/effect/overlay/holoray(loc)) - var/mob/living/silicon/ai/AI = user - if(istype(AI)) - AI.current = src - SetLightsAndPower() - update_holoray(user, get_turf(loc)) - return TRUE - -/obj/machinery/holopad/proc/clear_holo(mob/living/user) - qdel(masters[user]) // Get rid of user's hologram - unset_holo(user) - return TRUE - -/obj/machinery/holopad/proc/unset_holo(mob/living/user) - var/mob/living/silicon/ai/AI = user - if(istype(AI) && AI.current == src) - AI.current = null - LAZYREMOVE(masters, user) // Discard AI from the list of those who use holopad - qdel(holorays[user]) - LAZYREMOVE(holorays, user) - SetLightsAndPower() - return TRUE - -//Try to transfer hologram to another pad that can project on T -/obj/machinery/holopad/proc/transfer_to_nearby_pad(turf/T,mob/holo_owner) - var/obj/effect/overlay/holo_pad_hologram/h = masters[holo_owner] - if(!h || h.HC) //Holocalls can't change source. - return FALSE - for(var/pad in GLOB.network_holopads) - var/obj/machinery/holopad/another = pad - if(another == src) - continue - if(another.validate_location(T)) - unset_holo(holo_owner) - if(another.masters && another.masters[holo_owner]) - another.clear_holo(holo_owner) - another.set_holo(holo_owner, h) - return TRUE - return FALSE - -/obj/machinery/holopad/proc/validate_user(mob/living/user) - if(QDELETED(user) || user.incapacitated() || !user.client) - return FALSE - return TRUE - -//Can we display holos there -//Area check instead of line of sight check because this is a called a lot if AI wants to move around. -/obj/machinery/holopad/proc/validate_location(turf/T,check_los = FALSE) - if(T.z == z && get_dist(T, src) <= holo_range && T.loc == get_area(src)) - return TRUE - else - return FALSE - -/obj/machinery/holopad/proc/move_hologram(mob/living/user, turf/new_turf, direction) - if(LAZYLEN(masters) && masters[user]) - var/obj/effect/overlay/holo_pad_hologram/holo = masters[user] - var/transfered = FALSE - if(!validate_location(new_turf)) - if(!transfer_to_nearby_pad(new_turf,user)) - clear_holo(user) - return FALSE - else - transfered = TRUE - //All is good. - holo.forceMove(new_turf) - if(direction) - holo.setDir(direction) - if(!transfered) - update_holoray(user,new_turf) - return TRUE - - -/obj/machinery/holopad/proc/update_holoray(mob/living/user, turf/new_turf) - var/obj/effect/overlay/holo_pad_hologram/holo = masters[user] - var/obj/effect/overlay/holoray/ray = holorays[user] - var/disty = holo.y - ray.y - var/distx = holo.x - ray.x - var/newangle - if(!disty) - if(distx >= 0) - newangle = 90 - else - newangle = 270 - else - newangle = arctan(distx/disty) - if(disty < 0) - newangle += 180 - else if(distx < 0) - newangle += 360 - var/matrix/M = matrix() - if (get_dist(get_turf(holo),new_turf) <= 1) - animate(ray, transform = turn(M.Scale(1,sqrt(distx*distx+disty*disty)),newangle),time = 1) - else - ray.transform = turn(M.Scale(1,sqrt(distx*distx+disty*disty)),newangle) - -// RECORDED MESSAGES - -/obj/machinery/holopad/proc/setup_replay_holo(datum/holorecord/record) - var/obj/effect/overlay/holo_pad_hologram/Hologram = new(loc)//Spawn a blank effect at the location. - Hologram.add_overlay(record.caller_image) - Hologram.alpha = 170 - Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY) - Hologram.dir = SOUTH //for now - Hologram.grant_all_languages(omnitongue=TRUE) - var/datum/language_holder/holder = Hologram.get_language_holder() - holder.selected_default_language = record.language - Hologram.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it. - Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. - Hologram.setAnchored(TRUE)//So space wind cannot drag it. - Hologram.name = "[record.caller_name] (Hologram)"//If someone decides to right click. - Hologram.set_light(2) //hologram lighting - visible_message("A holographic image of [record.caller_name] flickers to life before your eyes!") - return Hologram - -/obj/machinery/holopad/proc/replay_start() - if(!replay_mode) - replay_mode = TRUE - replay_holo = setup_replay_holo(disk.record) - temp = "Replaying...
      " - temp += "Change offset
      " - temp += "End replay" - SetLightsAndPower() - replay_entry(1) - return - -/obj/machinery/holopad/proc/replay_stop() - if(replay_mode) - replay_mode = FALSE - loop_mode = FALSE - offset = FALSE - temp = null - QDEL_NULL(replay_holo) - SetLightsAndPower() - updateDialog() - -/obj/machinery/holopad/proc/record_start(mob/living/user) - if(!user || !disk || disk.record) - return - disk.record = new - record_mode = TRUE - record_start = world.time - record_user = user - disk.record.set_caller_image(user) - temp = "Recording...
      " - temp += "End recording." - -/obj/machinery/holopad/proc/record_message(mob/living/speaker,message,language) - if(!record_mode) - return - //make this command so you can have multiple languages in single record - if((!disk.record.caller_name || disk.record.caller_name == "Unknown") && istype(speaker)) - disk.record.caller_name = speaker.name - if(!disk.record.language) - disk.record.language = language - else if(language != disk.record.language) - disk.record.entries += list(list(HOLORECORD_LANGUAGE,language)) - - var/current_delay = 0 - for(var/E in disk.record.entries) - var/list/entry = E - if(entry[1] != HOLORECORD_DELAY) - continue - current_delay += entry[2] - - var/time_delta = world.time - record_start - current_delay - - if(time_delta >= 1) - disk.record.entries += list(list(HOLORECORD_DELAY,time_delta)) - disk.record.entries += list(list(HOLORECORD_SAY,message)) - if(disk.record.entries.len >= HOLORECORD_MAX_LENGTH) - record_stop() - -/obj/machinery/holopad/proc/replay_entry(entry_number) - if(!replay_mode) - return - if (!disk.record.entries.len) // check for zero entries such as photographs and no text recordings - return // and pretty much just display them statically untill manually stopped - if(disk.record.entries.len < entry_number) - if(loop_mode) - entry_number = 1 - else - replay_stop() - return - var/list/entry = disk.record.entries[entry_number] - var/command = entry[1] - switch(command) - if(HOLORECORD_SAY) - var/message = entry[2] - if(replay_holo) - replay_holo.say(message) - if(HOLORECORD_SOUND) - playsound(src,entry[2],50,1) - if(HOLORECORD_DELAY) - addtimer(CALLBACK(src,.proc/replay_entry,entry_number+1),entry[2]) - return - if(HOLORECORD_LANGUAGE) - var/datum/language_holder/holder = replay_holo.get_language_holder() - holder.selected_default_language = entry[2] - if(HOLORECORD_PRESET) - var/preset_type = entry[2] - var/datum/preset_holoimage/H = new preset_type - replay_holo.cut_overlays() - replay_holo.add_overlay(H.build_image()) - if(HOLORECORD_RENAME) - replay_holo.name = entry[2] + " (Hologram)" - .(entry_number+1) - -/obj/machinery/holopad/proc/record_stop() - if(record_mode) - record_mode = FALSE - temp = null - record_user = null - updateDialog() - -/obj/machinery/holopad/proc/record_clear() - if(disk && disk.record) - QDEL_NULL(disk.record) - updateDialog() - -/obj/effect/overlay/holo_pad_hologram - var/mob/living/Impersonation - var/datum/holocall/HC - -/obj/effect/overlay/holo_pad_hologram/Destroy() - Impersonation = null - if(!QDELETED(HC)) - HC.Disconnect(HC.calling_holopad) - return ..() - -/obj/effect/overlay/holo_pad_hologram/Process_Spacemove(movement_dir = 0) - return TRUE - -/obj/effect/overlay/holo_pad_hologram/examine(mob/user) - if(Impersonation) - return Impersonation.examine(user) - return ..() - -/obj/effect/overlay/holoray - name = "holoray" - icon = 'icons/effects/96x96.dmi' - icon_state = "holoray" - layer = FLY_LAYER - density = FALSE - anchored = TRUE - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - pixel_x = -32 - pixel_y = -32 - alpha = 100 - -#undef HOLOPAD_PASSIVE_POWER_USAGE -#undef HOLOGRAM_POWER_USAGE +/* Holograms! + * Contains: + * Holopad + * Hologram + * Other stuff + */ + +/* +Revised. Original based on space ninja hologram code. Which is also mine. /N +How it works: +AI clicks on holopad in camera view. View centers on holopad. +AI clicks again on the holopad to display a hologram. Hologram stays as long as AI is looking at the pad and it (the hologram) is in range of the pad. +AI can use the directional keys to move the hologram around, provided the above conditions are met and the AI in question is the holopad's master. +Any number of AIs can use a holopad. /Lo6 +AI may cancel the hologram at any time by clicking on the holopad once more. + +Possible to do for anyone motivated enough: + Give an AI variable for different hologram icons. + Itegrate EMP effect to disable the unit. +*/ + + +/* + * Holopad + */ + +GLOBAL_LIST_EMPTY(network_holopads) + +#define HOLOPAD_PASSIVE_POWER_USAGE 1 +#define HOLOGRAM_POWER_USAGE 2 + +/obj/machinery/holopad + name = "holopad" + desc = "It's a floor-mounted device for projecting holographic images." + icon_state = "holopad0" + layer = LOW_OBJ_LAYER + plane = FLOOR_PLANE + flags_1 = HEAR_1 + use_power = IDLE_POWER_USE + idle_power_usage = 5 + active_power_usage = 100 + max_integrity = 300 + armor = list("melee" = 50, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 0) + circuit = /obj/item/circuitboard/machine/holopad + var/list/masters //List of living mobs that use the holopad + var/list/holorays //Holoray-mob link. + var/last_request = 0 //to prevent request spam. ~Carn + var/holo_range = 5 // Change to change how far the AI can move away from the holopad before deactivating. + var/temp = "" + var/list/holo_calls //array of /datum/holocalls + var/datum/holocall/outgoing_call //do not modify the datums only check and call the public procs + var/obj/item/disk/holodisk/disk //Record disk + var/replay_mode = FALSE //currently replaying a recording + var/loop_mode = FALSE //currently looping a recording + var/record_mode = FALSE //currently recording + var/record_start = 0 //recording start time + var/record_user //user that inititiated the recording + var/obj/effect/overlay/holo_pad_hologram/replay_holo //replay hologram + var/static/force_answer_call = FALSE //Calls will be automatically answered after a couple rings, here for debugging + var/obj/effect/overlay/holoray/ray + var/ringing = FALSE + var/offset = FALSE + var/on_network = TRUE + +/obj/machinery/holopad/tutorial + resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + flags_1 = NODECONSTRUCT_1 + on_network = FALSE + var/proximity_range = 1 + +/obj/machinery/holopad/tutorial/Initialize(mapload) + . = ..() + if(proximity_range) + proximity_monitor = new(src, proximity_range) + if(mapload) + var/obj/item/disk/holodisk/new_disk = locate(/obj/item/disk/holodisk) in src.loc + if(new_disk && !disk) + new_disk.forceMove(src) + disk = new_disk + +/obj/machinery/holopad/tutorial/attack_hand(mob/user) + if(!istype(user)) + return + if(user.incapacitated() || !is_operational()) + return + if(replay_mode) + replay_stop() + else if(disk && disk.record) + replay_start() + +/obj/machinery/holopad/tutorial/HasProximity(atom/movable/AM) + if (!isliving(AM)) + return + if(!replay_mode && (disk && disk.record)) + replay_start() + +/obj/machinery/holopad/Initialize() + . = ..() + if(on_network) + GLOB.network_holopads += src + +/obj/machinery/holopad/Destroy() + if(outgoing_call) + outgoing_call.ConnectionFailure(src) + + for(var/I in holo_calls) + var/datum/holocall/HC = I + HC.ConnectionFailure(src) + + for (var/I in masters) + clear_holo(I) + + if(replay_mode) + replay_stop() + if(record_mode) + record_stop() + + QDEL_NULL(disk) + + GLOB.network_holopads -= src + return ..() + +/obj/machinery/holopad/power_change() + if (powered()) + stat &= ~NOPOWER + else + stat |= NOPOWER + if(replay_mode) + replay_stop() + if(record_mode) + record_stop() + if(outgoing_call) + outgoing_call.ConnectionFailure(src) + +/obj/machinery/holopad/obj_break() + . = ..() + if(outgoing_call) + outgoing_call.ConnectionFailure(src) + +/obj/machinery/holopad/RefreshParts() + var/holograph_range = 4 + for(var/obj/item/stock_parts/capacitor/B in component_parts) + holograph_range += 1 * B.rating + holo_range = holograph_range + +/obj/machinery/holopad/attackby(obj/item/P, mob/user, params) + if(default_deconstruction_screwdriver(user, "holopad_open", "holopad0", P)) + return + + if(default_pry_open(P)) + return + + if(default_unfasten_wrench(user, P)) + return + + if(default_deconstruction_crowbar(P)) + return + + if(istype(P,/obj/item/disk/holodisk)) + if(disk) + to_chat(user,"There's already a disk inside [src]") + return + if (!user.transferItemToLoc(P,src)) + return + to_chat(user,"You insert [P] into [src]") + disk = P + updateDialog() + return + + return ..() + + +/obj/machinery/holopad/ui_interact(mob/living/carbon/human/user) //Carn: Hologram requests. + . = ..() + if(!istype(user)) + return + + if(outgoing_call || user.incapacitated() || !is_operational()) + return + + user.set_machine(src) + var/dat + if(temp) + dat = temp + else + if(on_network) + dat += "Request an AI's presence
      " + dat += "Call another holopad
      " + if(disk) + if(disk.record) + //Replay + dat += "Replay disk recording
      " + dat += "Loop disk recording
      " + //Clear + dat += "Clear disk recording
      " + else + //Record + dat += "Start new recording
      " + //Eject + dat += "Eject disk
      " + + if(LAZYLEN(holo_calls)) + dat += "=====================================================
      " + + if(on_network) + var/one_answered_call = FALSE + var/one_unanswered_call = FALSE + for(var/I in holo_calls) + var/datum/holocall/HC = I + if(HC.connected_holopad != src) + dat += "Answer call from [get_area(HC.calling_holopad)]
      " + one_unanswered_call = TRUE + else + one_answered_call = TRUE + + if(one_answered_call && one_unanswered_call) + dat += "=====================================================
      " + //we loop twice for formatting + for(var/I in holo_calls) + var/datum/holocall/HC = I + if(HC.connected_holopad == src) + dat += "Disconnect call from [HC.user]
      " + + + var/datum/browser/popup = new(user, "holopad", name, 300, 175) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + +//Stop ringing the AI!! +/obj/machinery/holopad/proc/hangup_all_calls() + for(var/I in holo_calls) + var/datum/holocall/HC = I + HC.Disconnect(src) + +/obj/machinery/holopad/Topic(href, href_list) + if(..() || isAI(usr)) + return + add_fingerprint(usr) + if(!is_operational()) + return + if (href_list["AIrequest"]) + if(last_request + 200 < world.time) + last_request = world.time + temp = "You requested an AI's presence.
      " + temp += "Main Menu" + var/area/area = get_area(src) + for(var/mob/living/silicon/ai/AI in GLOB.silicon_mobs) + if(!AI.client) + continue + to_chat(AI, "Your presence is requested at \the [area].") + else + temp = "A request for AI presence was already sent recently.
      " + temp += "Main Menu" + + else if(href_list["Holocall"]) + if(outgoing_call) + return + + temp = "You must stand on the holopad to make a call!
      " + temp += "Main Menu" + if(usr.loc == loc) + var/list/callnames = list() + for(var/I in GLOB.network_holopads) + var/area/A = get_area(I) + if(A) + LAZYADD(callnames[A], I) + callnames -= get_area(src) + + var/result = input(usr, "Choose an area to call", "Holocall") as null|anything in callnames + if(QDELETED(usr) || !result || outgoing_call) + return + + if(usr.loc == loc) + temp = "Dialing...
      " + temp += "Main Menu" + new /datum/holocall(usr, src, callnames[result]) + + else if(href_list["connectcall"]) + var/datum/holocall/call_to_connect = locate(href_list["connectcall"]) + if(!QDELETED(call_to_connect)) + call_to_connect.Answer(src) + temp = "" + + else if(href_list["disconnectcall"]) + var/datum/holocall/call_to_disconnect = locate(href_list["disconnectcall"]) + if(!QDELETED(call_to_disconnect)) + call_to_disconnect.Disconnect(src) + temp = "" + + else if(href_list["mainmenu"]) + temp = "" + if(outgoing_call) + outgoing_call.Disconnect() + + else if(href_list["disk_eject"]) + if(disk && !replay_mode) + disk.forceMove(drop_location()) + disk = null + + else if(href_list["replay_stop"]) + replay_stop() + else if(href_list["replay_start"]) + replay_start() + else if(href_list["loop_start"]) + loop_mode = TRUE + replay_start() + else if(href_list["record_start"]) + record_start(usr) + else if(href_list["record_stop"]) + record_stop() + else if(href_list["record_clear"]) + record_clear() + else if(href_list["offset"]) + offset++ + if (offset > 4) + offset = FALSE + var/turf/new_turf + if (!offset) + new_turf = get_turf(src) + else + new_turf = get_step(src, GLOB.cardinals[offset]) + replay_holo.forceMove(new_turf) + updateDialog() + +//do not allow AIs to answer calls or people will use it to meta the AI sattelite +/obj/machinery/holopad/attack_ai(mob/living/silicon/ai/user) + if (!istype(user)) + return + if (!on_network) + return + /*There are pretty much only three ways to interact here. + I don't need to check for client since they're clicking on an object. + This may change in the future but for now will suffice.*/ + if(user.eyeobj.loc != src.loc)//Set client eye on the object if it's not already. + user.eyeobj.setLoc(get_turf(src)) + else if(!LAZYLEN(masters) || !masters[user])//If there is no hologram, possibly make one. + activate_holo(user) + else//If there is a hologram, remove it. + clear_holo(user) + +/obj/machinery/holopad/process() + if(LAZYLEN(masters)) + for(var/I in masters) + var/mob/living/master = I + var/mob/living/silicon/ai/AI = master + if(!istype(AI)) + AI = null + + if(!is_operational() || !validate_user(master)) + clear_holo(master) + + if(outgoing_call) + outgoing_call.Check() + + ringing = FALSE + + for(var/I in holo_calls) + var/datum/holocall/HC = I + if(HC.connected_holopad != src) + if(force_answer_call && world.time > (HC.call_start_time + (HOLOPAD_MAX_DIAL_TIME / 2))) + HC.Answer(src) + break + if(outgoing_call) + HC.Disconnect(src)//can't answer calls while calling + else + playsound(src, 'sound/machines/twobeep.ogg', 100) //bring, bring! + ringing = TRUE + + update_icon() + +/obj/machinery/holopad/proc/activate_holo(mob/living/user) + var/mob/living/silicon/ai/AI = user + if(!istype(AI)) + AI = null + + if(is_operational() && (!AI || AI.eyeobj.loc == loc))//If the projector has power and client eye is on it + if (AI && istype(AI.current, /obj/machinery/holopad)) + to_chat(user, "ERROR: \black Image feed in progress.") + return + + var/obj/effect/overlay/holo_pad_hologram/Hologram = new(loc)//Spawn a blank effect at the location. + if(AI) + Hologram.icon = AI.holo_icon + else //make it like real life + Hologram.icon = user.icon + Hologram.icon_state = user.icon_state + Hologram.copy_overlays(user, TRUE) + //codersprite some holo effects here + Hologram.alpha = 100 + Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY) + Hologram.Impersonation = user + + Hologram.copy_known_languages_from(user,replace = TRUE) + Hologram.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it. + Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. + Hologram.setAnchored(TRUE)//So space wind cannot drag it. + Hologram.name = "[user.name] (Hologram)"//If someone decides to right click. + Hologram.set_light(2) //hologram lighting + move_hologram() + + set_holo(user, Hologram) + visible_message("A holographic image of [user] flickers to life before your eyes!") + + return Hologram + else + to_chat(user, "ERROR: Unable to project hologram.") + +/*This is the proc for special two-way communication between AI and holopad/people talking near holopad. +For the other part of the code, check silicon say.dm. Particularly robot talk.*/ +/obj/machinery/holopad/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode, atom/movable/source) + . = ..() + if(speaker && LAZYLEN(masters) && !radio_freq)//Master is mostly a safety in case lag hits or something. Radio_freq so AIs dont hear holopad stuff through radios. + for(var/mob/living/silicon/ai/master in masters) + if(masters[master] && speaker != master) + master.relay_speech(message, speaker, message_language, raw_message, radio_freq, spans, message_mode) + + for(var/I in holo_calls) + var/datum/holocall/HC = I + if(HC.connected_holopad == src && speaker != HC.hologram) + HC.user.Hear(message, speaker, message_language, raw_message, radio_freq, spans, message_mode, source) + + if(outgoing_call && speaker == outgoing_call.user) + outgoing_call.hologram.say(raw_message) + + if(record_mode && speaker == record_user) + record_message(speaker,raw_message,message_language) + +/obj/machinery/holopad/proc/SetLightsAndPower() + var/total_users = LAZYLEN(masters) + LAZYLEN(holo_calls) + use_power = total_users > 0 ? ACTIVE_POWER_USE : IDLE_POWER_USE + active_power_usage = HOLOPAD_PASSIVE_POWER_USAGE + (HOLOGRAM_POWER_USAGE * total_users) + if(total_users || replay_mode) + set_light(2) + else + set_light(0) + update_icon() + +/obj/machinery/holopad/update_icon() + var/total_users = LAZYLEN(masters) + LAZYLEN(holo_calls) + if(ringing) + icon_state = "holopad_ringing" + else if(total_users || replay_mode) + icon_state = "holopad1" + else + icon_state = "holopad0" + +/obj/machinery/holopad/proc/set_holo(mob/living/user, var/obj/effect/overlay/holo_pad_hologram/h) + LAZYSET(masters, user, h) + LAZYSET(holorays, user, new /obj/effect/overlay/holoray(loc)) + var/mob/living/silicon/ai/AI = user + if(istype(AI)) + AI.current = src + SetLightsAndPower() + update_holoray(user, get_turf(loc)) + return TRUE + +/obj/machinery/holopad/proc/clear_holo(mob/living/user) + qdel(masters[user]) // Get rid of user's hologram + unset_holo(user) + return TRUE + +/obj/machinery/holopad/proc/unset_holo(mob/living/user) + var/mob/living/silicon/ai/AI = user + if(istype(AI) && AI.current == src) + AI.current = null + LAZYREMOVE(masters, user) // Discard AI from the list of those who use holopad + qdel(holorays[user]) + LAZYREMOVE(holorays, user) + SetLightsAndPower() + return TRUE + +//Try to transfer hologram to another pad that can project on T +/obj/machinery/holopad/proc/transfer_to_nearby_pad(turf/T,mob/holo_owner) + var/obj/effect/overlay/holo_pad_hologram/h = masters[holo_owner] + if(!h || h.HC) //Holocalls can't change source. + return FALSE + for(var/pad in GLOB.network_holopads) + var/obj/machinery/holopad/another = pad + if(another == src) + continue + if(another.validate_location(T)) + unset_holo(holo_owner) + if(another.masters && another.masters[holo_owner]) + another.clear_holo(holo_owner) + another.set_holo(holo_owner, h) + return TRUE + return FALSE + +/obj/machinery/holopad/proc/validate_user(mob/living/user) + if(QDELETED(user) || user.incapacitated() || !user.client) + return FALSE + return TRUE + +//Can we display holos there +//Area check instead of line of sight check because this is a called a lot if AI wants to move around. +/obj/machinery/holopad/proc/validate_location(turf/T,check_los = FALSE) + if(T.z == z && get_dist(T, src) <= holo_range && T.loc == get_area(src)) + return TRUE + else + return FALSE + +/obj/machinery/holopad/proc/move_hologram(mob/living/user, turf/new_turf, direction) + if(LAZYLEN(masters) && masters[user]) + var/obj/effect/overlay/holo_pad_hologram/holo = masters[user] + var/transfered = FALSE + if(!validate_location(new_turf)) + if(!transfer_to_nearby_pad(new_turf,user)) + clear_holo(user) + return FALSE + else + transfered = TRUE + //All is good. + holo.forceMove(new_turf) + if(direction) + holo.setDir(direction) + if(!transfered) + update_holoray(user,new_turf) + return TRUE + + +/obj/machinery/holopad/proc/update_holoray(mob/living/user, turf/new_turf) + var/obj/effect/overlay/holo_pad_hologram/holo = masters[user] + var/obj/effect/overlay/holoray/ray = holorays[user] + var/disty = holo.y - ray.y + var/distx = holo.x - ray.x + var/newangle + if(!disty) + if(distx >= 0) + newangle = 90 + else + newangle = 270 + else + newangle = arctan(distx/disty) + if(disty < 0) + newangle += 180 + else if(distx < 0) + newangle += 360 + var/matrix/M = matrix() + if (get_dist(get_turf(holo),new_turf) <= 1) + animate(ray, transform = turn(M.Scale(1,sqrt(distx*distx+disty*disty)),newangle),time = 1) + else + ray.transform = turn(M.Scale(1,sqrt(distx*distx+disty*disty)),newangle) + +// RECORDED MESSAGES + +/obj/machinery/holopad/proc/setup_replay_holo(datum/holorecord/record) + var/obj/effect/overlay/holo_pad_hologram/Hologram = new(loc)//Spawn a blank effect at the location. + Hologram.add_overlay(record.caller_image) + Hologram.alpha = 170 + Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY) + Hologram.dir = SOUTH //for now + Hologram.grant_all_languages(omnitongue=TRUE) + var/datum/language_holder/holder = Hologram.get_language_holder() + holder.selected_default_language = record.language + Hologram.mouse_opacity = MOUSE_OPACITY_TRANSPARENT//So you can't click on it. + Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. + Hologram.setAnchored(TRUE)//So space wind cannot drag it. + Hologram.name = "[record.caller_name] (Hologram)"//If someone decides to right click. + Hologram.set_light(2) //hologram lighting + visible_message("A holographic image of [record.caller_name] flickers to life before your eyes!") + return Hologram + +/obj/machinery/holopad/proc/replay_start() + if(!replay_mode) + replay_mode = TRUE + replay_holo = setup_replay_holo(disk.record) + temp = "Replaying...
      " + temp += "Change offset
      " + temp += "End replay" + SetLightsAndPower() + replay_entry(1) + return + +/obj/machinery/holopad/proc/replay_stop() + if(replay_mode) + replay_mode = FALSE + loop_mode = FALSE + offset = FALSE + temp = null + QDEL_NULL(replay_holo) + SetLightsAndPower() + updateDialog() + +/obj/machinery/holopad/proc/record_start(mob/living/user) + if(!user || !disk || disk.record) + return + disk.record = new + record_mode = TRUE + record_start = world.time + record_user = user + disk.record.set_caller_image(user) + temp = "Recording...
      " + temp += "End recording." + +/obj/machinery/holopad/proc/record_message(mob/living/speaker,message,language) + if(!record_mode) + return + //make this command so you can have multiple languages in single record + if((!disk.record.caller_name || disk.record.caller_name == "Unknown") && istype(speaker)) + disk.record.caller_name = speaker.name + if(!disk.record.language) + disk.record.language = language + else if(language != disk.record.language) + disk.record.entries += list(list(HOLORECORD_LANGUAGE,language)) + + var/current_delay = 0 + for(var/E in disk.record.entries) + var/list/entry = E + if(entry[1] != HOLORECORD_DELAY) + continue + current_delay += entry[2] + + var/time_delta = world.time - record_start - current_delay + + if(time_delta >= 1) + disk.record.entries += list(list(HOLORECORD_DELAY,time_delta)) + disk.record.entries += list(list(HOLORECORD_SAY,message)) + if(disk.record.entries.len >= HOLORECORD_MAX_LENGTH) + record_stop() + +/obj/machinery/holopad/proc/replay_entry(entry_number) + if(!replay_mode) + return + if (!disk.record.entries.len) // check for zero entries such as photographs and no text recordings + return // and pretty much just display them statically untill manually stopped + if(disk.record.entries.len < entry_number) + if(loop_mode) + entry_number = 1 + else + replay_stop() + return + var/list/entry = disk.record.entries[entry_number] + var/command = entry[1] + switch(command) + if(HOLORECORD_SAY) + var/message = entry[2] + if(replay_holo) + replay_holo.say(message) + if(HOLORECORD_SOUND) + playsound(src,entry[2],50,1) + if(HOLORECORD_DELAY) + addtimer(CALLBACK(src,.proc/replay_entry,entry_number+1),entry[2]) + return + if(HOLORECORD_LANGUAGE) + var/datum/language_holder/holder = replay_holo.get_language_holder() + holder.selected_default_language = entry[2] + if(HOLORECORD_PRESET) + var/preset_type = entry[2] + var/datum/preset_holoimage/H = new preset_type + replay_holo.cut_overlays() + replay_holo.add_overlay(H.build_image()) + if(HOLORECORD_RENAME) + replay_holo.name = entry[2] + " (Hologram)" + .(entry_number+1) + +/obj/machinery/holopad/proc/record_stop() + if(record_mode) + record_mode = FALSE + temp = null + record_user = null + updateDialog() + +/obj/machinery/holopad/proc/record_clear() + if(disk && disk.record) + QDEL_NULL(disk.record) + updateDialog() + +/obj/effect/overlay/holo_pad_hologram + var/mob/living/Impersonation + var/datum/holocall/HC + +/obj/effect/overlay/holo_pad_hologram/Destroy() + Impersonation = null + if(!QDELETED(HC)) + HC.Disconnect(HC.calling_holopad) + return ..() + +/obj/effect/overlay/holo_pad_hologram/Process_Spacemove(movement_dir = 0) + return TRUE + +/obj/effect/overlay/holo_pad_hologram/examine(mob/user) + if(Impersonation) + return Impersonation.examine(user) + return ..() + +/obj/effect/overlay/holoray + name = "holoray" + icon = 'icons/effects/96x96.dmi' + icon_state = "holoray" + layer = FLY_LAYER + density = FALSE + anchored = TRUE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + pixel_x = -32 + pixel_y = -32 + alpha = 100 + +#undef HOLOPAD_PASSIVE_POWER_USAGE +#undef HOLOGRAM_POWER_USAGE diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index acc0505256..099b51db82 100644 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -1,137 +1,137 @@ -/obj/machinery/igniter - name = "igniter" - desc = "It's useful for igniting plasma." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "igniter0" - plane = FLOOR_PLANE - use_power = IDLE_POWER_USE - idle_power_usage = 2 - active_power_usage = 4 - max_integrity = 300 - armor = list("melee" = 50, "bullet" = 30, "laser" = 70, "energy" = 50, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70) - resistance_flags = FIRE_PROOF - var/id = null - var/on = FALSE - -/obj/machinery/igniter/incinerator_toxmix - id = INCINERATOR_TOXMIX_IGNITER - -/obj/machinery/igniter/incinerator_atmos - id = INCINERATOR_ATMOS_IGNITER - -/obj/machinery/igniter/incinerator_syndicatelava - id = INCINERATOR_SYNDICATELAVA_IGNITER - -/obj/machinery/igniter/on - on = TRUE - icon_state = "igniter1" - -/obj/machinery/igniter/attack_hand(mob/user) - . = ..() - if(.) - return - add_fingerprint(user) - - use_power(50) - on = !( on ) - icon_state = "igniter[on]" - -/obj/machinery/igniter/process() //ugh why is this even in process()? - if (src.on && !(stat & NOPOWER) ) - var/turf/location = src.loc - if (isturf(location)) - location.hotspot_expose(700,10,1) - return 1 - -/obj/machinery/igniter/Initialize() - . = ..() - icon_state = "igniter[on]" - -/obj/machinery/igniter/power_change() - if(!( stat & NOPOWER) ) - icon_state = "igniter[src.on]" - else - icon_state = "igniter0" - -// Wall mounted remote-control igniter. - -/obj/machinery/sparker - name = "mounted igniter" - desc = "A wall-mounted ignition device." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "migniter" - resistance_flags = FIRE_PROOF - var/id = null - var/disable = 0 - var/last_spark = 0 - var/base_state = "migniter" - var/datum/effect_system/spark_spread/spark_system - -/obj/machinery/sparker/toxmix - id = INCINERATOR_TOXMIX_IGNITER - -/obj/machinery/sparker/Initialize() - . = ..() - spark_system = new /datum/effect_system/spark_spread - spark_system.set_up(2, 1, src) - spark_system.attach(src) - -/obj/machinery/sparker/Destroy() - QDEL_NULL(spark_system) - return ..() - -/obj/machinery/sparker/power_change() - if ( powered() && disable == 0 ) - stat &= ~NOPOWER - icon_state = "[base_state]" -// src.sd_SetLuminosity(2) - else - stat |= ~NOPOWER - icon_state = "[base_state]-p" -// src.sd_SetLuminosity(0) - -/obj/machinery/sparker/attackby(obj/item/W, mob/user, params) - if (istype(W, /obj/item/screwdriver)) - add_fingerprint(user) - src.disable = !src.disable - if (src.disable) - user.visible_message("[user] has disabled \the [src]!", "You disable the connection to \the [src].") - icon_state = "[base_state]-d" - if (!src.disable) - user.visible_message("[user] has reconnected \the [src]!", "You fix the connection to \the [src].") - if(src.powered()) - icon_state = "[base_state]" - else - icon_state = "[base_state]-p" - else - return ..() - -/obj/machinery/sparker/attack_ai() - if (anchored) - return src.ignite() - else - return - -/obj/machinery/sparker/proc/ignite() - if (!(powered())) - return - - if ((src.disable) || (src.last_spark && world.time < src.last_spark + 50)) - return - - - flick("[base_state]-spark", src) - spark_system.start() - last_spark = world.time - use_power(1000) - var/turf/location = src.loc - if (isturf(location)) - location.hotspot_expose(1000,100,1) - return 1 - -/obj/machinery/sparker/emp_act(severity) - . = ..() - if (. & EMP_PROTECT_SELF) - return - if(!(stat & (BROKEN|NOPOWER))) - ignite() +/obj/machinery/igniter + name = "igniter" + desc = "It's useful for igniting plasma." + icon = 'icons/obj/stationobjs.dmi' + icon_state = "igniter0" + plane = FLOOR_PLANE + use_power = IDLE_POWER_USE + idle_power_usage = 2 + active_power_usage = 4 + max_integrity = 300 + armor = list("melee" = 50, "bullet" = 30, "laser" = 70, "energy" = 50, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 70) + resistance_flags = FIRE_PROOF + var/id = null + var/on = FALSE + +/obj/machinery/igniter/incinerator_toxmix + id = INCINERATOR_TOXMIX_IGNITER + +/obj/machinery/igniter/incinerator_atmos + id = INCINERATOR_ATMOS_IGNITER + +/obj/machinery/igniter/incinerator_syndicatelava + id = INCINERATOR_SYNDICATELAVA_IGNITER + +/obj/machinery/igniter/on + on = TRUE + icon_state = "igniter1" + +/obj/machinery/igniter/attack_hand(mob/user) + . = ..() + if(.) + return + add_fingerprint(user) + + use_power(50) + on = !( on ) + icon_state = "igniter[on]" + +/obj/machinery/igniter/process() //ugh why is this even in process()? + if (src.on && !(stat & NOPOWER) ) + var/turf/location = src.loc + if (isturf(location)) + location.hotspot_expose(700,10,1) + return 1 + +/obj/machinery/igniter/Initialize() + . = ..() + icon_state = "igniter[on]" + +/obj/machinery/igniter/power_change() + if(!( stat & NOPOWER) ) + icon_state = "igniter[src.on]" + else + icon_state = "igniter0" + +// Wall mounted remote-control igniter. + +/obj/machinery/sparker + name = "mounted igniter" + desc = "A wall-mounted ignition device." + icon = 'icons/obj/stationobjs.dmi' + icon_state = "migniter" + resistance_flags = FIRE_PROOF + var/id = null + var/disable = 0 + var/last_spark = 0 + var/base_state = "migniter" + var/datum/effect_system/spark_spread/spark_system + +/obj/machinery/sparker/toxmix + id = INCINERATOR_TOXMIX_IGNITER + +/obj/machinery/sparker/Initialize() + . = ..() + spark_system = new /datum/effect_system/spark_spread + spark_system.set_up(2, 1, src) + spark_system.attach(src) + +/obj/machinery/sparker/Destroy() + QDEL_NULL(spark_system) + return ..() + +/obj/machinery/sparker/power_change() + if ( powered() && disable == 0 ) + stat &= ~NOPOWER + icon_state = "[base_state]" +// src.sd_SetLuminosity(2) + else + stat |= ~NOPOWER + icon_state = "[base_state]-p" +// src.sd_SetLuminosity(0) + +/obj/machinery/sparker/attackby(obj/item/W, mob/user, params) + if (istype(W, /obj/item/screwdriver)) + add_fingerprint(user) + src.disable = !src.disable + if (src.disable) + user.visible_message("[user] has disabled \the [src]!", "You disable the connection to \the [src].") + icon_state = "[base_state]-d" + if (!src.disable) + user.visible_message("[user] has reconnected \the [src]!", "You fix the connection to \the [src].") + if(src.powered()) + icon_state = "[base_state]" + else + icon_state = "[base_state]-p" + else + return ..() + +/obj/machinery/sparker/attack_ai() + if (anchored) + return src.ignite() + else + return + +/obj/machinery/sparker/proc/ignite() + if (!(powered())) + return + + if ((src.disable) || (src.last_spark && world.time < src.last_spark + 50)) + return + + + flick("[base_state]-spark", src) + spark_system.start() + last_spark = world.time + use_power(1000) + var/turf/location = src.loc + if (isturf(location)) + location.hotspot_expose(1000,100,1) + return 1 + +/obj/machinery/sparker/emp_act(severity) + . = ..() + if (. & EMP_PROTECT_SELF) + return + if(!(stat & (BROKEN|NOPOWER))) + ignite() diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index 2a4b903906..e14033a959 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -1,67 +1,67 @@ -// the light switch -// can have multiple per area -// can also operate on non-loc area through "otherarea" var -/obj/machinery/light_switch - name = "light switch" - icon = 'icons/obj/power.dmi' - icon_state = "light1" - desc = "Make dark." - var/on = TRUE - var/area/area = null - var/otherarea = null - -/obj/machinery/light_switch/Initialize() - . = ..() - area = get_area(src) - - if(otherarea) - area = locate(text2path("/area/[otherarea]")) - - if(!name) - name = "light switch ([area.name])" - - on = area.lightswitch - update_icon() - -/obj/machinery/light_switch/update_icon() - if(stat & NOPOWER) - icon_state = "light-p" - else - if(on) - icon_state = "light1" - else - icon_state = "light0" - -/obj/machinery/light_switch/examine(mob/user) - . = ..() - . += "It is [on? "on" : "off"]." - -/obj/machinery/light_switch/interact(mob/user) - . = ..() - on = !on - - area.lightswitch = on - area.update_icon() - - for(var/obj/machinery/light_switch/L in area) - L.on = on - L.update_icon() - - area.power_change() - -/obj/machinery/light_switch/power_change() - - if(!otherarea) - if(powered(LIGHT)) - stat &= ~NOPOWER - else - stat |= NOPOWER - - update_icon() - -/obj/machinery/light_switch/emp_act(severity) - . = ..() - if (. & EMP_PROTECT_SELF) - return - if(!(stat & (BROKEN|NOPOWER))) - power_change() +// the light switch +// can have multiple per area +// can also operate on non-loc area through "otherarea" var +/obj/machinery/light_switch + name = "light switch" + icon = 'icons/obj/power.dmi' + icon_state = "light1" + desc = "Make dark." + var/on = TRUE + var/area/area = null + var/otherarea = null + +/obj/machinery/light_switch/Initialize() + . = ..() + area = get_area(src) + + if(otherarea) + area = locate(text2path("/area/[otherarea]")) + + if(!name) + name = "light switch ([area.name])" + + on = area.lightswitch + update_icon() + +/obj/machinery/light_switch/update_icon() + if(stat & NOPOWER) + icon_state = "light-p" + else + if(on) + icon_state = "light1" + else + icon_state = "light0" + +/obj/machinery/light_switch/examine(mob/user) + . = ..() + . += "It is [on? "on" : "off"]." + +/obj/machinery/light_switch/interact(mob/user) + . = ..() + on = !on + + area.lightswitch = on + area.update_icon() + + for(var/obj/machinery/light_switch/L in area) + L.on = on + L.update_icon() + + area.power_change() + +/obj/machinery/light_switch/power_change() + + if(!otherarea) + if(powered(LIGHT)) + stat &= ~NOPOWER + else + stat |= NOPOWER + + update_icon() + +/obj/machinery/light_switch/emp_act(severity) + . = ..() + if (. & EMP_PROTECT_SELF) + return + if(!(stat & (BROKEN|NOPOWER))) + power_change() diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm index 370621e0c8..9a10ede1ac 100644 --- a/code/game/machinery/magnet.dm +++ b/code/game/machinery/magnet.dm @@ -1,380 +1,380 @@ -// Magnetic attractor, creates variable magnetic fields and attraction. -// Can also be used to emit electron/proton beams to create a center of magnetism on another tile - -// tl;dr: it's magnets lol -// This was created for firing ranges, but I suppose this could have other applications - Doohl - -/obj/machinery/magnetic_module - icon = 'icons/obj/objects.dmi' - icon_state = "floor_magnet-f" - name = "electromagnetic generator" - desc = "A device that uses station power to create points of magnetic energy." - level = 1 // underfloor - layer = LOW_OBJ_LAYER - use_power = IDLE_POWER_USE - idle_power_usage = 50 - - var/freq = FREQ_MAGNETS // radio frequency - var/electricity_level = 1 // intensity of the magnetic pull - var/magnetic_field = 1 // the range of magnetic attraction - var/code = 0 // frequency code, they should be different unless you have a group of magnets working together or something - var/turf/center // the center of magnetic attraction - var/on = FALSE - var/magneting = FALSE - - // x, y modifiers to the center turf; (0, 0) is centered on the magnet, whereas (1, -1) is one tile right, one tile down - var/center_x = 0 - var/center_y = 0 - var/max_dist = 20 // absolute value of center_x,y cannot exceed this integer - -/obj/machinery/magnetic_module/Initialize() - ..() - var/turf/T = loc - hide(T.intact) - center = T - SSradio.add_object(src, freq, RADIO_MAGNETS) - return INITIALIZE_HINT_LATELOAD - -/obj/machinery/magnetic_module/LateInitialize() - magnetic_process() - -/obj/machinery/magnetic_module/Destroy() - SSradio.remove_object(src, freq) - center = null - return ..() - -// update the invisibility and icon -/obj/machinery/magnetic_module/hide(intact) - invisibility = intact ? INVISIBILITY_MAXIMUM : 0 - update_icon() - -// update the icon_state -/obj/machinery/magnetic_module/update_icon() - var/state="floor_magnet" - var/onstate="" - if(!on) - onstate="0" - - if(invisibility) - icon_state = "[state][onstate]-f" // if invisible, set icon to faded version - // in case of being revealed by T-scanner - else - icon_state = "[state][onstate]" - -/obj/machinery/magnetic_module/receive_signal(datum/signal/signal) - - var/command = signal.data["command"] - var/modifier = signal.data["modifier"] - var/signal_code = signal.data["code"] - if(command && (signal_code == code)) - - Cmd(command, modifier) - - - -/obj/machinery/magnetic_module/proc/Cmd(command, modifier) - - if(command) - switch(command) - if("set-electriclevel") - if(modifier) - electricity_level = modifier - if("set-magneticfield") - if(modifier) - magnetic_field = modifier - - if("add-elec") - electricity_level++ - if(electricity_level > 12) - electricity_level = 12 - if("sub-elec") - electricity_level-- - if(electricity_level <= 0) - electricity_level = 1 - if("add-mag") - magnetic_field++ - if(magnetic_field > 4) - magnetic_field = 4 - if("sub-mag") - magnetic_field-- - if(magnetic_field <= 0) - magnetic_field = 1 - - if("set-x") - if(modifier) - center_x = modifier - if("set-y") - if(modifier) - center_y = modifier - - if("N") // NORTH - center_y++ - if("S") // SOUTH - center_y-- - if("E") // EAST - center_x++ - if("W") // WEST - center_x-- - if("C") // CENTER - center_x = 0 - center_y = 0 - if("R") // RANDOM - center_x = rand(-max_dist, max_dist) - center_y = rand(-max_dist, max_dist) - - if("set-code") - if(modifier) - code = modifier - if("toggle-power") - on = !on - - if(on) - INVOKE_ASYNC(src, .proc/magnetic_process) - - - -/obj/machinery/magnetic_module/process() - if(stat & NOPOWER) - on = FALSE - - // Sanity checks: - if(electricity_level <= 0) - electricity_level = 1 - if(magnetic_field <= 0) - magnetic_field = 1 - - - // Limitations: - if(abs(center_x) > max_dist) - center_x = max_dist - if(abs(center_y) > max_dist) - center_y = max_dist - if(magnetic_field > 4) - magnetic_field = 4 - if(electricity_level > 12) - electricity_level = 12 - - // Update power usage: - if(on) - use_power = ACTIVE_POWER_USE - active_power_usage = electricity_level*15 - else - use_power = NO_POWER_USE - - update_icon() - - -/obj/machinery/magnetic_module/proc/magnetic_process() // proc that actually does the magneting - if(magneting) - return - while(on) - - magneting = TRUE - center = locate(x+center_x, y+center_y, z) - if(center) - for(var/obj/M in orange(magnetic_field, center)) - if(!M.anchored && (M.flags_1 & CONDUCT_1)) - step_towards(M, center) - - for(var/mob/living/silicon/S in orange(magnetic_field, center)) - if(isAI(S)) - continue - step_towards(S, center) - - use_power(electricity_level * 5) - sleep(13 - electricity_level) - - magneting = FALSE - - - - -/obj/machinery/magnetic_controller - name = "magnetic control console" - icon = 'icons/obj/airlock_machines.dmi' // uses an airlock machine icon, THINK GREEN HELP THE ENVIRONMENT - RECYCLING! - icon_state = "airlock_control_standby" - density = FALSE - use_power = IDLE_POWER_USE - idle_power_usage = 45 - var/frequency = FREQ_MAGNETS - var/code = 0 - var/list/magnets = list() - var/title = "Magnetic Control Console" - var/autolink = 0 // if set to 1, can't probe for other magnets! - - var/pathpos = 1 // position in the path - var/path = "w;e;e;w;s;n;n;s" // text path of the magnet - var/speed = 1 // lowest = 1, highest = 10 - var/list/rpath = list() // real path of the magnet, used in iterator - - var/moving = 0 // 1 if scheduled to loop - var/looping = 0 // 1 if looping - - var/datum/radio_frequency/radio_connection - - -/obj/machinery/magnetic_controller/Initialize() - . = ..() - if(autolink) - for(var/obj/machinery/magnetic_module/M in GLOB.machines) - if(M.freq == frequency && M.code == code) - magnets.Add(M) - - if(path) // check for default path - filter_path() // renders rpath - radio_connection = SSradio.add_object(src, frequency, RADIO_MAGNETS) - -/obj/machinery/magnetic_controller/Destroy() - SSradio.remove_object(src, frequency) - magnets = null - rpath = null - return ..() - -/obj/machinery/magnetic_controller/process() - if(magnets.len == 0 && autolink) - for(var/obj/machinery/magnetic_module/M in GLOB.machines) - if(M.freq == frequency && M.code == code) - magnets.Add(M) - -/obj/machinery/magnetic_controller/ui_interact(mob/user) - . = ..() - var/dat = "Magnetic Control Console

      " - if(!autolink) - dat += {" - Frequency: [frequency]
      - Code: [code]
      - Probe Generators
      - "} - - if(magnets.len >= 1) - - dat += "Magnets confirmed:
      " - var/i = 0 - for(var/obj/machinery/magnetic_module/M in magnets) - i++ - dat += "     < \[[i]\] ([M.on ? "On":"Off"]) | Electricity level: - [M.electricity_level] +; Magnetic field: - [M.magnetic_field] +
      " - - dat += "
      Speed: - [speed] +
      " - dat += "Path: {[path]}
      " - dat += "Moving: [moving ? "Enabled":"Disabled"]" - - - user << browse(dat, "window=magnet;size=400x500") - onclose(user, "magnet") - -/obj/machinery/magnetic_controller/Topic(href, href_list) - if(..()) - return - usr.set_machine(src) - - if(href_list["radio-op"]) - - // Prepare signal beforehand, because this is a radio operation - var/datum/signal/signal = new(list("code" = code)) - - // Apply any necessary commands - switch(href_list["radio-op"]) - if("togglepower") - signal.data["command"] = "toggle-power" - - if("minuselec") - signal.data["command"] = "sub-elec" - if("pluselec") - signal.data["command"] = "add-elec" - - if("minusmag") - signal.data["command"] = "sub-mag" - if("plusmag") - signal.data["command"] = "add-mag" - - - // Broadcast the signal - - radio_connection.post_signal(src, signal, filter = RADIO_MAGNETS) - - spawn(1) - updateUsrDialog() // pretty sure this increases responsiveness - - if(href_list["operation"]) - switch(href_list["operation"]) - if("plusspeed") - speed ++ - if(speed > 10) - speed = 10 - if("minusspeed") - speed -- - if(speed <= 0) - speed = 1 - if("setpath") - var/newpath = copytext(sanitize(input(usr, "Please define a new path!",,path) as text|null),1,MAX_MESSAGE_LEN) - if(newpath && newpath != "") - moving = 0 // stop moving - path = newpath - pathpos = 1 // reset position - filter_path() // renders rpath - - if("togglemoving") - moving = !moving - if(moving) - spawn() MagnetMove() - - - updateUsrDialog() - -/obj/machinery/magnetic_controller/proc/MagnetMove() - if(looping) - return - - while(moving && rpath.len >= 1) - - if(stat & (BROKEN|NOPOWER)) - break - - looping = 1 - - // Prepare the radio signal - var/datum/signal/signal = new(list("code" = code)) - - if(pathpos > rpath.len) // if the position is greater than the length, we just loop through the list! - pathpos = 1 - - var/nextmove = uppertext(rpath[pathpos]) // makes it un-case-sensitive - - if(!(nextmove in list("N","S","E","W","C","R"))) - // N, S, E, W are directional - // C is center - // R is random (in magnetic field's bounds) - qdel(signal) - break // break the loop if the character located is invalid - - signal.data["command"] = nextmove - - - pathpos++ // increase iterator - - // Broadcast the signal - spawn() - radio_connection.post_signal(src, signal, filter = RADIO_MAGNETS) - - if(speed == 10) - sleep(1) - else - sleep(12-speed) - - looping = 0 - - -/obj/machinery/magnetic_controller/proc/filter_path() - // Generates the rpath variable using the path string, think of this as "string2list" - // Doesn't use params2list() because of the akward way it stacks entities - rpath = list() // clear rpath - var/maximum_character = min( 50, length(path) ) // chooses the maximum length of the iterator. 50 max length - - for(var/i=1, i<=maximum_character, i++) // iterates through all characters in path - - var/nextchar = copytext(path, i, i+1) // find next character - - if(!(nextchar in list(";", "&", "*", " "))) // if char is a separator, ignore - rpath += copytext(path, i, i+1) // else, add to list - - // there doesn't HAVE to be separators but it makes paths syntatically visible +// Magnetic attractor, creates variable magnetic fields and attraction. +// Can also be used to emit electron/proton beams to create a center of magnetism on another tile + +// tl;dr: it's magnets lol +// This was created for firing ranges, but I suppose this could have other applications - Doohl + +/obj/machinery/magnetic_module + icon = 'icons/obj/objects.dmi' + icon_state = "floor_magnet-f" + name = "electromagnetic generator" + desc = "A device that uses station power to create points of magnetic energy." + level = 1 // underfloor + layer = LOW_OBJ_LAYER + use_power = IDLE_POWER_USE + idle_power_usage = 50 + + var/freq = FREQ_MAGNETS // radio frequency + var/electricity_level = 1 // intensity of the magnetic pull + var/magnetic_field = 1 // the range of magnetic attraction + var/code = 0 // frequency code, they should be different unless you have a group of magnets working together or something + var/turf/center // the center of magnetic attraction + var/on = FALSE + var/magneting = FALSE + + // x, y modifiers to the center turf; (0, 0) is centered on the magnet, whereas (1, -1) is one tile right, one tile down + var/center_x = 0 + var/center_y = 0 + var/max_dist = 20 // absolute value of center_x,y cannot exceed this integer + +/obj/machinery/magnetic_module/Initialize() + ..() + var/turf/T = loc + hide(T.intact) + center = T + SSradio.add_object(src, freq, RADIO_MAGNETS) + return INITIALIZE_HINT_LATELOAD + +/obj/machinery/magnetic_module/LateInitialize() + magnetic_process() + +/obj/machinery/magnetic_module/Destroy() + SSradio.remove_object(src, freq) + center = null + return ..() + +// update the invisibility and icon +/obj/machinery/magnetic_module/hide(intact) + invisibility = intact ? INVISIBILITY_MAXIMUM : 0 + update_icon() + +// update the icon_state +/obj/machinery/magnetic_module/update_icon() + var/state="floor_magnet" + var/onstate="" + if(!on) + onstate="0" + + if(invisibility) + icon_state = "[state][onstate]-f" // if invisible, set icon to faded version + // in case of being revealed by T-scanner + else + icon_state = "[state][onstate]" + +/obj/machinery/magnetic_module/receive_signal(datum/signal/signal) + + var/command = signal.data["command"] + var/modifier = signal.data["modifier"] + var/signal_code = signal.data["code"] + if(command && (signal_code == code)) + + Cmd(command, modifier) + + + +/obj/machinery/magnetic_module/proc/Cmd(command, modifier) + + if(command) + switch(command) + if("set-electriclevel") + if(modifier) + electricity_level = modifier + if("set-magneticfield") + if(modifier) + magnetic_field = modifier + + if("add-elec") + electricity_level++ + if(electricity_level > 12) + electricity_level = 12 + if("sub-elec") + electricity_level-- + if(electricity_level <= 0) + electricity_level = 1 + if("add-mag") + magnetic_field++ + if(magnetic_field > 4) + magnetic_field = 4 + if("sub-mag") + magnetic_field-- + if(magnetic_field <= 0) + magnetic_field = 1 + + if("set-x") + if(modifier) + center_x = modifier + if("set-y") + if(modifier) + center_y = modifier + + if("N") // NORTH + center_y++ + if("S") // SOUTH + center_y-- + if("E") // EAST + center_x++ + if("W") // WEST + center_x-- + if("C") // CENTER + center_x = 0 + center_y = 0 + if("R") // RANDOM + center_x = rand(-max_dist, max_dist) + center_y = rand(-max_dist, max_dist) + + if("set-code") + if(modifier) + code = modifier + if("toggle-power") + on = !on + + if(on) + INVOKE_ASYNC(src, .proc/magnetic_process) + + + +/obj/machinery/magnetic_module/process() + if(stat & NOPOWER) + on = FALSE + + // Sanity checks: + if(electricity_level <= 0) + electricity_level = 1 + if(magnetic_field <= 0) + magnetic_field = 1 + + + // Limitations: + if(abs(center_x) > max_dist) + center_x = max_dist + if(abs(center_y) > max_dist) + center_y = max_dist + if(magnetic_field > 4) + magnetic_field = 4 + if(electricity_level > 12) + electricity_level = 12 + + // Update power usage: + if(on) + use_power = ACTIVE_POWER_USE + active_power_usage = electricity_level*15 + else + use_power = NO_POWER_USE + + update_icon() + + +/obj/machinery/magnetic_module/proc/magnetic_process() // proc that actually does the magneting + if(magneting) + return + while(on) + + magneting = TRUE + center = locate(x+center_x, y+center_y, z) + if(center) + for(var/obj/M in orange(magnetic_field, center)) + if(!M.anchored && (M.flags_1 & CONDUCT_1)) + step_towards(M, center) + + for(var/mob/living/silicon/S in orange(magnetic_field, center)) + if(isAI(S)) + continue + step_towards(S, center) + + use_power(electricity_level * 5) + sleep(13 - electricity_level) + + magneting = FALSE + + + + +/obj/machinery/magnetic_controller + name = "magnetic control console" + icon = 'icons/obj/airlock_machines.dmi' // uses an airlock machine icon, THINK GREEN HELP THE ENVIRONMENT - RECYCLING! + icon_state = "airlock_control_standby" + density = FALSE + use_power = IDLE_POWER_USE + idle_power_usage = 45 + var/frequency = FREQ_MAGNETS + var/code = 0 + var/list/magnets = list() + var/title = "Magnetic Control Console" + var/autolink = 0 // if set to 1, can't probe for other magnets! + + var/pathpos = 1 // position in the path + var/path = "w;e;e;w;s;n;n;s" // text path of the magnet + var/speed = 1 // lowest = 1, highest = 10 + var/list/rpath = list() // real path of the magnet, used in iterator + + var/moving = 0 // 1 if scheduled to loop + var/looping = 0 // 1 if looping + + var/datum/radio_frequency/radio_connection + + +/obj/machinery/magnetic_controller/Initialize() + . = ..() + if(autolink) + for(var/obj/machinery/magnetic_module/M in GLOB.machines) + if(M.freq == frequency && M.code == code) + magnets.Add(M) + + if(path) // check for default path + filter_path() // renders rpath + radio_connection = SSradio.add_object(src, frequency, RADIO_MAGNETS) + +/obj/machinery/magnetic_controller/Destroy() + SSradio.remove_object(src, frequency) + magnets = null + rpath = null + return ..() + +/obj/machinery/magnetic_controller/process() + if(magnets.len == 0 && autolink) + for(var/obj/machinery/magnetic_module/M in GLOB.machines) + if(M.freq == frequency && M.code == code) + magnets.Add(M) + +/obj/machinery/magnetic_controller/ui_interact(mob/user) + . = ..() + var/dat = "Magnetic Control Console

      " + if(!autolink) + dat += {" + Frequency: [frequency]
      + Code: [code]
      + Probe Generators
      + "} + + if(magnets.len >= 1) + + dat += "Magnets confirmed:
      " + var/i = 0 + for(var/obj/machinery/magnetic_module/M in magnets) + i++ + dat += "     < \[[i]\] ([M.on ? "On":"Off"]) | Electricity level: - [M.electricity_level] +; Magnetic field: - [M.magnetic_field] +
      " + + dat += "
      Speed: - [speed] +
      " + dat += "Path: {[path]}
      " + dat += "Moving: [moving ? "Enabled":"Disabled"]" + + + user << browse(dat, "window=magnet;size=400x500") + onclose(user, "magnet") + +/obj/machinery/magnetic_controller/Topic(href, href_list) + if(..()) + return + usr.set_machine(src) + + if(href_list["radio-op"]) + + // Prepare signal beforehand, because this is a radio operation + var/datum/signal/signal = new(list("code" = code)) + + // Apply any necessary commands + switch(href_list["radio-op"]) + if("togglepower") + signal.data["command"] = "toggle-power" + + if("minuselec") + signal.data["command"] = "sub-elec" + if("pluselec") + signal.data["command"] = "add-elec" + + if("minusmag") + signal.data["command"] = "sub-mag" + if("plusmag") + signal.data["command"] = "add-mag" + + + // Broadcast the signal + + radio_connection.post_signal(src, signal, filter = RADIO_MAGNETS) + + spawn(1) + updateUsrDialog() // pretty sure this increases responsiveness + + if(href_list["operation"]) + switch(href_list["operation"]) + if("plusspeed") + speed ++ + if(speed > 10) + speed = 10 + if("minusspeed") + speed -- + if(speed <= 0) + speed = 1 + if("setpath") + var/newpath = copytext(sanitize(input(usr, "Please define a new path!",,path) as text|null),1,MAX_MESSAGE_LEN) + if(newpath && newpath != "") + moving = 0 // stop moving + path = newpath + pathpos = 1 // reset position + filter_path() // renders rpath + + if("togglemoving") + moving = !moving + if(moving) + spawn() MagnetMove() + + + updateUsrDialog() + +/obj/machinery/magnetic_controller/proc/MagnetMove() + if(looping) + return + + while(moving && rpath.len >= 1) + + if(stat & (BROKEN|NOPOWER)) + break + + looping = 1 + + // Prepare the radio signal + var/datum/signal/signal = new(list("code" = code)) + + if(pathpos > rpath.len) // if the position is greater than the length, we just loop through the list! + pathpos = 1 + + var/nextmove = uppertext(rpath[pathpos]) // makes it un-case-sensitive + + if(!(nextmove in list("N","S","E","W","C","R"))) + // N, S, E, W are directional + // C is center + // R is random (in magnetic field's bounds) + qdel(signal) + break // break the loop if the character located is invalid + + signal.data["command"] = nextmove + + + pathpos++ // increase iterator + + // Broadcast the signal + spawn() + radio_connection.post_signal(src, signal, filter = RADIO_MAGNETS) + + if(speed == 10) + sleep(1) + else + sleep(12-speed) + + looping = 0 + + +/obj/machinery/magnetic_controller/proc/filter_path() + // Generates the rpath variable using the path string, think of this as "string2list" + // Doesn't use params2list() because of the akward way it stacks entities + rpath = list() // clear rpath + var/maximum_character = min( 50, length(path) ) // chooses the maximum length of the iterator. 50 max length + + for(var/i=1, i<=maximum_character, i++) // iterates through all characters in path + + var/nextchar = copytext(path, i, i+1) // find next character + + if(!(nextchar in list(";", "&", "*", " "))) // if char is a separator, ignore + rpath += copytext(path, i, i+1) // else, add to list + + // there doesn't HAVE to be separators but it makes paths syntatically visible diff --git a/code/game/machinery/mass_driver.dm b/code/game/machinery/mass_driver.dm index 7ebed0ab0c..ab0a0534ab 100644 --- a/code/game/machinery/mass_driver.dm +++ b/code/game/machinery/mass_driver.dm @@ -1,38 +1,38 @@ -/obj/machinery/mass_driver - name = "mass driver" - desc = "The finest in spring-loaded piston toy technology, now on a space station near you." - icon = 'icons/obj/stationobjs.dmi' - icon_state = "mass_driver" - use_power = IDLE_POWER_USE - idle_power_usage = 2 - active_power_usage = 50 - var/power = 1 - var/code = 1 - var/id = 1 - var/drive_range = 50 //this is mostly irrelevant since current mass drivers throw into space, but you could make a lower-range mass driver for interstation transport or something I guess. - - -/obj/machinery/mass_driver/proc/drive(amount) - if(stat & (BROKEN|NOPOWER)) - return - use_power(500) - var/O_limit - var/atom/target = get_edge_target_turf(src, dir) - for(var/atom/movable/O in loc) - if(!O.anchored || ismecha(O)) //Mechs need their launch platforms. - O_limit++ - if(O_limit >= 20) - audible_message("[src] lets out a screech, it doesn't seem to be able to handle the load.") - break - use_power(500) - O.throw_at(target, drive_range * power, power) - flick("mass_driver1", src) - - -/obj/machinery/mass_driver/emp_act(severity) - . = ..() - if (. & EMP_PROTECT_SELF) - return - if(stat & (BROKEN|NOPOWER)) - return - drive() +/obj/machinery/mass_driver + name = "mass driver" + desc = "The finest in spring-loaded piston toy technology, now on a space station near you." + icon = 'icons/obj/stationobjs.dmi' + icon_state = "mass_driver" + use_power = IDLE_POWER_USE + idle_power_usage = 2 + active_power_usage = 50 + var/power = 1 + var/code = 1 + var/id = 1 + var/drive_range = 50 //this is mostly irrelevant since current mass drivers throw into space, but you could make a lower-range mass driver for interstation transport or something I guess. + + +/obj/machinery/mass_driver/proc/drive(amount) + if(stat & (BROKEN|NOPOWER)) + return + use_power(500) + var/O_limit + var/atom/target = get_edge_target_turf(src, dir) + for(var/atom/movable/O in loc) + if(!O.anchored || ismecha(O)) //Mechs need their launch platforms. + O_limit++ + if(O_limit >= 20) + audible_message("[src] lets out a screech, it doesn't seem to be able to handle the load.") + break + use_power(500) + O.throw_at(target, drive_range * power, power) + flick("mass_driver1", src) + + +/obj/machinery/mass_driver/emp_act(severity) + . = ..() + if (. & EMP_PROTECT_SELF) + return + if(stat & (BROKEN|NOPOWER)) + return + drive() diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index 0f57bea656..5a567886b8 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -1,214 +1,214 @@ -// Navigation beacon for AI robots -// No longer exists on the radio controller, it is managed by a global list. - -/obj/machinery/navbeacon - - icon = 'icons/obj/objects.dmi' - icon_state = "navbeacon0-f" - name = "navigation beacon" - desc = "A radio beacon used for bot navigation." - level = 1 // underfloor - layer = LOW_OBJ_LAYER - max_integrity = 500 - armor = list("melee" = 70, "bullet" = 70, "laser" = 70, "energy" = 70, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 80) - - var/open = FALSE // true if cover is open - var/locked = TRUE // true if controls are locked - var/freq = FREQ_NAV_BEACON - var/location = "" // location response text - var/list/codes // assoc. list of transponder codes - var/codes_txt = "" // codes as set on map: "tag1;tag2" or "tag1=value;tag2=value" - - req_one_access = list(ACCESS_ENGINE, ACCESS_ROBOTICS) - -/obj/machinery/navbeacon/Initialize() - . = ..() - - set_codes() - - var/turf/T = loc - hide(T.intact) - if(codes["patrol"]) - if(!GLOB.navbeacons["[z]"]) - GLOB.navbeacons["[z]"] = list() - GLOB.navbeacons["[z]"] += src //Register with the patrol list! - if(codes["delivery"]) - GLOB.deliverybeacons += src - GLOB.deliverybeacontags += location - -/obj/machinery/navbeacon/Destroy() - if (GLOB.navbeacons["[z]"]) - GLOB.navbeacons["[z]"] -= src //Remove from beacon list, if in one. - GLOB.deliverybeacons -= src - return ..() - -/obj/machinery/navbeacon/onTransitZ(old_z, new_z) - if (GLOB.navbeacons["[old_z]"]) - GLOB.navbeacons["[old_z]"] -= src - if (GLOB.navbeacons["[new_z]"]) - GLOB.navbeacons["[new_z]"] += src - ..() - -// set the transponder codes assoc list from codes_txt -/obj/machinery/navbeacon/proc/set_codes() - if(!codes_txt) - return - - codes = new() - - var/list/entries = splittext(codes_txt, ";") // entries are separated by semicolons - - for(var/e in entries) - var/index = findtext(e, "=") // format is "key=value" - if(index) - var/key = copytext(e, 1, index) - var/val = copytext(e, index+1) - codes[key] = val - else - codes[e] = "1" - - -// called when turf state changes -// hide the object if turf is intact -/obj/machinery/navbeacon/hide(intact) - invisibility = intact ? INVISIBILITY_MAXIMUM : 0 - update_icon() - -// update the icon_state -/obj/machinery/navbeacon/update_icon() - var/state="navbeacon[open]" - - if(invisibility) - icon_state = "[state]-f" // if invisible, set icon to faded version - // in case revealed by T-scanner - else - icon_state = "[state]" - -/obj/machinery/navbeacon/attackby(obj/item/I, mob/user, params) - var/turf/T = loc - if(T.intact) - return // prevent intraction when T-scanner revealed - - if(istype(I, /obj/item/screwdriver)) - open = !open - - user.visible_message("[user] [open ? "opens" : "closes"] the beacon's cover.", "You [open ? "open" : "close"] the beacon's cover.") - - update_icon() - - else if (istype(I, /obj/item/card/id)||istype(I, /obj/item/pda)) - if(open) - if (src.allowed(user)) - src.locked = !src.locked - to_chat(user, "Controls are now [src.locked ? "locked" : "unlocked"].") - else - to_chat(user, "Access denied.") - updateDialog() - else - to_chat(user, "You must open the cover first!") - else - return ..() - -/obj/machinery/navbeacon/attack_ai(mob/user) - interact(user, 1) - -/obj/machinery/navbeacon/attack_paw() - return - -/obj/machinery/navbeacon/ui_interact(mob/user) - . = ..() - var/ai = isAI(user) - var/turf/T = loc - if(T.intact) - return // prevent intraction when T-scanner revealed - - if(!open && !ai) // can't alter controls if not open, unless you're an AI - to_chat(user, "The beacon's control cover is closed!") - return - - - var/t - - if(locked && !ai) - t = {"Navigation Beacon

      -(swipe card to unlock controls)
      -Location: [location ? location : "(none)"]
      -Transponder Codes: