From 368ea6477091a6ec8d27a420a86a845f11c65b12 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 6 Jun 2025 17:29:18 -0400 Subject: [PATCH 01/36] Add a basic modpack system readme --- mods/README.md | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 mods/README.md diff --git a/mods/README.md b/mods/README.md new file mode 100644 index 000000000000..3ad3e5f818b8 --- /dev/null +++ b/mods/README.md @@ -0,0 +1,56 @@ +# Modpacks + +## What exactly are modpacks? + +Modpacks are, effectively, self-contained (modular) feature bundles. They can contain new objects, new species, new UIs, overrides for existing code, and even more. If you want a feature to be optional on a per-map or per-server basis, while ensuring it's always checked for correctness in unit tests, it should be placed in a modpack. + +## Wait, but I've heard that modular code is bad! + +This is a common sentiment, but it's sort of a misconception. There's nothing *inherently* wrong with modular code; after all, it's just code that'd designed for easy extension and reusability, which is always desirable in a project like SS13. However, the way other codebases tend to handle modularity by just adding new DM files in a separate folder, directly included in the DME, creates issues. Some of the common objections are: + +### Load Order + +With the typical way "modular" code is done, load order is difficult to manage and often results in folder names like `upstreamname`, `downstreamname`, `zzzz_servername`, etc., plus it requires editing the main DME. Modpacks have a defined, user-controlled load order, and cross-modpack compatibility is always handled after all modpacks are loaded. + +### Organization and Navigation + +Similarly, that file-structure makes it very difficult to organize and navigate the codebase as a whole. The original modularization standards were fairly straightforward, in that the modular folder was treated as a straight-forward layer on top of the original codebase, with files being treated as though they're present in the original codebase structure. a trend that ended up being set by other servers going for modularization was adding subdirectories of "modules", with almost every unique piece of content being given it's own individual module folder. The problem with this is that modules don't really have any defined structure or handling, and tend to just amount to subdirectories and nothing more. With every piece of content having its own module, even if they just override or overwrite base-game definitions and nothing more, this leads to the codebase being incredibly hard to navigate even if you already know roughly where what you want to modify is. This even applies to the base game, because some code is separated by type (obj, datum, etc.) and others are separated into conceptual modules. + +Nebula's modpacks are similar to modules in that they're separated by concept, but modpacks are more rigorous, with scripts and tests for validation. Each modpack is tested as a unit (along with the base game) as well as in integration with other modpacks on the various included maps. + +### Proc Overrides + +Modular code relies heavily on overrides and even side-overrides (overrides defined after, but on the same type as, an existing proc override or definition), which can obfuscate control flow and lead to code breaking when assumptions made about the calling proc change. This is a valid concern! In a lot of cases, though, it's avoidable by making modular behaviour use explicit interfaces intended for change in modpacks, like specifying datum (often decl) handlers that receive one override each. `/decl/human_examination` is a good example of this. + +### Merge Conflicts + +The issue with "modularity" as done elsewhere is that it just masks conflicts; upstream files are kept intact, but they might be unincluded or the methods they define/call might be completely replaced later on. This swaps out annoying but easily-resolvable merge conflicts for the far-worse issue of silent breakage. + +### Upstream Conflicts + +More broadly, modular code on a downstream with an upstream that does frequent refactors and rewrites is inevitably going to break when the upstream codebase does anything. Names change, so do assumptions, and even design directions might diverge so far that reconciling them will be hard or even impossible. There's not really getting around that, but we can at least mitigate it by designing stable interfaces and documenting changes. When upstream code is written with modularity in mind, downstreams have a much easier time adding content. + +### Implicit Dependencies + +The idea of modular code as independent falls apart when code modules begin to require each other to function, without explicitly noting that dependency. Worse yet, sometimes there are non-modular edits to base-game code that require a particular piece of modular code to be included. Since Nebula runs unit tests on an example map with no modpacks and no map-specific code, the core game will always function without any modpacks included. Similarly, modpacks are tested one-at-a-time as well as all together, to ensure there aren't any implicit dependencies. If one modpack requires another to function, there's three methods to resolve this. First, you could have one modpack include the other, making the dependency explicit. Second, you could merge the modpacks so they aren't separate at all. Third, you could use a compatibility patch to gate the content that requires both to be loaded. + +## Okay, but how do I make a modpack? + +TODO: Write this section. Explain things like creating a DME, where to include the DME, etc. Also explain some common organizational conventions like `foo_overrides.dm` files and `overrides` folders to better organize overrides of base-game procs and functionality. + +### How do I modpack... + +- A subsystem? + - Check the psionics modpack for an example. +- Something small? + - Check the mundane or scaling descriptor modpacks as examples. +- NanoUI templates? + - Check the inertial dampener or supermatter modpacks as examples. (Don't forget to set the nanoui_directory variable on the modpack decl!) + +## How do I write upstream/core code with extension via modpacks in mind? + +TODO: Write this section. Give examples like `/decl/atmos_grief_fix_step`, `/decl/human_examination`, the cocktails system, etc. Iterating over subtypes of a base type makes it easy for modpacks to add new code. Also maybe address some footguns like trying to make something modular before trying to make it actually work? Could also discuss the open-closed principle I guess, e.g. write code that gets *extended* rather than *modified* (so avoiding side-overrides, etc.). + +# Contribution + +Please contribute to this README/guide. It's currently unfinished and doesn't cover a lot of important things. Thanks. \ No newline at end of file From 0bf2b9f7ebbd6cbe8bfde9fb5e9f7454c9db1c3f Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 9 Sep 2025 16:09:37 -0400 Subject: [PATCH 02/36] Attempt to fix and debug random away-site unit test failures --- .../_machines_base/machine_construction/_construction.dm | 4 ++++ .../machinery/_machines_base/machine_construction/airlock.dm | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/code/game/machinery/_machines_base/machine_construction/_construction.dm b/code/game/machinery/_machines_base/machine_construction/_construction.dm index 8ae207901bbc..3555ee7173f1 100644 --- a/code/game/machinery/_machines_base/machine_construction/_construction.dm +++ b/code/game/machinery/_machines_base/machine_construction/_construction.dm @@ -76,6 +76,10 @@ return MCS_CHANGE if(istext(fail)) to_chat(user, fail) + // This logging exists so that random CI fails due to state change failures will be caught. + #ifdef UNIT_TEST + log_unit_test("[log_info_line(machine)]: [fail]") + #endif return MCS_BLOCK return fail return MCS_CONTINUE diff --git a/code/game/machinery/_machines_base/machine_construction/airlock.dm b/code/game/machinery/_machines_base/machine_construction/airlock.dm index 48de7420a1b7..c6a8a4fa6f15 100644 --- a/code/game/machinery/_machines_base/machine_construction/airlock.dm +++ b/code/game/machinery/_machines_base/machine_construction/airlock.dm @@ -8,6 +8,10 @@ // Prevent access locks on doors from interfering with our interactions. for(var/obj/item/stock_parts/access_lock/lock in machine.get_all_components_of_type(/obj/item/stock_parts/access_lock)) lock.locked = FALSE + // And ensure the door's closed + var/obj/machinery/door/the_door = machine + if(istype(the_door)) // just in case + the_door.operating = FALSE // A lot of doors refuse to change states if operating. // Test hacking state if(!machine.attackby(screwdriver, user)) return "Machine [log_info_line(machine)] did not respond to attackby with screwdriver." From 638ddea534167fcf10598dedc73162d540a6ec81 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 23 Sep 2025 02:13:20 -0400 Subject: [PATCH 03/36] Fix missing populate_branches call --- code/game/world.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/world.dm b/code/game/world.dm index 1c65910d510c..266e234d0a1b 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -101,6 +101,7 @@ GLOBAL_PROTECTED_UNTYPED(game_id, null) update_holiday() //Uncommenting ALLOW_HOLIDAYS in configuration will enable this. try_load_alien_whitelist() investigate_reset() + global.using_map.populate_branches() // Precache/build trait trees. for(var/decl/trait/trait in decls_repository.get_decls_of_type_unassociated(/decl/trait)) trait.build_references() From 0b4703c019a62a52d4484a664fbab07d3da44ab6 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 23 Sep 2025 14:12:33 -0400 Subject: [PATCH 04/36] Simplify some code via `drop_from_slot()` --- code/modules/mob/living/inventory.dm | 2 +- code/modules/organs/external/_external.dm | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/code/modules/mob/living/inventory.dm b/code/modules/mob/living/inventory.dm index 21b92392fbdd..4d3d35090dc6 100644 --- a/code/modules/mob/living/inventory.dm +++ b/code/modules/mob/living/inventory.dm @@ -153,8 +153,8 @@ // For any old slots which had no equivalent, drop the item into the world for(var/old_slot_id in old_slots) + drop_from_slot(old_slot_id) var/datum/inventory_slot/old_slot = old_slots[old_slot_id] - drop_from_inventory(old_slot.get_equipped_item()) old_slot.clear_slot() // Call this manually since it is no longer in _inventory_slots qdel(old_slot) diff --git a/code/modules/organs/external/_external.dm b/code/modules/organs/external/_external.dm index 3f62d4a17485..4cafbfe2e108 100644 --- a/code/modules/organs/external/_external.dm +++ b/code/modules/organs/external/_external.dm @@ -527,19 +527,21 @@ if(!in_place) parent.update_wounds() +/// Drops all clothing covered by this body part. /obj/item/organ/external/proc/drop_equipped_clothing() if(!owner) return + // TODO: Determine if this is even necessary; slots that require organ tags will vanish when the organ is lost if((body_part & SLOT_FOOT_LEFT) || (body_part & SLOT_FOOT_RIGHT)) - owner.drop_from_inventory(owner.get_equipped_item(slot_shoes_str)) + owner.drop_from_slot(slot_shoes_str) if((body_part & SLOT_HAND_LEFT) || (body_part & SLOT_HAND_RIGHT)) - owner.drop_from_inventory(owner.get_equipped_item(slot_gloves_str)) + owner.drop_from_slot(slot_gloves_str) if(body_part & SLOT_HEAD) - owner.drop_from_inventory(owner.get_equipped_item(slot_head_str)) - owner.drop_from_inventory(owner.get_equipped_item(slot_glasses_str)) - owner.drop_from_inventory(owner.get_equipped_item(slot_l_ear_str)) - owner.drop_from_inventory(owner.get_equipped_item(slot_r_ear_str)) - owner.drop_from_inventory(owner.get_equipped_item(slot_wear_mask_str)) + owner.drop_from_slot(slot_head_str) + owner.drop_from_slot(slot_glasses_str) + owner.drop_from_slot(slot_l_ear_str) + owner.drop_from_slot(slot_r_ear_str) + owner.drop_from_slot(slot_wear_mask_str) //Helper proc used by various tools for repairing robot limbs /obj/item/organ/external/proc/robo_repair(var/repair_amount, var/damage_type, var/damage_desc, obj/item/tool, mob/living/user) From e456493b0c680ee5c258f0086fe88c57643a6bf5 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 24 Sep 2025 10:37:41 +1000 Subject: [PATCH 05/36] Attempting to fix issues with skillset loading. --- code/modules/mob/skills/skillset.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/skills/skillset.dm b/code/modules/mob/skills/skillset.dm index 1b0544de7423..5e9928b3bf4a 100644 --- a/code/modules/mob/skills/skillset.dm +++ b/code/modules/mob/skills/skillset.dm @@ -37,7 +37,7 @@ var/global/list/all_skill_verbs for(var/datum/skill_buff/SB in skill_buffs) . += SB.buffs[skill_path] -/datum/skillset/proc/obtain_from_mob(mob/mob) +/datum/skillset/proc/obtain_from_mob(mob/living/mob) if(!istype(mob) || !skills_transferable || !mob.skillset.skills_transferable) return skill_list = mob.skillset.skill_list From 4942aba4dcab5c6cb5a0f61694c5e805401103a0 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 25 Sep 2025 20:49:52 -0400 Subject: [PATCH 06/36] Remove some entirely-unused defunct variables --- code/game/machinery/_machines_base/stock_parts/cupholder.dm | 1 - .../game/machinery/_machines_base/stock_parts/network_lock.dm | 1 - code/game/machinery/alarm.dm | 1 - .../machinery/embedded_controller/embedded_controller_base.dm | 2 -- code/game/machinery/turret_control.dm | 1 - code/game/machinery/turrets/_turrets.dm | 4 ---- code/game/objects/effects/wet_floor.dm | 1 - code/game/objects/items/devices/chameleonproj.dm | 1 - code/game/objects/items/devices/radio/radio.dm | 1 - code/game/objects/random/subtypes/misc.dm | 1 - code/game/objects/structures/fires.dm | 1 - code/game/objects/structures/tables.dm | 1 - code/modules/backgrounds/citizenship/_citizenship.dm | 1 - code/modules/client/client_defines.dm | 1 - code/modules/clothing/spacesuits/rig/modules/infiltration.dm | 1 - code/modules/clothing/suits/_suit.dm | 1 - code/modules/codex/codex_cataloguer.dm | 2 -- code/modules/lighting/lighting_corner.dm | 3 --- code/modules/mob/living/simple_animal/_simple_animal.dm | 1 - 19 files changed, 26 deletions(-) diff --git a/code/game/machinery/_machines_base/stock_parts/cupholder.dm b/code/game/machinery/_machines_base/stock_parts/cupholder.dm index da49b9b5e9c1..3a3b0aafeba3 100644 --- a/code/game/machinery/_machines_base/stock_parts/cupholder.dm +++ b/code/game/machinery/_machines_base/stock_parts/cupholder.dm @@ -7,7 +7,6 @@ part_flags = PART_FLAG_HAND_REMOVE place_verb = "place" eject_handler = /decl/interaction_handler/remove_held_item/cup - var/image/cupholder_overlay var/obj/item/cup /obj/item/stock_parts/item_holder/cupholder/Destroy() diff --git a/code/game/machinery/_machines_base/stock_parts/network_lock.dm b/code/game/machinery/_machines_base/stock_parts/network_lock.dm index d5cd653186e4..f3be2c31c429 100644 --- a/code/game/machinery/_machines_base/stock_parts/network_lock.dm +++ b/code/game/machinery/_machines_base/stock_parts/network_lock.dm @@ -21,7 +21,6 @@ var/interact_sounds = list("keyboard", "keystroke") var/interact_sound_volume = 40 - var/static/legacy_compatibility_mode = TRUE // Makes legacy access on ids play well with mapped devices with network locks. Override if your server is fully using network-enabled ids or has no mapped access. /obj/item/stock_parts/network_receiver/network_lock/modify_mapped_vars(map_hash) ..() diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index ea3a147ad7ea..4e52cbc8c9c1 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -845,7 +845,6 @@ FIRE ALARM var/time = 1 SECOND var/timing = FALSE var/last_process = 0 - var/static/list/overlays_cache var/sound_id var/datum/sound_token/sound_token diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index 5b622e965a41..6e25b53fb5c3 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -61,8 +61,6 @@ var/tmp/screen_state = "screen_standby" ///Bitflag to indicate which indicator lights are on so dummy controllers can match the same state var/tmp/indicator_state = 0 - ///If set, this controller will route its commands to the master controller with the same id_tag. - var/obj/machinery/embedded_controller/radio/master ///Radio connection to use for emiting commands var/datum/radio_frequency/radio_connection diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm index 4955f4173658..c91249ac56d6 100644 --- a/code/game/machinery/turret_control.dm +++ b/code/game/machinery/turret_control.dm @@ -20,7 +20,6 @@ var/lethal = 0 var/locked = 1 var/area/control_area //can be area name, path or nothing. - var/mob/living/silicon/ai/master_ai var/check_arrest = 1 //checks if the perp is set to arrest var/check_records = 1 //checks if a security record exists at all diff --git a/code/game/machinery/turrets/_turrets.dm b/code/game/machinery/turrets/_turrets.dm index d0e2354b8d57..8fe7e01dc0d6 100644 --- a/code/game/machinery/turrets/_turrets.dm +++ b/code/game/machinery/turrets/_turrets.dm @@ -23,10 +23,6 @@ var/image/transverse_left // Images for displaying the range of the turret's transverse var/image/transverse_right - // Sounds - var/turn_on_sound = null // Played when turret goes from off to on. - var/turn_off_sound = null // The above, in reverse. - // Shooting var/obj/item/gun/installed_gun = /obj/item/gun/energy/laser/practice // Instance of the gun inside the turret. var/gun_looting_prob = 25 // If the turret dies and then is disassembled, this is the odds of getting the gun. diff --git a/code/game/objects/effects/wet_floor.dm b/code/game/objects/effects/wet_floor.dm index 664d777a3887..cef4e3b2c8f9 100644 --- a/code/game/objects/effects/wet_floor.dm +++ b/code/game/objects/effects/wet_floor.dm @@ -5,7 +5,6 @@ mouse_opacity = MOUSE_OPACITY_UNCLICKABLE simulated = FALSE var/wetness = 0 - var/image/wet_overlay = null var/wet_timer_id /atom/movable/wet_floor/Initialize() diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm index f09470bc64ec..fc743829ceef 100644 --- a/code/game/objects/items/devices/chameleonproj.dm +++ b/code/game/objects/items/devices/chameleonproj.dm @@ -103,7 +103,6 @@ anchored = TRUE is_spawnable_type = FALSE movement_handlers = list(/datum/movement_handler/delay/chameleon_projector) - var/can_move = TRUE var/obj/item/chameleon/master = null /obj/effect/dummy/chameleon/Initialize(mapload, var/obj/item/chameleon/projector) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 7277834d2d25..92c10b97b1bb 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -56,7 +56,6 @@ var/broadcasting = FALSE var/listening = TRUE var/list/channels - var/default_color = "#6d3f40" var/decrypt_all_messages = FALSE var/can_use_analog = TRUE var/datum/extension/network_device/radio/radio_device_type = /datum/extension/network_device/radio diff --git a/code/game/objects/random/subtypes/misc.dm b/code/game/objects/random/subtypes/misc.dm index 01f0b1fb231c..27d600db80a6 100644 --- a/code/game/objects/random/subtypes/misc.dm +++ b/code/game/objects/random/subtypes/misc.dm @@ -117,7 +117,6 @@ desc = "This is some random junk." icon = 'icons/obj/items/storage/trashbag.dmi' icon_state = "trashbag3" - var/spawn_choice /obj/random/junk/spawn_choices() var/static/list/spawnable_choices diff --git a/code/game/objects/structures/fires.dm b/code/game/objects/structures/fires.dm index 6f4821ea174c..1b3832173b7e 100644 --- a/code/game/objects/structures/fires.dm +++ b/code/game/objects/structures/fires.dm @@ -57,7 +57,6 @@ var/light_color_low = "#ff0000" var/list/affected_exterior_turfs - var/next_fuel_consumption = 0 var/last_fuel_burn_temperature = T20C // TODO: Replace this and the fuel var with just tracking currently-burning matter? // Or use atom fires when those are implemented? diff --git a/code/game/objects/structures/tables.dm b/code/game/objects/structures/tables.dm index ab9fbf3e716e..fb9dda2bf289 100644 --- a/code/game/objects/structures/tables.dm +++ b/code/game/objects/structures/tables.dm @@ -26,7 +26,6 @@ var/can_flip = TRUE var/is_flipped = FALSE var/decl/material/additional_reinf_material - var/base_type = /obj/structure/table var/top_surface_noun = "tabletop" diff --git a/code/modules/backgrounds/citizenship/_citizenship.dm b/code/modules/backgrounds/citizenship/_citizenship.dm index e16cc9455ac7..d6c349aa1edd 100644 --- a/code/modules/backgrounds/citizenship/_citizenship.dm +++ b/code/modules/backgrounds/citizenship/_citizenship.dm @@ -1,7 +1,6 @@ /decl/background_detail/citizenship abstract_type = /decl/background_detail/citizenship category = /decl/background_category/citizenship - var/ruling_body = "Other Faction" var/capital var/size_heading = "Systems" var/size_value diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index b3487b5e361b..15d3d676b993 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -34,7 +34,6 @@ //IRC admin that spoke with them last. var/irc_admin - var/mute_irc = 0 // Prevents people from being spammed about multikeying every time their mob changes. var/warned_about_multikeying = 0 diff --git a/code/modules/clothing/spacesuits/rig/modules/infiltration.dm b/code/modules/clothing/spacesuits/rig/modules/infiltration.dm index 0fe76208c172..c0cdb63b43d6 100644 --- a/code/modules/clothing/spacesuits/rig/modules/infiltration.dm +++ b/code/modules/clothing/spacesuits/rig/modules/infiltration.dm @@ -185,7 +185,6 @@ interface_name = "dead man's switch" interface_desc = "An integrated automatic self-destruct module. When the wearer dies, so does the surrounding area. Can be triggered manually." var/list/explosion_values = list(1,2,4,5) - var/blinking = 0 var/blink_mode = 0 var/blink_delay = 10 var/blink_time = 40 diff --git a/code/modules/clothing/suits/_suit.dm b/code/modules/clothing/suits/_suit.dm index 7b4809a3b42d..82fdbbb486c5 100644 --- a/code/modules/clothing/suits/_suit.dm +++ b/code/modules/clothing/suits/_suit.dm @@ -11,7 +11,6 @@ valid_accessory_slots = list(ACCESSORY_SLOT_ARMBAND, ACCESSORY_SLOT_OVER) fallback_slot = slot_wear_suit_str var/protects_against_weather = FALSE - var/fire_resist = T0C+100 /obj/item/clothing/suit/gives_weather_protection() return protects_against_weather diff --git a/code/modules/codex/codex_cataloguer.dm b/code/modules/codex/codex_cataloguer.dm index a465ab387b48..ecca7be613bf 100644 --- a/code/modules/codex/codex_cataloguer.dm +++ b/code/modules/codex/codex_cataloguer.dm @@ -22,8 +22,6 @@ var/scan_speed_modifier = 1 /// How many tiles away it can scan. Changing this also changes the box size. var/scan_range = 3 - /// If another person is within this radius, they will also be credited with a successful scan. - var/credit_sharing_range = 14 /// How much to make the next scan shorter. var/tmp/partial_scan_time = 0 /// Weakref of the thing that was last scanned if inturrupted. Used to allow for partial scans to be resumed. diff --git a/code/modules/lighting/lighting_corner.dm b/code/modules/lighting/lighting_corner.dm index 3170ed85d090..3d150896b47b 100644 --- a/code/modules/lighting/lighting_corner.dm +++ b/code/modules/lighting/lighting_corner.dm @@ -61,9 +61,6 @@ var/global/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, var/cache_b = 0 var/cache_mx = 0 - /// Used for planet lighting. Probably needs a better system to prevent over-updating when not needed at some point. - var/update_gen = 0 - /datum/lighting_corner/New(turf/new_turf, diagonal, oi) SSlighting.total_lighting_corners += 1 diff --git a/code/modules/mob/living/simple_animal/_simple_animal.dm b/code/modules/mob/living/simple_animal/_simple_animal.dm index e569fc44d985..28c2a4c16e30 100644 --- a/code/modules/mob/living/simple_animal/_simple_animal.dm +++ b/code/modules/mob/living/simple_animal/_simple_animal.dm @@ -81,7 +81,6 @@ var/return_damage_min var/return_damage_max - var/performing_delayed_life_action = FALSE var/glowing_eyes = FALSE var/mob_icon_state_flags = 0 From cf9feb2ba20b5315d49976decdf5304241422dc9 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 25 Sep 2025 21:08:57 -0400 Subject: [PATCH 07/36] Implement icon_state_active on oxygen pump --- code/game/machinery/oxygen_pump.dm | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/code/game/machinery/oxygen_pump.dm b/code/game/machinery/oxygen_pump.dm index 51f5f1d33cec..7482f522af6c 100644 --- a/code/game/machinery/oxygen_pump.dm +++ b/code/game/machinery/oxygen_pump.dm @@ -17,7 +17,7 @@ var/mask_type = /obj/item/clothing/mask/breath/emergency var/icon_state_open = "emerg_open" var/icon_state_closed = "emerg" - var/icon_state_active // TODO implement + var/icon_state_active power_channel = ENVIRON idle_power_usage = 10 @@ -136,16 +136,24 @@ return return 1 +/obj/machinery/oxygen_pump/on_update_icon() + if(stat & MAINT) + icon_state = icon_state_open + else if(icon_state_active && use_power == POWER_USE_ACTIVE) // the base type doesn't have an active state + icon_state = icon_state_active + else + icon_state = icon_state_closed + /obj/machinery/oxygen_pump/attackby(obj/item/used_item, mob/user) if(IS_SCREWDRIVER(used_item)) stat ^= MAINT user.visible_message(SPAN_NOTICE("\The [user] [stat & MAINT ? "opens" : "closes"] \the [src]."), SPAN_NOTICE("You [stat & MAINT ? "open" : "close"] \the [src].")) - if(stat & MAINT) - icon_state = icon_state_open - if(!stat) - icon_state = icon_state_closed + queue_icon_update() return TRUE - if(istype(used_item, /obj/item/tank) && (stat & MAINT)) + if(istype(used_item, /obj/item/tank)) + if(!(stat & MAINT)) + to_chat(user, SPAN_WARNING("Please open the maintenance hatch first.")) + return TRUE if(tank) to_chat(user, SPAN_WARNING("\The [src] already has a tank installed!")) return TRUE @@ -155,9 +163,6 @@ user.visible_message(SPAN_NOTICE("\The [user] installs \the [tank] into \the [src]."), SPAN_NOTICE("You install \the [tank] into \the [src].")) src.add_fingerprint(user) return TRUE - if(istype(used_item, /obj/item/tank) && !stat) - to_chat(user, SPAN_WARNING("Please open the maintenance hatch first.")) - return TRUE return FALSE // TODO: should this be a parent call? do we want this to be (de)constructable? /obj/machinery/oxygen_pump/get_examine_strings(mob/user, distance, infix, suffix) From d27b8a82b51689961e3b2e8ddcc86fe2acbc2b4e Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 25 Sep 2025 21:09:44 -0400 Subject: [PATCH 08/36] Fix load_event not working due to unused variable --- code/controllers/subsystems/configuration.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystems/configuration.dm b/code/controllers/subsystems/configuration.dm index b342f71f85d3..a61105bc0644 100644 --- a/code/controllers/subsystems/configuration.dm +++ b/code/controllers/subsystems/configuration.dm @@ -15,7 +15,7 @@ SUBSYSTEM_DEF(configuration) load_files() load_sql() - load_event() + load_event(load_event_from) for(var/client/C) C.update_post_config_load() From 5478df383963131f2e04eb5eb76a579e13e70714 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 25 Sep 2025 21:10:21 -0400 Subject: [PATCH 09/36] Remove unused, broken crew manifest spawner --- code/game/objects/effects/manifest.dm | 19 ------------------- nebula.dme | 1 - 2 files changed, 20 deletions(-) delete mode 100644 code/game/objects/effects/manifest.dm diff --git a/code/game/objects/effects/manifest.dm b/code/game/objects/effects/manifest.dm deleted file mode 100644 index 6b84dae52a08..000000000000 --- a/code/game/objects/effects/manifest.dm +++ /dev/null @@ -1,19 +0,0 @@ -/obj/effect/manifest - name = "manifest" - icon = 'icons/effects/markers.dmi' - icon_state = "x" - -/obj/effect/manifest/Initialize() - . = ..() - set_invisibility(INVISIBILITY_ABSTRACT) - -/obj/effect/manifest/proc/manifest() - var/dat = "Crew Manifest:
" - for(var/mob/living/human/M in SSmobs.mob_list) - dat += text(" [] - []
", M.name, M.get_assignment()) - var/obj/item/paper/P = new /obj/item/paper( src.loc ) - P.info = dat - P.SetName("paper- 'Crew Manifest'") - //SN src = null - qdel(src) - return \ No newline at end of file diff --git a/nebula.dme b/nebula.dme index 8a80aa8dfcb0..a897c4435032 100644 --- a/nebula.dme +++ b/nebula.dme @@ -1036,7 +1036,6 @@ #include "code\game\objects\effects\landmarks.dm" #include "code\game\objects\effects\landmarks_endgame.dm" #include "code\game\objects\effects\landmarks_latejoin.dm" -#include "code\game\objects\effects\manifest.dm" #include "code\game\objects\effects\mines.dm" #include "code\game\objects\effects\misc.dm" #include "code\game\objects\effects\overlays.dm" From 9a675149a6b4ff33d7c54af57e11802769837775 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 25 Sep 2025 21:19:24 -0400 Subject: [PATCH 10/36] Implement unused id_title variable on special_role --- code/game/antagonist/antagonist_equip.dm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/code/game/antagonist/antagonist_equip.dm b/code/game/antagonist/antagonist_equip.dm index 022bb8c57d09..2ca60eefcfd9 100644 --- a/code/game/antagonist/antagonist_equip.dm +++ b/code/game/antagonist/antagonist_equip.dm @@ -21,10 +21,13 @@ var/decl/outfit/outfit = GET_DECL(default_outfit) outfit.equip_outfit(player) - if(default_access) - var/obj/item/card/id/id = player.get_equipped_item(slot_wear_id_str) - if(id) + var/obj/item/card/id/id = player.get_equipped_item(slot_wear_id_str) + if(id) + if(default_access) LAZYDISTINCTADD(id.access, default_access) + if(id_title) + id.assignment = id_title + id.position = id_title if(rig_type) equip_rig(rig_type, player) From b7836652f4015a3d443ae2d109decee6e18f61c7 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 25 Sep 2025 21:20:11 -0400 Subject: [PATCH 11/36] Replace deprecated bodytype `has_eyes` variable --- code/modules/bodytype/_bodytype.dm | 4 +--- mods/content/corporate/datum/robolimbs.dm | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/code/modules/bodytype/_bodytype.dm b/code/modules/bodytype/_bodytype.dm index a60007dda2e4..e706f5b387ae 100644 --- a/code/modules/bodytype/_bodytype.dm +++ b/code/modules/bodytype/_bodytype.dm @@ -53,8 +53,6 @@ var/global/list/bodytypes_by_category = list() var/nail_noun /// What tech levels should limbs of this type use/need? var/limb_tech = @'{"biotech":2}' - /// Determines if eyes should render on heads using this bodytype. - var/has_eyes = TRUE /// Prefixed to the initial name of the limb, if non-null. var/modifier_string /// Modifies min and max broken damage for the limb. @@ -231,7 +229,7 @@ var/global/list/bodytypes_by_category = list() var/eye_contaminant_guard = 0 /// Are the eyes of this bodytype resistant to flashes? var/eye_innate_flash_protection = FLASH_PROTECTION_NONE - /// Icon to draw eye overlays from. + /// Icon to draw eye overlays from. If null, eyes will not be drawn. var/eye_icon = 'icons/mob/human_races/species/default_eyes.dmi' /// Do the eyes of this mob apply a pref colour like hair? var/apply_eye_colour = TRUE diff --git a/mods/content/corporate/datum/robolimbs.dm b/mods/content/corporate/datum/robolimbs.dm index 4eba38ba1b61..bf0ad145495f 100644 --- a/mods/content/corporate/datum/robolimbs.dm +++ b/mods/content/corporate/datum/robolimbs.dm @@ -13,7 +13,7 @@ name = "Bishop Rook" desc = "This limb has a polished metallic casing and a holographic face emitter." icon_base = 'mods/content/corporate/icons/cyberlimbs/bishop/bishop_rook.dmi' - has_eyes = FALSE + eye_icon = null // Do not draw eyes. bodytype_category = BODYTYPE_HUMANOID organ_material = /decl/material/solid/metal/steel matter = list( @@ -32,7 +32,7 @@ name = "Hephaestus Titan" desc = "This limb has a casing of an olive drab finish, providing a reinforced housing look." icon_base = 'mods/content/corporate/icons/cyberlimbs/hephaestus/hephaestus_titan.dmi' - has_eyes = FALSE + eye_icon = null // Do not draw eyes. bodytype_category = BODYTYPE_HUMANOID uid = "bodytype_prosthetic_hephaestus_titan" @@ -88,7 +88,7 @@ name = "Morpheus Mantis" desc = "This limb has a casing of sleek black metal and repulsive insectile design." icon_base = 'mods/content/corporate/icons/cyberlimbs/morpheus/morpheus_mantis.dmi' - has_eyes = FALSE + eye_icon = null // Do not draw eyes. uid = "bodytype_prosthetic_morpheus_mantis" /decl/bodytype/prosthetic/veymed From aafb8698d04eabd6c030cea1e4cfd715d2673ad2 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 25 Sep 2025 23:02:50 -0400 Subject: [PATCH 12/36] Replace defunct show_reagent_name variable --- code/game/objects/items/welding/weldingtool_tank.dm | 4 ++-- code/modules/reagents/reagent_containers.dm | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/code/game/objects/items/welding/weldingtool_tank.dm b/code/game/objects/items/welding/weldingtool_tank.dm index 7cb3e5bd84a0..b28b73115dff 100644 --- a/code/game/objects/items/welding/weldingtool_tank.dm +++ b/code/game/objects/items/welding/weldingtool_tank.dm @@ -11,7 +11,7 @@ atom_flags = ATOM_FLAG_OPEN_CONTAINER obj_flags = OBJ_FLAG_HOLLOW volume = 20 - show_reagent_name = TRUE + presentation_flags = PRESENTATION_FLAG_NAME current_health = 40 max_health = 40 material = /decl/material/solid/metal/steel @@ -123,7 +123,7 @@ size_in_use = ITEM_SIZE_LARGE unlit_force = 9 lit_force = 15 - show_reagent_name = FALSE + presentation_flags = 0 _base_attack_force = 8 var/tmp/last_gen = 0 diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 2bf3103378e2..23ed47bc72e5 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -14,7 +14,6 @@ var/volume = 30 var/label_text var/presentation_flags = 0 - var/show_reagent_name = FALSE var/detail_color var/detail_state From cf9e09d921e851af7ec0bbd012ba8eb9ff8dac47 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 26 Sep 2025 01:09:28 -0400 Subject: [PATCH 13/36] Delete unused implantchair machine --- code/modules/implants/implantchair.dm | 146 -------------------------- icons/obj/machines/implantchair.dmi | Bin 7622 -> 0 bytes nebula.dme | 1 - 3 files changed, 147 deletions(-) delete mode 100644 code/modules/implants/implantchair.dm delete mode 100644 icons/obj/machines/implantchair.dmi diff --git a/code/modules/implants/implantchair.dm b/code/modules/implants/implantchair.dm deleted file mode 100644 index 6bfe7ff3b67c..000000000000 --- a/code/modules/implants/implantchair.dm +++ /dev/null @@ -1,146 +0,0 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 - -/obj/machinery/implantchair - name = "loyalty implanter" - desc = "Used to implant occupants with loyalty implants." - icon = 'icons/obj/machines/implantchair.dmi' - icon_state = "implantchair" - density = TRUE - opacity = FALSE - anchored = TRUE - - var/ready = TRUE - var/list/obj/item/implant/loyalty/implant_list = list() - var/max_implants = 5 - var/injection_cooldown = 600 - var/replenish_cooldown = 6000 - var/mob/living/occupant = null - var/injecting = FALSE - -/obj/machinery/implantchair/Initialize() - . = ..() - add_implants() - -/obj/machinery/implantchair/interface_interact(user) - interact(user) - return TRUE - -/obj/machinery/implantchair/interact(mob/user) - user.set_machine(src) - var/health_text = "" - if(src.occupant) - if(src.occupant.current_health <= -100) - health_text = "Dead" - else if(src.occupant.current_health < 0) - health_text = "[round(src.occupant.current_health,0.1)]" - else - health_text = "[round(src.occupant.current_health,0.1)]" - - var/dat ="Implanter Status
" - - dat +="Current occupant: [src.occupant ? "
Name: [src.occupant]
Health: [health_text]
" : "None"]
" - dat += "Implants: [src.implant_list.len ? "[implant_list.len]" : "Replenish"]
" - if(src.occupant) - dat += "[src.ready ? "Implant" : "Recharging"]
" - user.set_machine(src) - show_browser(user, dat, "window=implant") - onclose(user, "implant") - - -/obj/machinery/implantchair/OnTopic(mob/user, href_list) - if((. = ..())) - return - if(!ready) // avoid topic hacking - return TOPIC_NOACTION - if(href_list["implant"] && occupant) - injecting = TRUE - go_out() - ready = FALSE - addtimer(CALLBACK(src, PROC_REF(make_ready)), injection_cooldown) - - if(href_list["replenish"]) - ready = 0 - addtimer(CALLBACK(src, PROC_REF(add_implants)), replenish_cooldown) - addtimer(CALLBACK(src, PROC_REF(make_ready)), replenish_cooldown) - -/obj/machinery/implantchair/proc/make_ready() - ready = TRUE - -/obj/machinery/implantchair/grab_attack(obj/item/grab/grab, mob/user) - var/mob/living/victim = grab.get_affecting_mob() - if(istype(victim) && victim.can_enter_cryopod(user) && put_mob(victim)) - qdel(grab) - updateUsrDialog() - return TRUE - return ..() - -/obj/machinery/implantchair/proc/go_out(var/mob/M) - if(!( src.occupant )) - return - if(M == occupant) // so that the guy inside can't eject himself -Agouri - return - if (src.occupant.client) - src.occupant.client.eye = src.occupant.client.mob - src.occupant.client.perspective = MOB_PERSPECTIVE - occupant.dropInto(loc) - if(injecting) - implant(src.occupant) - injecting = FALSE - src.occupant = null - icon_state = "implantchair" - return - - -/obj/machinery/implantchair/proc/put_mob(mob/living/M) - if(!ishuman(M)) - to_chat(usr, "\The [src] cannot hold this!") - return - if(src.occupant) - to_chat(usr, "\The [src] is already occupied!") - return - if(M.client) - M.client.perspective = EYE_PERSPECTIVE - M.client.eye = src - M.forceMove(src) - src.occupant = M - src.add_fingerprint(usr) - icon_state = "implantchair_on" - return 1 - - -/obj/machinery/implantchair/proc/implant(var/mob/M) - if (!ishuman(M)) - return - if(!implant_list.len) return - for(var/obj/item/implant/loyalty/imp in implant_list) - if(!imp) continue - if(istype(imp, /obj/item/implant/loyalty)) - M.visible_message(SPAN_NOTICE("\The [M] has been implanted by \the [src].")) - if(imp.implanted(M)) - imp.forceMove(M) - imp.imp_in = M - imp.implanted = 1 - implant_list -= imp - break - -/obj/machinery/implantchair/proc/add_implants() - for(var/i=0, iV=-0C=2zim?iVFcd}Sysx zo&D~I^SH$0za{1TWPe~Zr@v5*ZqU%Zp$!(UG&9^}ds_ei9QR2?K~#90<(zwTTUVX$ zKSw&!Ig({bekF3^CT@}@P9|*}nu4Ki#?Y1;E_d(@^y0uU^}xVQhev&B0k0Mqm&Z)X zaEH(`mvjv<4i~6zhev=?(o%~0pqM_L=3(dM$c_`sZ&|Y5k8}UnTasnjtsh~*g1wfP zbYAwUaWd(2(Q}z}np8TCVH93_;_;sq-Mbk4kAD2F+_`8p%DO}x zfHN~Q42MGKR;}Q;1}t;ImrGo?DGKU3U`zsZ@$& zGJ%m!lSn0V=Kxa4Bt|ApcHEn1^>Oap$)f4M9Q;fwg*6)GO0&w*bc(U07#ImTDoc|o zt|=+u`EZz!MU~f*oF6>>M}c2tf)>-d9z3YD?77w0w*6|p`=jqL5sgt{)A?23X%d+X z-@4;70I0XV7l)?dwCSvJyV+Ll;oyfqIT@!nGaJkZt- zfa&kv2f9YTrm?=foGU$5Ja}8%yux1zemI$?#A4=&feQe9v-A z%4HSheE;u1T!6nU1!UVNANVQ&M}|ijnwaG8uGz_n3&Y&@)qiGiatgD>0>JYZ{UpL+ zQn4ui^3XwAu4z~aY_8pT;H!j_XyqGq^56pi92uX)7Yy5$^rb_j&hK z^|@;+Qh?2B<%#|Qo;-Pmd){^fCoT;0%M+)V$)pJ+^3LW>m#yXb(Q$@DVYYi#f;b1? z;o!Gt&hm`!JlEA;#^K|A{PxIE`X?s=P)l8Cx<>Q%t-Lfo#f7nPwymkYWcW_a%Co~` zJa%D(x2|2y6a53c;v1y*!bPyz(aOrvtXAH(b``IL<4nflBvPq@K1?h50T17Ike=`T zjJnlToVYN|?*`6;NhuIMz)KhWym5_(iRo#giNs1E3)=TT_Z6Nx@O`$Fx%lZ*zu~xV zkX!1vvuY9_)FqBF1Vh?mkj@7l-VegDqpQafEI&vMQ; zzzyY2Ru2u}`{knq`_B?jB>2UJQLZX?G8BmuOJ@rDn0E$vz1|w2Z6RQzqvMXh{nWnP z@$k=|BH45;W{ZWPiNL(iq*5uyW@ZRSW3TyQi@|@#hd!M@6{P6=>vDnK9>BQWdwrNm$R zhAWHkqf=857013nh>1iJe>7Uq&w@Unv9a;a1><5F4{xs90l>Sy^iL>;!TtB&k75?V zrlN|jjZ}({{Nq0|o=B2Rr5Fx{7xDg!#NV~h(?G@zZZ?h zh&W3N`dCpE6ikT3DM)ecorY z_{Ps4XHuHq+4zf{0Yzcii4#Wvh{a<>LP3-bH7K>U7(O3n$Q9s>ni`m#nA_h{TM>RX z42(u+h{dD0H*bQ8@!SJ5i3FP6PU-r~AsFEF>E7Q9emWgzY;1(8x86v`*H1hg&f}L? zP_=a%#_$DB^d6nJ<3(q}G8$+Dc(d25oa#H06MoGH-j8C+*E;7*bs~#MfEI(_*w}dI zo4sD;)XA4~!cSgNi)z)FF`09wCobc0-DX44G@RG$$n`ZgGPLAkT+#bW{9q_Z$*y|L znnoa%W+stfCXpZ>iD0%^u(_N73*s-i6frw2yWy@osrkVBacW`#LQ(Td$bK_PM{QTl z#M5bX)3S?@MQ!(|ZYQy>nhNQ7iA9M=B1{AdvvDIH$ENAn-rK@;U+h>B=Ir;s@t(U# zUQvtPrUQ^pil{KF{Oqw!)39ke?vLEY&0qgoL4O4bFgiN!Sj=a(IV@^U_yEShAc`e# zj}?mr!{;jitkU%bUv8=RRl1eR)grvpZ8jWME1KQDpglIlW4KlGyw{e4Uum^qTUSe| z(}h*na@F6t_|bSARm#b!TMMq`7G##Q)_K?W{x8RdE)tE#_~keMgDNaUrl&9|CNhS| zK<%zFMxxVv;=cQM+_YD%9p62*D zAJOAS(Mn2)=r*Fm7Xhf+c{TdvI5*#T15b=j@;|P917BGIKIGQ}KJ)O;I6gc=FcRgo zZ-D7%oQHwakR4i$EPEE(T8fcxK`l>!Mpo#ADbs4Tr9=#^vO(ni|GOMo3#txRQ`e#7M5G zCY(%?t`;R=&1|N^Ry+e*_S|at-2+@#vHdmi{S(mo_qQ1UC7P8omy<^!ridD9_q`0E^4T z`rW&!+^`#1+xcSWS)Ro>eK@WI{fyl__dAd9MEQB|fVgN%<(GCn$)I|uN>S%cl4 zzXBj*R?&5x(<9@2q3z?jPD9gEgyakWxc8n8Uh(J41#{by@mDwJp0(KQoc53M#vNA* zLAYHwGASW^UCfNvZ`s5V-{2+3kDAQr7L}ff0B_$a$}Z)${0PsQpzGIqI2H_}T8b5+ z0?dS_dC$(eb4#`MW)GQ@=IsuOy`M4;%J(MUCIqaWVWYSR8&8> zx&zJ?>i<+}hQ85pEEWsNOr~hIEEWG6(~U%KfdB)cFxHY1tVPHx!?$Z1M58!$E4^dmh4^pTox?vC3}ZJdMAF59mJ0CXuO9*6 zP1oH-Fp%P>eGeDi_?DW#A(ohC==_=7xyQfR#fEp@gvDZ^!lv`$4}MwnoM9MPuH8W- zlObcV()pQvMfWTX|8(x$kH36?y4H6AP_=Fylin8z6+H>O=_&%LG;Y<*cRqLTCBy&G zJ^x1i?H>T3qSV3EqtDKZZ~v?6obV5R@}CN>732Y%>voVzCP^%?a2|_>86O{JbKMSh z?AVE|#F3*UzVO^{c-_^-bdy9P!Lg$+QMYw_?p!9FruW1veEt4?xv*d<_*=K_e$ddXIAd{xAK(@eAz1bYO}R z|H8Jiva*^|XE`M$4vrr`io@Y#W+up}{~}XU<6OLWvFMp-G(;pa!;`;$1h>0_jG-f&B_}8c=Trp8>i8O$xLE`+!z6_$=T7+$LzwzyXt3AUI@#Lk2X;=R80?&$@L8So=Ue7zJl zKtPVtc16sBCWLZ)K#x>RJ+_&de06hPCFD_N(0#L7OY;xH6&-Z`u_r}kEc6f|f zB9Y_gSAR}yrFu1fe(M?NHi=Q+gcz-L2y^6<0&SmVhGK~0{Rkm8$XT-=XrBEWrCH1R zg98S10AA@MJV5<&6_9Q1-@XrkmqHQ7V{zVERmMmn$;Tf&$oMP@-iv_{GpQ8uRJw>C zzmoRZ@BRmn=jXq3!+Op~q6PeX-J;?h9wTKh;W8-NAJDQ!jNCSa3CRk!SphH5ses!M zcE3r1T15!5Nr5&60)|kIR{@Vn_<_9{XfuiD8l=Fp3aQP0SDk&~< z55lo`0d?RD3~ni{;rV>DJ* z;R}R{`1#&yF{-@?N86=9k0DHvF3n4;0{aXx8$3V@LNV=%m^n=dXPY%seTe=%3dAzd zU=sb*%V#`DMYDqa0kiq>FW>uhf`8q_o>guhc<6@&$H!S?voiFg7p<&3HxnYMG-LBr z1XqgR^R;i!&(DA6X=-n}8SJ7w;ETqJ`1u`gu;Q^ok4ZR1Kf*lJD#9cMRPbBC9fc+< z^thnI1no26+Yaq^*sltOZ~+>9(0wg5*`P;Ki_1g?DAUTi3GFVUMRUVNBnB|b)UbR z{?Rcm1cDHcW17X!S2PXR`dUED0M%lFXpB*{FiUPP7vZ2E5w)}{Vx$HXQIcqtqjo=X zG@(OA|IN1O~=mCTu@FEn@AZJ&$6w$y6o$z!jg%S#q9*=V2(OYq`;e6Yr$vCWtx=xbp74h@CO2vq5meEO@jDWgLLV!MCpCXEHhZG^eE=43{jR=3xBE!%Y zMCiE>Sqnl$PHhM!b|QrDM?BwPTA>0i|M4SS4*crEx%^AdcjL$~!4W@Yho2^pnD>rl zwc00tM=kKHkrCpN2o9??w?ANZO9cW1BT@AK`Z;qwkjD&u2ORnd#7+sJ^vMKkuStw% z_blgGj~MOsh>`6@D6bt69o5O=8`6|DAr#hV$b14}j+zjDV%hrxvi$g|c!Iw$J2_uo z0hwa^u9a612?m+|!NWvj2~^c|N%{FX{Dt`W50LZIymG_DioqyaIK z_ey8!mvKCZ(VHF7Z5im23Tv8mEo*uXA^c05kz&O{>iDUEg<5!BGrKnf!zII-IzNdaCDPRAB`vYQS&>?)7I&XT*Qeo%Czww^C`0=;C zh0~_z_?YoXWL|!Lsndn&Be(H}t#y3&mUrd)i)|N<)Q@ns9z>|vrsSPwyCUp$D`IAJ zA#A-qE4s;+GddAILDZBK8pwyCtq2q3A)jXyD8T6GxC5{E&e!_P-d|}|sa>~@fV&(` z*RVPqL_hJ_rNvhAt7ks>z42@L1s)F~k=v(;=*S~K zm$g42TaW+ZZ+}bQ&_#k7gTVnGzMmcfz+ShN!R~I%77Lr3-p0(p05@N`jicqOdHc34 zeBt`*E)75bmye140g)(!em}lvo~Fde6!7ym+;lU>;5lyCbu~R^EAQBORRKT0bNUvC z2Vt9Y#WYon;zopGdJqv!w<1Px&QFjpRcDth_se{uD|??jZdLM?(k{gJy{1|F1D3;& zFI82_sw%nMY^Hy7jId&&(kkqJZnwyq8dh(*g39Vu=~{etBQkzcew+2juwiBNXuBvu*ad zEI;1E`rNrvRYkK}aeAsT#bb;V^&kbIs_5q8z-zhqS+2d?Y^FrlaFhxAK9`+Sp@5>> zahi&moBO^AZB{v=)x2%@Ad;uUE|InF*TEMTW}{Yv78BH};M1Y|6dc$r`s=enmnxie zpA0_%+RQ=;wYpdQh;4GQ#ubTdcL+?etw0fVRO5f zjK;}mI_YFGX9fXQD+cH1p@+Aaq1zCn`%qGh&}Jnc?YJjIsUhbdWX{m6K+F(1M7sj@ zCxux#kb#&<`V^S~XJ=Lq!Vw=v%#!Bkr2;;P#QyHjN?3`G68d z@bh07pPCB`z@b&Lb|cM0lN7ukp@b$WtWKl=4N-Dvl?w4GvP?~$jMb;)qn{@ETy7B` zQQ+IhtW0>h{P@|eKO8CK$8Qt=xiAn2ysGe5f}iE*1N4qf6yjg|`W*gje*Rn&*z6Q# z;!b&-4Ko9B9k*Tzvsnr-Agi6VvUHtYzRWt~2AMPTApFE$WLX2D+^nL!@^cyc0}A=^ z4R_xTK)J3l{JY-y`SF{!Ai^cVz)F~K3T$UMMO}|N`8Ugr{pWBZbTHcto;FhO8oqW z^|v@Yvqq+8fxmi12(!h==LOkZAiKbxtq*k}vu6c53_(Y1k&4;})R{zW$-^8c{O8Ee zZ|)V#B8Lxi5SCNVqwa)dW2P-hm$9kL{mT_MYwE4KkY=`RjRrDWL= z9-tvJM*)A1{QS1h*Rj_StcV^&O(#3TLDuhQ39c2v^=TqsQpgGv@_r(KNWkiWE}2`* z=APCg%+|8@2mC4V^BZpx!psQ^ktiKTmK6{RX;nqI8Ze1P_byqk*o!DTbjWhU0YtgE oPZ9TJNxxYW)h+w3RfI42|HAz<@paeSi2wiq07*qoM6N<$g2(R Date: Fri, 26 Sep 2025 02:24:47 -0400 Subject: [PATCH 14/36] Clean up implant-related code --- code/__defines/misc.dm | 2 +- code/datums/uplink/uplink_sources.dm | 15 +- code/game/machinery/computer/prisoner.dm | 98 +++++++------ code/game/machinery/teleporter.dm | 44 +++--- code/game/objects/items/weapons/locator.dm | 133 ++++++++---------- .../loadout/lists/augmentations.dm | 4 +- code/modules/emotes/emote_mob.dm | 7 +- code/modules/implants/implant.dm | 72 +++++----- .../implants/implant_types/adrenaline.dm | 14 +- code/modules/implants/implant_types/chem.dm | 22 ++- .../implants/implant_types/compressed.dm | 91 ++++++------ .../implants/implant_types/death_alarm.dm | 30 ++-- .../implants/implant_types/explosive.dm | 51 +++---- .../modules/implants/implant_types/freedom.dm | 19 +-- .../implants/implant_types/imprinting.dm | 83 ++++++----- .../modules/implants/implant_types/loyalty.dm | 21 +-- .../implants/implant_types/tracking.dm | 10 +- .../implants/implant_types/translator.dm | 10 +- code/modules/implants/implant_types/uplink.dm | 7 +- code/modules/implants/implantcase.dm | 15 +- code/modules/implants/implanter.dm | 4 +- code/modules/implants/implantpad.dm | 40 +++--- code/modules/mob/living/human/human.dm | 37 ++--- code/modules/mob/living/silicon/silicon.dm | 2 +- code/modules/surgery/implant.dm | 56 ++++---- mods/content/pheromones/pheromone_mob.dm | 2 +- .../psionics/items/foundation_implanter.dm | 7 +- mods/content/psionics/machines/psimonitor.dm | 4 +- mods/content/xenobiology/slime/items.dm | 6 +- 29 files changed, 460 insertions(+), 446 deletions(-) diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index a4e64c8e07dc..4d5a639708f0 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -53,7 +53,7 @@ #define STATUS_HUD 2 // Alive, dead, diseased, etc. #define ID_HUD 3 // The job asigned to your ID. #define WANTED_HUD 4 // Wanted, released, paroled, security status. -#define IMPLOYAL_HUD 5 // Loyality implant. +#define IMPLOYAL_HUD 5 // Loyalty implant. #define IMPCHEM_HUD 6 // Chemical implant. #define IMPTRACK_HUD 7 // Tracking implant. #define SPECIALROLE_HUD 8 // AntagHUD image. diff --git a/code/datums/uplink/uplink_sources.dm b/code/datums/uplink/uplink_sources.dm index a37027741bf1..37f30e941cc9 100644 --- a/code/datums/uplink/uplink_sources.dm +++ b/code/datums/uplink/uplink_sources.dm @@ -68,21 +68,16 @@ var/global/list/default_uplink_source_priority = list( name = "Implant" desc = "Teleports an uplink implant into your head. Costs 20% of the initial TC amount." -/decl/uplink_source/implant/setup_uplink_source(var/mob/living/human/H, var/amount) - if(!istype(H)) +/decl/uplink_source/implant/setup_uplink_source(var/mob/living/human/recipient, var/amount) + if(!istype(recipient)) return SETUP_FAILED - var/obj/item/organ/external/head = GET_EXTERNAL_ORGAN(H, BP_HEAD) + var/obj/item/organ/external/head = GET_EXTERNAL_ORGAN(recipient, BP_HEAD) if(!head) return SETUP_FAILED - var/obj/item/implant/uplink/U = new(H, round(amount * 0.8)) - U.imp_in = H - U.implanted = TRUE - U.part = head - LAZYADD(head.implants, U) - - U.implanted(H) // This proc handles the installation feedback + var/obj/item/implant/uplink/uplink_implant = new(recipient, round(amount * 0.8)) + uplink_implant.implant_in_mob(recipient, recipient, head) /decl/uplink_source/unit name = "Uplink Unit" diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm index aa9eb1647d52..13b2847b3440 100644 --- a/code/game/machinery/computer/prisoner.dm +++ b/code/game/machinery/computer/prisoner.dm @@ -7,76 +7,86 @@ icon_screen = "explosive" light_color = "#a91515" initial_access = list(access_armory) - var/screen = 0 // 0 - No Access Denied, 1 - Access allowed + var/locked = FALSE /obj/machinery/computer/prisoner/interface_interact(user) interact(user) return TRUE /obj/machinery/computer/prisoner/interact(var/mob/user) - var/dat + var/dat = list() dat += "Prisoner Implant Manager System
" - if(screen == 0) + if(locked) dat += "
Unlock Console" - else if(screen == 1) + else dat += "
Chemical Implants
" - var/turf/Tr = null - for(var/obj/item/implant/chem/C in global.chem_implants) - Tr = get_turf(C) - if((Tr) && !LEVELS_ARE_Z_CONNECTED(Tr.z, src.z)) continue // Out of range - if(!C.implanted) continue - dat += "[C.imp_in.name] | Remaining Units: [C.reagents.total_volume] | Inject: " - dat += "((1))" - dat += "((5))" - dat += "((10))
" + for(var/obj/item/implant/chem/chem_implant in global.chem_implants) + var/turf/implant_turf = get_turf(chem_implant) + if(implant_turf && !LEVELS_ARE_Z_CONNECTED(implant_turf.z, src.z)) + continue // Out of range + if(!chem_implant.implanted) + continue + dat += "[chem_implant.imp_in.name] | Remaining Units: [chem_implant.reagents.total_volume] | Inject: " + dat += "((1))" + dat += "((5))" + dat += "((10))
" dat += "********************************
" dat += "
Tracking Implants
" - for(var/obj/item/implant/tracking/T in global.tracking_implants) - Tr = get_turf(T) - if((Tr) && !LEVELS_ARE_Z_CONNECTED(Tr.z, src.z)) continue // Out of range - if(!T.implanted) continue - var/loc_display = "Space" - var/mob/living/M = T.imp_in - if(!isspaceturf(M.loc)) - var/turf/mob_loc = get_turf(M) - loc_display = mob_loc.loc - if(T.malfunction) + for(var/obj/item/implant/tracking/tracking_implant in global.tracking_implants) + var/turf/implant_turf = get_turf(tracking_implant) + if(implant_turf && !LEVELS_ARE_Z_CONNECTED(implant_turf.z, src.z)) + continue // Out of range + if(!tracking_implant.implanted) + continue + var/area/tracked_area = get_area(tracking_implant) + var/loc_display = tracked_area.proper_name + if(tracking_implant.malfunction) loc_display = pick(teleportlocs) - dat += "ID: [T.id] | Location: [loc_display]
" - dat += "(Message Holder) |
" + dat += "ID: [tracking_implant.id] | Location: [loc_display]
" + dat += "(Message Holder) |
" dat += "********************************
" dat += "
Lock Console" - show_browser(user, dat, "window=computer;size=400x500") + show_browser(user, JOINTEXT(dat), "window=computer;size=400x500") onclose(user, "computer") /obj/machinery/computer/prisoner/OnTopic(mob/user, href_list) if((. = ..())) return - . = TOPIC_REFRESH - if(href_list["inject1"]) - var/obj/item/implant/I = locate(href_list["inject1"]) - if(I) I.activate(1) - - else if(href_list["inject5"]) - var/obj/item/implant/I = locate(href_list["inject5"]) - if(I) I.activate(5) - - else if(href_list["inject10"]) - var/obj/item/implant/I = locate(href_list["inject10"]) - if(I) I.activate(10) + if(href_list["inject"]) + var/obj/item/implant/chem/chem_implant = locate(href_list["inject"]) + if(!chem_implant) + return TOPIC_REFRESH // evidently their copy of the UI is out of date + if(!istype(chem_implant)) // exists but is not a chem implant + // warn that this is likely an href hacking attempt + PRINT_STACK_TRACE("Possible HREF hacking attempt, chem implant inject called on non-chem-implant!") + message_admins("Possible HREF hacking attempt, chem implant inject called on [href_list["inject"]] by [user] (ckey [(user.ckey)])!") + return TOPIC_HANDLED + var/amount_to_inject = clamp(text2num(href_list["amount"]), 1, 10) // don't let href hacking give more than 10 units at once + chem_implant.activate(amount_to_inject) + return TOPIC_HANDLED else if(href_list["lock"]) if(allowed(user)) - screen = !screen + locked = !locked + return TOPIC_REFRESH else to_chat(user, "Unauthorized Access.") + return TOPIC_HANDLED else if(href_list["warn"]) var/warning = sanitize(input(user,"Message:","Enter your message here!","")) - if(!warning) return TOPIC_HANDLED - var/obj/item/implant/I = locate(href_list["warn"]) - if(I?.imp_in) - var/mob/living/victim = I.imp_in - to_chat(victim, "You hear a voice in your head saying: '[warning]'") + if(!warning) + return TOPIC_HANDLED + var/obj/item/implant/tracking/tracker = locate(href_list["warn"]) + if(!tracker) + return TOPIC_REFRESH // evidently their copy of the UI is out of date + if(!istype(tracker)) // exists but is not a tracking implant + // warn that this is likely an href hacking attempt + PRINT_STACK_TRACE("Possible HREF hacking attempt, tracking implant warn called on non-tracking-implant!") + message_admins("Possible HREF hacking attempt, tracking implant warn called on [href_list["warn"]] by [user] (ckey [(user.ckey)])!") + return TOPIC_HANDLED + to_chat(tracker.imp_in, SPAN_NOTICE("You hear a voice in your head saying: '[warning]'")) + return TOPIC_HANDLED + return TOPIC_NOACTION diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index 6053e343fad9..b2ee51ae93a7 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -86,12 +86,13 @@ for(var/obj/item/radio/beacon/radio in global.radio_beacons) if(!radio.functioning) continue - var/turf/T = get_turf(radio) - if (!T) + var/turf/radio_turf = get_turf(radio) + if (!radio_turf) continue - if(!isPlayerLevel(T.z)) + if(!isPlayerLevel(radio_turf.z)) continue - var/tmpname = T.loc.name + var/area/radio_area = get_area(radio) + var/tmpname = radio_area.proper_name if(areaindex[tmpname]) tmpname = "[tmpname] ([++areaindex[tmpname]])" else @@ -101,22 +102,21 @@ for (var/obj/item/implant/tracking/used_item in global.tracking_implants) if (!used_item.implanted || !ismob(used_item.loc)) continue + var/mob/victim = used_item.loc + // Can only track dead people up to 10 minutes after death + if (victim.stat == DEAD && world.time > victim.timeofdeath + 10 MINUTES) + continue + var/turf/victim_turf = get_turf(victim) + if(!victim_turf) + continue + if(!isPlayerLevel(victim_turf.z)) + continue + var/tmpname = victim.real_name + if(areaindex[tmpname]) + tmpname = "[tmpname] ([++areaindex[tmpname]])" else - var/mob/M = used_item.loc - if (M.stat == DEAD) - if (M.timeofdeath + 6000 < world.time) - continue - var/turf/T = get_turf(M) - if(!T) - continue - if(!isPlayerLevel(T.z)) - continue - var/tmpname = M.real_name - if(areaindex[tmpname]) - tmpname = "[tmpname] ([++areaindex[tmpname]])" - else - areaindex[tmpname] = 1 - L[tmpname] = used_item + areaindex[tmpname] = 1 + L[tmpname] = used_item var/desc = input("Please select a location to lock in.", "Locking Computer") in L|null if(!desc) @@ -127,7 +127,7 @@ audible_message(SPAN_NOTICE("Locked in.")) return -/obj/machinery/computer/teleporter/verb/set_id(t as text) +/obj/machinery/computer/teleporter/verb/set_id(new_tag as text) set category = "Object" set name = "Set teleporter ID" set src in oview(1) @@ -135,8 +135,8 @@ if(stat & (NOPOWER|BROKEN) || !isliving(usr)) return - if (t) - src.id = t + if (new_tag) + src.id = new_tag return /obj/machinery/computer/teleporter/proc/target_lost() diff --git a/code/game/objects/items/weapons/locator.dm b/code/game/objects/items/weapons/locator.dm index 01fe0fcc8c02..fc5bcf8b0fc8 100644 --- a/code/game/objects/items/weapons/locator.dm +++ b/code/game/objects/items/weapons/locator.dm @@ -34,79 +34,68 @@ Frequency: onclose(user, "radio") return -/obj/item/locator/Topic(href, href_list) - ..() - if (usr.stat || usr.restrained()) +/obj/item/locator/OnTopic(mob/user, href_list, datum/topic_state/state) + var/turf/current_location = get_turf(user) //What turf is the user on? + if(!current_location || isAdminLevel(current_location.z)) //If turf was not found or they're on an admin Z-level + to_chat(user, "\The [src] is malfunctioning.") return - var/turf/current_location = get_turf(usr)//What turf is the user on? - if(!current_location||current_location.z==2)//If turf was not found or they're on z level 2. - to_chat(usr, "\The [src] is malfunctioning.") + if(!CanPhysicallyInteract(user)) return - if ((usr.contents.Find(src) || (in_range(src, usr) && isturf(src.loc)))) - usr.set_machine(src) - if (href_list["refresh"]) - src.temp = "Persistent Signal Locator
" - var/turf/sr = get_turf(src) - - if (sr) - src.temp += "Located Beacons:
" - - for(var/obj/item/radio/beacon/radio in global.radio_beacons) - if(!radio.functioning) - continue - if (radio.frequency == src.frequency) - var/turf/tr = get_turf(radio) - if (tr.z == sr.z && tr) - var/direct = max(abs(tr.x - sr.x), abs(tr.y - sr.y)) - if (direct < 5) - direct = "very strong" - else - if (direct < 10) - direct = "strong" - else - if (direct < 20) - direct = "weak" - else - direct = "very weak" - src.temp += "[radio.code]-[dir2text(get_dir(sr, tr))]-[direct]
" - - src.temp += "Extranneous Signals:
" - for (var/obj/item/implant/tracking/implant in global.tracking_implants) - if (!implant.implanted || !(istype(implant.loc,/obj/item/organ/external) || ismob(implant.loc))) - continue - else - var/mob/M = implant.loc - if (M.stat == DEAD) - if (M.timeofdeath + 6000 < world.time) - continue + user.set_machine(src) + if (href_list["refresh"]) + src.temp = "Persistent Signal Locator
" + var/turf/source_turf = get_turf(src) + if (!source_turf) + src.temp += "Processing Error: Unable to locate orbital position.
" + return TOPIC_REFRESH + src.temp += "Located Beacons:
" + for(var/obj/item/radio/beacon/radio in global.radio_beacons) + if(!radio.functioning) + continue + if (radio.frequency != frequency) + continue + var/turf/radio_turf = get_turf(radio) + if (radio_turf.z != source_turf.z || !radio_turf) + continue + var/distance + switch(get_dist(radio_turf, source_turf)) + if(0 to 5) + distance = "very strong" + if(6 to 10) + distance = "strong" + if(11 to 20) + distance = "weak" + else + continue + if(distance) + src.temp += "[radio.code]-[dir2text(get_dir(source_turf, radio_turf))]-[distance]
" - var/turf/tr = get_turf(implant) - if (tr.z == sr.z && tr) - var/direct = max(abs(tr.x - sr.x), abs(tr.y - sr.y)) - if (direct < 20) - if (direct < 5) - direct = "very strong" - else - if (direct < 10) - direct = "strong" - else - direct = "weak" - src.temp += "[implant.id]-[dir2text(get_dir(sr, tr))]-[direct]
" + src.temp += "Extraneous Signals:
" + for (var/obj/item/implant/tracking/implant in global.tracking_implants) + if (!implant.implanted || !(istype(implant.loc,/obj/item/organ/external) || ismob(implant.loc))) + continue + var/mob/victim = implant.loc + // Don't show dead people that have been dead for a while + if (victim.stat == DEAD && world.time > victim.timeofdeath + 10 MINUTES) + continue + var/turf/implant_turf = get_turf(implant) + if (implant_turf?.z != source_turf.z) + continue + var/distance + switch(get_dist(implant_turf, source_turf)) + if(0 to 5) + distance = "very strong" + if(6 to 10) + distance = "strong" + if(11 to 20) + distance = "weak" + if(distance) + src.temp += "[implant.id]-[dir2text(get_dir(source_turf, implant_turf))]-[distance]
" - src.temp += "You are at \[[sr.x],[sr.y],[sr.z]\] in orbital coordinates.

Refresh
" - else - src.temp += "Processing Error: Unable to locate orbital position.
" - else - if (href_list["freq"]) - src.frequency += text2num(href_list["freq"]) - src.frequency = sanitize_frequency(src.frequency) - else - if (href_list["temp"]) - src.temp = null - if (ismob(src.loc)) - attack_self(src.loc) - else - for(var/mob/M in viewers(1, src)) - if (M.client) - src.attack_self(M) - return + src.temp += "You are at \[[source_turf.x],[source_turf.y],[source_turf.z]\] in orbital coordinates.

Refresh
" + else if (href_list["freq"]) + src.frequency += text2num(href_list["freq"]) + src.frequency = sanitize_frequency(src.frequency) + else if (href_list["temp"]) + src.temp = null + return TOPIC_REFRESH diff --git a/code/modules/client/preference_setup/loadout/lists/augmentations.dm b/code/modules/client/preference_setup/loadout/lists/augmentations.dm index fe6385963080..1fa6febaf4fa 100644 --- a/code/modules/client/preference_setup/loadout/lists/augmentations.dm +++ b/code/modules/client/preference_setup/loadout/lists/augmentations.dm @@ -8,11 +8,11 @@ custom_setup_proc = /obj/item/proc/AttemptAugmentation custom_setup_proc_arguments = list(BP_CHEST) -/obj/item/proc/AttemptAugmentation(mob/user, target_zone) +/obj/item/proc/AttemptAugmentation(mob/living/user, target_zone) to_chat(user, SPAN_DANGER("Was unable to augment you with \the [src].")) qdel(src) -/obj/item/implant/AttemptAugmentation(mob/user, target_zone) +/obj/item/implant/AttemptAugmentation(mob/living/user, target_zone) if(can_implant(user, user, target_zone) && implant_in_mob(user, user, target_zone)) var/obj/item/organ/organ = GET_EXTERNAL_ORGAN(user, target_zone) to_chat(user, SPAN_NOTICE("You have \a [src] implanted in your [organ.name].")) diff --git a/code/modules/emotes/emote_mob.dm b/code/modules/emotes/emote_mob.dm index 9cfdf00cdd0f..b91444de9608 100644 --- a/code/modules/emotes/emote_mob.dm +++ b/code/modules/emotes/emote_mob.dm @@ -99,9 +99,10 @@ next_emote = world.time + use_emote.emote_delay use_emote.do_emote(src, message) - for (var/obj/item/implant/I in src) - if (I.implanted) - I.trigger(act, src) + for (var/obj/item/implant/implant in src) + if(!implant.implanted) + continue + implant.trigger(act, src) #undef EMOTE_REFRESH_SPAM_COOLDOWN diff --git a/code/modules/implants/implant.dm b/code/modules/implants/implant.dm index 2572ce810556..0e58c2b46b19 100644 --- a/code/modules/implants/implant.dm +++ b/code/modules/implants/implant.dm @@ -1,3 +1,4 @@ +#define MALFUNCTION_NONE 0 #define MALFUNCTION_TEMPORARY 1 #define MALFUNCTION_PERMANENT 2 @@ -8,13 +9,15 @@ icon_state = "implant" w_class = ITEM_SIZE_TINY material = /decl/material/solid/metal/titanium - var/implanted = null - var/mob/imp_in = null - var/obj/item/organ/external/part = null + var/implanted = FALSE + var/mob/imp_in + var/obj/item/organ/external/part var/implant_color = "b" - var/malfunction = 0 - var/known //if advanced scanners would name these in results - var/hidden //if scanners will locate this implant at all + var/malfunction = MALFUNCTION_NONE + /// if TRUE, advanced scanners will directly name the implant in results + var/known = FALSE + /// if FALSE, scanners will not locate this implant at all + var/hidden = FALSE /obj/item/implant/proc/trigger(emote, source) return @@ -25,48 +28,46 @@ /obj/item/implant/proc/activate() return -/obj/item/implant/proc/disable(var/time = 100) +/obj/item/implant/proc/disable(var/time = 10 SECONDS) if(malfunction) - return 0 + return FALSE malfunction = MALFUNCTION_TEMPORARY addtimer(CALLBACK(src,PROC_REF(restore)),time) - return 1 + return TRUE /obj/item/implant/proc/restore() if(malfunction == MALFUNCTION_PERMANENT || !malfunction) - return 0 + return FALSE - malfunction = 0 - return 1 + malfunction = MALFUNCTION_NONE + return TRUE // What does the implant do upon injection? -// return 0 if the implant fails (ex. Revhead and loyalty implant.) +// return FALSE if the implant fails (ex. Revhead and loyalty implant.) // return TRUE if the implant succeeds (ex. Nonrevhead and loyalty implant.) -/obj/item/implant/proc/implanted(var/mob/source) +/obj/item/implant/proc/implanted(var/mob/living/source) return TRUE -/obj/item/implant/proc/can_implant(mob/M, mob/user, var/target_zone) - var/mob/living/human/H = M - if(istype(H) && !GET_EXTERNAL_ORGAN(H, target_zone)) - to_chat(user, "\The [M] is missing that body part.") +/obj/item/implant/proc/can_implant(mob/living/victim, mob/user, var/target_zone) + var/mob/living/human/human_victim = victim + if(istype(human_victim) && !GET_EXTERNAL_ORGAN(human_victim, target_zone)) + to_chat(user, SPAN_WARNING("\The [human_victim] is missing that body part.")) return FALSE return TRUE -/obj/item/implant/proc/implant_in_mob(mob/M, var/target_zone) - if (ishuman(M)) - var/mob/living/human/H = M - var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(H, target_zone) +/obj/item/implant/proc/implant_in_mob(mob/living/victim, mob/living/user, var/target_zone) + if (ishuman(victim)) + var/mob/living/human/human_victim = victim + var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(human_victim, target_zone) if(affected) LAZYADD(affected.implants, src) part = affected - BITSET(H.hud_updateflag, IMPLOYAL_HUD) - - forceMove(M) - imp_in = M - implanted = 1 - implanted(M) + forceMove(victim) + imp_in = victim + implanted = TRUE + implanted(victim) return TRUE @@ -75,7 +76,7 @@ if(part) LAZYREMOVE(part.implants, src) part = null - implanted = 0 + implanted = FALSE //Called in surgery when incision is retracted open / ribs are opened - basically before you can take implant out /obj/item/implant/proc/exposed() @@ -97,13 +98,10 @@ return FALSE /obj/item/implant/proc/meltdown() //breaks it down, making implant unrecongizible - if(malfunction == MALFUNCTION_PERMANENT) return + if(malfunction == MALFUNCTION_PERMANENT) + return to_chat(imp_in, SPAN_DANGER("You feel something melting inside [part ? "your [part.name]" : "you"]!")) - if (part) - part.take_damage(15, BURN, inflicter = "Electronics meltdown") - else - var/mob/living/M = imp_in - M.apply_damage(15,BURN) + imp_in.apply_damage(15, BURN, used_weapon = "Electronics meltdown", given_organ = part) // used_weapon can be a string or an item, for some reason name = "melted implant" desc = "Charred circuit in melted plastic case. Wonder what that used to be..." icon_state = "implant_melted" @@ -116,11 +114,13 @@ else if(prob(power * 25)) activate() else if(prob(power * 33)) - disable(rand(power*100,power*1000)) + disable(rand(power*10 SECONDS,power*100 SECONDS)) /obj/item/implant/Destroy() if(part) LAZYREMOVE(part.implants, src) + part = null + imp_in = null var/obj/item/implanter/implanter = loc if(istype(implanter) && implanter.imp == src) implanter.imp = null diff --git a/code/modules/implants/implant_types/adrenaline.dm b/code/modules/implants/implant_types/adrenaline.dm index ec6f6166e42b..c7e2dc6a2ffb 100644 --- a/code/modules/implants/implant_types/adrenaline.dm +++ b/code/modules/implants/implant_types/adrenaline.dm @@ -2,8 +2,8 @@ name = "adrenalin implant" desc = "Removes all stuns and knockdowns." origin_tech = @'{"materials":1,"biotech":2,"esoteric":2}' - hidden = 1 - var/uses + hidden = TRUE + var/uses = 3 /obj/item/implant/adrenalin/get_data() return {" @@ -22,17 +22,19 @@ activate() /obj/item/implant/adrenalin/activate()//this implant is unused but I'm changing it for the sake of consistency - if (uses < 1 || malfunction || !imp_in) return 0 + if (uses < 1 || malfunction || !imp_in) + return 0 uses-- - to_chat(imp_in, "You feel a sudden surge of energy!") + to_chat(imp_in, SPAN_NOTICE("You feel a sudden surge of energy!")) imp_in.set_status_condition(STAT_STUN, 0) imp_in.set_status_condition(STAT_WEAK, 0) imp_in.set_status_condition(STAT_PARA, 0) /obj/item/implant/adrenalin/implanted(mob/source) - source.StoreMemory("\A [src] can be activated by using the pale emote, say *pale to attempt to activate.", /decl/memory_options/system) - to_chat(source, "\The [src] can be activated by using the pale emote, say *pale to attempt to activate.") + var/activation_string = "can be activated by using the pale emote, say *pale to attempt to activate." + source.StoreMemory("\A [src] [activation_string]", /decl/memory_options/system) + to_chat(source, "\The [src] [activation_string]") return TRUE /obj/item/implanter/adrenalin diff --git a/code/modules/implants/implant_types/chem.dm b/code/modules/implants/implant_types/chem.dm index a98016b2d583..b78de9f03523 100644 --- a/code/modules/implants/implant_types/chem.dm +++ b/code/modules/implants/implant_types/chem.dm @@ -4,7 +4,7 @@ var/global/list/chem_implants = list() name = "chemical implant" desc = "Injects things." origin_tech = @'{"materials":1,"biotech":2}' - known = 1 + known = TRUE /obj/item/implant/chem/get_data() return {" @@ -33,24 +33,22 @@ var/global/list/chem_implants = list() global.chem_implants -= src /obj/item/implant/chem/activate(var/amount) - if(malfunction || (!ishuman(imp_in))) return 0 + if(malfunction) + return FALSE if(!amount) amount = rand(1,25) - var/mob/living/R = imp_in - reagents.trans_to_mob(R, amount, CHEM_INJECT) - to_chat(R, "You hear a faint *beep*.") + reagents.trans_to_mob(imp_in, amount, CHEM_INJECT) + to_chat(imp_in, SPAN_NOTICE("You hear a faint *beep*.")) /obj/item/implant/chem/attackby(obj/item/used_item, mob/user) if(istype(used_item, /obj/item/chems/syringe)) if(reagents.total_volume >= reagents.maximum_volume) - to_chat(user, "\The [src] is full.") - else - if(do_after(user,5,src)) - used_item.reagents.trans_to_obj(src, 5) - to_chat(user, "You inject 5 units of the solution. The syringe now contains [used_item.reagents.total_volume] units.") + to_chat(user, SPAN_WARNING("\The [src] is full.")) + else if(do_after(user, 0.5 SECONDS, src)) + used_item.reagents.trans_to_obj(src, 5) + to_chat(user, SPAN_NOTICE("You inject 5 units of the solution. The syringe now contains [used_item.reagents.total_volume] units.")) return TRUE - else - return ..() + return ..() /obj/item/implantcase/chem name = "glass case - 'chem'" diff --git a/code/modules/implants/implant_types/compressed.dm b/code/modules/implants/implant_types/compressed.dm index ad6dee6983b1..d9f6512f81f8 100644 --- a/code/modules/implants/implant_types/compressed.dm +++ b/code/modules/implants/implant_types/compressed.dm @@ -8,27 +8,29 @@ var/obj/item/scanned /obj/item/implant/compressed/trigger(emote, mob/source) - if (src.scanned == null) - return 0 + if (!scanned) + return FALSE - if (emote == src.activation_emote) - to_chat(source, "The air glows as \the [src.scanned.name] uncompresses.") + if (emote == activation_emote) + to_chat(source, "The air glows as \the [scanned] uncompresses.") activate() /obj/item/implant/compressed/activate() - if(malfunction) return - var/turf/T = get_turf(src) + if(malfunction) + return + var/turf/our_turf = get_turf(src) if (imp_in) imp_in.put_in_hands(scanned) else - scanned.forceMove(T) + scanned.forceMove(our_turf) qdel(src) /obj/item/implant/compressed/implanted(mob/source) - src.activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch_v", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink") + activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch_v", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink") + var/activation_string = "can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate." if (source.mind) - source.StoreMemory("\A [src] can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", /decl/memory_options/system) - to_chat(source, "\The [src] can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.") + source.StoreMemory("\A [src] [activation_string]", /decl/memory_options/system) + to_chat(source, "\The [src] [activation_string].") return TRUE /obj/item/implanter/compressed @@ -36,56 +38,57 @@ icon = 'icons/obj/items/implant/compressed_implant.dmi' icon_state = "cimplanter1" desc = "The matter compressor safety is on." - var/safe = 1 imp = /obj/item/implant/compressed + var/const/SAFETY_OFF = 0 + var/const/SAFETY_ON = 1 + var/const/SAFETY_USED = 2 + var/safe = SAFETY_ON /obj/item/implanter/compressed/on_update_icon() . = ..() - if (imp) - var/obj/item/implant/compressed/c = imp - if(!c.scanned) - icon_state = "cimplanter1" - else - icon_state = "cimplanter2" + if (istype(imp, /obj/item/implant/compressed)) + var/obj/item/implant/compressed/compression_implant = imp + icon_state = compression_implant.scanned ? "cimplanter2" : "cimplanter1" else icon_state = "cimplanter0" /obj/item/implanter/compressed/use_on_mob(mob/living/target, mob/living/user, animate = TRUE) - var/obj/item/implant/compressed/c = imp - if(!istype(c) || c.scanned == null) + var/obj/item/implant/compressed/compression_implant = imp + if(!istype(compression_implant) || compression_implant.scanned == null) to_chat(user, SPAN_WARNING("Please compress an object with the implanter first.")) return TRUE return ..() -/obj/item/implanter/compressed/afterattack(obj/item/A, mob/user, proximity) +/obj/item/implanter/compressed/afterattack(obj/item/used_item, mob/user, proximity) if(!proximity) return - if(istype(A) && imp) - var/obj/item/implant/compressed/c = imp - if (c.scanned) - if (!A.storage) - to_chat(user, "Something is already compressed inside the implant!") - return - else if(safe) - if (!A.storage) - to_chat(user, "The matter compressor safeties prevent you from doing that.") - return - if(ishuman(A.loc)) - var/mob/living/human/H = A.loc - if(!H.try_unequip(A)) - return - else if(isobj(A.loc) && A.loc.storage) - A.loc.storage.remove_from_storage(user, A) - c.scanned = A - A.forceMove(src) //Store it inside - safe = 2 - desc = "It currently contains some matter." - update_icon() + if(!istype(imp, /obj/item/implant/compressed)) + to_chat(user, SPAN_WARNING("There is no compressed matter implant in \the [src]!")) + return + var/obj/item/implant/compressed/compression_implant = imp + if (compression_implant.scanned) + if (!used_item.storage) + to_chat(user, SPAN_WARNING("Something is already compressed inside the implant!")) + return + else if(safe >= SAFETY_ON) + if (!used_item.storage) + to_chat(user, SPAN_WARNING("The matter compressor safeties prevent you from doing that.")) + return + var/atom/used_item_loc = used_item.loc + var/mob/living/human/holder = used_item_loc + if(istype(holder) && !holder.try_unequip(used_item)) + return + if(used_item_loc.storage) + used_item_loc.storage.remove_from_storage(user, used_item) + compression_implant.scanned = used_item + used_item.forceMove(src) //Store it inside + safe = SAFETY_USED + desc = "It currently contains some matter." + update_icon() /obj/item/implanter/compressed/attack_self(var/mob/user) - if(!imp || safe == 2) + if(!imp || safe == SAFETY_USED) return ..() - safe = !safe - to_chat(user, "You [safe ? "enable" : "disable"] the matter compressor safety.") + to_chat(user, SPAN_NOTICE("You [safe ? "enable" : "disable"] the matter compressor safety.")) src.desc = "The matter compressor safety is [safe ? "on" : "off"]." \ No newline at end of file diff --git a/code/modules/implants/implant_types/death_alarm.dm b/code/modules/implants/implant_types/death_alarm.dm index f41e96f1f29d..8bbe9fa27513 100644 --- a/code/modules/implants/implant_types/death_alarm.dm +++ b/code/modules/implants/implant_types/death_alarm.dm @@ -2,8 +2,11 @@ name = "death alarm implant" desc = "An alarm which monitors host vital signs and transmits a radio message upon death." origin_tech = @'{"materials":1,"biotech":2,"programming":3}' - known = 1 + known = TRUE var/mobname = "John Doe" + var/const/DEATH_ALARM_CAUSE_EMP = "emp" + var/const/DEATH_ALARM_CAUSE_GIB = "gib" + var/const/DEATH_ALARM_CAUSE_DEATH = "death" /obj/item/implant/death_alarm/get_data() return {" @@ -21,22 +24,21 @@ return TRUE /obj/item/implant/death_alarm/Process() - if (!implanted) return - var/mob/M = imp_in + if (!implanted) + return + if(isnull(imp_in)) // If the mob got gibbed + activate(DEATH_ALARM_CAUSE_GIB) + else if(imp_in.stat == DEAD) + activate(DEATH_ALARM_CAUSE_DEATH) - if(isnull(M)) // If the mob got gibbed - activate(null) - else if(M.stat == DEAD) - activate("death") - -/obj/item/implant/death_alarm/activate(var/cause = "emp") - if(malfunction) return - var/mob/M = imp_in - var/area/location = get_area(M) - if (cause == "emp" && prob(50)) +/obj/item/implant/death_alarm/activate(var/cause = DEATH_ALARM_CAUSE_EMP) + if(malfunction) + return + var/area/location = get_area(imp_in) + if (cause == DEATH_ALARM_CAUSE_EMP && prob(50)) location = pick(teleportlocs) var/death_message = "[mobname] has died in [location.proper_name]!" - if(!cause) + if(cause == DEATH_ALARM_CAUSE_GIB) death_message = "[mobname] has died-zzzzt in-in-in..." STOP_PROCESSING(SSobj, src) do_telecomms_announcement(src, death_message, "[mobname]'s Death Alarm", list("Security", "Medical", "Command")) diff --git a/code/modules/implants/implant_types/explosive.dm b/code/modules/implants/implant_types/explosive.dm index e588e56009a8..c4d2919bd763 100644 --- a/code/modules/implants/implant_types/explosive.dm +++ b/code/modules/implants/implant_types/explosive.dm @@ -4,7 +4,7 @@ desc = "A military grade micro bio-explosive. Highly dangerous." icon_state = "implant_evil" origin_tech = @'{"materials":1,"biotech":2,"esoteric":3}' - hidden = 1 + hidden = TRUE var/elevel var/phrase var/code = 13 @@ -26,24 +26,24 @@ if(!malfunction) . += {"
Explosion yield mode:
- [elevel ? elevel : "NONE SET"]
+ [elevel || "NONE SET"]
Activation phrase:
- [phrase ? phrase : "NONE SET"]
+ [phrase || "NONE SET"]
Frequency:
- - - [format_frequency(src.frequency)] + [format_frequency(frequency)] + +
Code:
- - - [src.code] + [code] + +
Tampering warning message:
This will be broadcasted on radio if implant is exposed during surgery.
- [warning_message ? warning_message : "NONE SET"] + [warning_message || "NONE SET"] "} /obj/item/implant/explosive/Initialize() @@ -52,12 +52,12 @@ set_frequency(frequency) /obj/item/implant/explosive/Topic(href, href_list) - ..() +/obj/item/implant/explosive/OnTopic(mob/user, href_list, datum/topic_state/state) if (href_list["freq"]) var/new_frequency = frequency + text2num(href_list["freq"]) new_frequency = sanitize_frequency(new_frequency, RADIO_LOW_FREQ, RADIO_HIGH_FREQ) set_frequency(new_frequency) - interact(usr) + return TOPIC_REFRESH if (href_list["code"]) var/adj = text2num(href_list["code"]) if(!adj) @@ -65,22 +65,22 @@ else code += adj code = clamp(code,1,100) - interact(usr) + return TOPIC_REFRESH if (href_list["mode"]) var/mod = input("Set explosion mode", "Explosion mode") as null|anything in list("Localized Limb", "Destroy Body", "Full Explosion") if(mod) elevel = mod - interact(usr) + return TOPIC_REFRESH if (href_list["msg"]) var/msg = input("Set tampering message, or leave blank for no broadcasting.", "Anti-tampering", warning_message) as text|null if(msg) warning_message = msg - interact(usr) + return TOPIC_REFRESH if (href_list["phrase"]) var/talk = input("Set activation phrase", "Audio activation", phrase) as text|null if(talk) phrase = sanitize_phrase(talk) - interact(usr) + return TOPIC_REFRESH /obj/item/implant/explosive/receive_signal(datum/signal/signal) if(signal && signal.encryption == code) @@ -113,35 +113,36 @@ if (malfunction) return - var/turf/T = get_turf(src) - if(T) - T.hotspot_expose(3500,125) + var/turf/our_turf = get_turf(src) + if(our_turf) + our_turf.hotspot_expose(3500, CELL_VOLUME/20) // expose roughly 1/20th of a cell to 3500K heat - playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3) + playsound(our_turf, 'sound/items/countdown.ogg', 75, 1, -3) if(ismob(imp_in)) - imp_in.audible_message("Something beeps inside [imp_in][part ? "'s [part.name]" : ""]!") + imp_in.audible_message(SPAN_WARNING("Something beeps inside [imp_in][part ? "'s [part.name]" : ""]!")) log_and_message_admins("Explosive implant triggered in [imp_in] ([imp_in.key]). (JMP) ") else - audible_message("[src] beeps omniously!") - log_and_message_admins("Explosive implant triggered in [T.loc]. (JMP) ") + audible_message(SPAN_WARNING("[src] beeps omniously!")) + log_and_message_admins("Explosive implant triggered in [our_turf.loc]. (JMP) ") if(!elevel) elevel = "Full Explosion" switch(elevel) if ("Localized Limb") - if (part) - if (istype(part,/obj/item/organ/external/chest) || \ - istype(part,/obj/item/organ/external/groin)) + switch(part?.organ_tag) + if(BP_CHEST, BP_GROIN) part.take_damage(60, inflicter = "Explosion") + if(null) + pass() else part.dismember(0,DISMEMBER_METHOD_BLUNT) - explosion(T, -1, -1, 2, 3) + explosion(our_turf, -1, -1, 2, 3) if ("Destroy Body") - explosion(T, -1, 0, 1, 6) + explosion(our_turf, -1, 0, 1, 6) if(ismob(imp_in)) imp_in.gib() if ("Full Explosion") - explosion(T, 0, 1, 3, 6) + explosion(our_turf, 0, 1, 3, 6) if(ismob(imp_in)) imp_in.gib() qdel(src) diff --git a/code/modules/implants/implant_types/freedom.dm b/code/modules/implants/implant_types/freedom.dm index 2ec9c0890aed..3fe600c5108d 100644 --- a/code/modules/implants/implant_types/freedom.dm +++ b/code/modules/implants/implant_types/freedom.dm @@ -5,7 +5,7 @@ desc = "Use this to escape from those evil Red Shirts." origin_tech = @'{"materials":1,"biotech":2,"esoteric":2}' implant_color = "r" - hidden = 1 + hidden = TRUE var/activation_emote var/uses @@ -34,7 +34,8 @@ activate() /obj/item/implant/freedom/activate() - if(uses < 1 || malfunction) return 0 + if(uses < 1 || malfunction) + return FALSE if(remove_cuffs_and_unbuckle(imp_in)) uses-- to_chat(imp_in, "You feel a faint click.") @@ -42,16 +43,18 @@ /obj/item/implant/freedom/proc/remove_cuffs_and_unbuckle(mob/living/user) var/obj/cuffs = user.get_equipped_item(slot_handcuffed_str) if(!cuffs) - return 0 - . = user.try_unequip(cuffs) - if(. && user.buckled && user.buckled.buckle_require_restraints) + return FALSE + if(!user.try_unequip(cuffs)) + return FALSE + if(user.buckled && user.buckled.buckle_require_restraints) user.buckled.unbuckle_mob() - return + return TRUE /obj/item/implant/freedom/implanted(mob/living/source) src.activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch_v", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink") - source.StoreMemory("\A [src] can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", /decl/memory_options/system) - to_chat(source, "\The [src] can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.") + var/activation_string = "can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate." + source.StoreMemory("\A [src] [activation_string]", /decl/memory_options/system) + to_chat(source, "\The [src] [activation_string]") return TRUE /obj/item/implanter/freedom diff --git a/code/modules/implants/implant_types/imprinting.dm b/code/modules/implants/implant_types/imprinting.dm index f493ae39ffa7..5a8305087572 100644 --- a/code/modules/implants/implant_types/imprinting.dm +++ b/code/modules/implants/implant_types/imprinting.dm @@ -2,9 +2,9 @@ name = "imprinting implant" desc = "Latest word in training your peons." origin_tech = @'{"materials":1,"biotech":2,"programming":3}' - hidden = 1 + hidden = TRUE var/list/instructions = list("Do your job.", "Respect your superiors.", "Wash you hands after using the toilet.") - var/brainwashing = 0 + var/brainwashing = FALSE /obj/item/implant/imprinting/get_data() . = {" @@ -18,56 +18,58 @@ It is HIGLY ILLEGAL and the seller does NOT endorse use of this device in such way. Any amount of "Mind-Breaker"(TM) present in bloodstream will trigger this side-effect.
"} . += "
Instructions:
" - for(var/i = 1 to instructions.len) + for(var/i = 1 to length(instructions)) . += "- [instructions[i]] Edit Remove
" . += "Add" -/obj/item/implant/imprinting/Topic(href, href_list) - ..() +/obj/item/implant/imprinting/OnTopic(mob/user, href_list, datum/topic_state/state) if (href_list["add"]) var/mod = sanitize(input("Add an instruction", "Instructions") as text|null) if(mod) instructions += mod - interact(usr) + return TOPIC_REFRESH + return TOPIC_HANDLED if (href_list["edit"]) var/idx = text2num(href_list["edit"]) var/mod = sanitize(input("Edit the instruction", "Instruction Editing", instructions[idx]) as text|null) if(mod) instructions[idx] = mod - interact(usr) + return TOPIC_REFRESH + return TOPIC_HANDLED if (href_list["del"]) instructions -= instructions[text2num(href_list["del"])] - interact(usr) + return TOPIC_REFRESH + return TOPIC_NOACTION -/obj/item/implant/imprinting/implanted(mob/M) - var/mob/living/human/H = M - if(!istype(H)) +/obj/item/implant/imprinting/implanted(mob/living/victim) + var/mob/living/human/human_victim = victim + if(!istype(human_victim)) return FALSE - if(H.reagents.has_reagent(/decl/material/liquid/hallucinogenics)) - brainwashing = 1 + if(human_victim.reagents.has_reagent(/decl/material/liquid/hallucinogenics)) + brainwashing = TRUE var/msg = get_instructions() - to_chat(M, msg) - if(M.mind) - M.StoreMemory(msg, /decl/memory_options/system) + to_chat(human_victim, msg) + if(human_victim.mind) + human_victim.StoreMemory(msg, /decl/memory_options/system) if(brainwashing) - log_and_message_admins("was implanted with a brainwashing implant holding following laws: [jointext(instructions, ";")].", M) - addtimer(CALLBACK(src,PROC_REF(activate)),3000,(TIMER_UNIQUE|TIMER_OVERRIDE)) + log_and_message_admins("was implanted with a brainwashing implant holding the following laws: [jointext(instructions, ";")].", human_victim) + addtimer(CALLBACK(src,PROC_REF(activate)), 5 MINUTES, (TIMER_UNIQUE|TIMER_OVERRIDE)) return TRUE /obj/item/implant/imprinting/proc/get_instructions() . = list() if(brainwashing) - . += "The fog in your head clears, and you remember some important things. You hold following things as deep convictions, almost like synthetics' laws:
" + . += SPAN_DANGER("The fog in your head clears, and you remember some important things. You hold the following as deep convictions, almost like synthetics' laws:") else - . += "You hear an annoying voice in the back of your head. The things it keeps reminding you of:
" + . += SPAN_NOTICE("You hear an annoying voice in the back of your head. The things it keeps reminding you of are:") for(var/thing in instructions) - . += "- [thing]
" - . = JOINTEXT(.) + . += "- [thing]" + . = jointext(., "
") /obj/item/implant/imprinting/disable(time) . = ..() if(. && brainwashing)//add deactivate and reactivate messages? - to_chat(imp_in,"A wave of nausea comes over you.
You are no longer so sure of those beliefs you've had...") + show_deactivate_message() /obj/item/implant/imprinting/restore() . = ..() @@ -76,18 +78,19 @@ activate() /obj/item/implant/imprinting/activate() - if(malfunction || !implanted || imp_in) return + if(malfunction || !implanted || imp_in) + return var/instruction = pick(instructions) if(brainwashing) - instruction = "You recall one of your beliefs: \"[instruction]\"" + instruction = SPAN_WARNING("You recall one of your beliefs: \"[instruction]\"") else - instruction = "You remember suddenly: \"[instruction]\"" + instruction = SPAN_NOTICE("You remember suddenly: \"[instruction]\"") to_chat(imp_in, instruction) - addtimer(CALLBACK(src,PROC_REF(activate)),3000,(TIMER_UNIQUE|TIMER_OVERRIDE)) + addtimer(CALLBACK(src, PROC_REF(activate)), 5 MINUTES, (TIMER_UNIQUE|TIMER_OVERRIDE)) /obj/item/implant/imprinting/removed() if(brainwashing && !malfunction) - to_chat(imp_in,"A wave of nausea comes over you.
You are no longer so sure of those beliefs you've had...") + show_deactivate_message() ..() /obj/item/implant/imprinting/emp_act(severity) @@ -95,22 +98,26 @@ if(prob(power * 15)) meltdown() else if(prob(power * 40)) - disable(rand(power*100,power*1000))//a few precious seconds of freedom + disable(rand(power*10 SECONDS,power*100 SECONDS))//a few precious seconds of freedom + +/obj/item/implant/imprinting/proc/show_deactivate_message() + to_chat(imp_in, SPAN_WARNING("A wave of nausea comes over you.")) + to_chat(imp_in, SPAN_GOOD("You are no longer so sure of those beliefs you've had...")) /obj/item/implant/imprinting/meltdown() if(brainwashing && !malfunction)//if it's already broken don't send the message again - to_chat(imp_in,"A wave of nausea comes over you.
You are no longer so sure of those beliefs you've had...") + show_deactivate_message() . = ..() -/obj/item/implant/imprinting/can_implant(mob/M, mob/user, target_zone) - var/mob/living/human/H = M - if(istype(H)) - var/obj/item/organ/internal/B = GET_INTERNAL_ORGAN(H, BP_BRAIN) - if(!B || H.isSynthetic()) - to_chat(user, "\The [M] cannot be imprinted.") +/obj/item/implant/imprinting/can_implant(mob/living/victim, mob/living/user, target_zone) + var/mob/living/human/human_victim = victim + if(istype(human_victim)) + var/obj/item/organ/internal/victim_brain = GET_INTERNAL_ORGAN(human_victim, BP_BRAIN) + if(!victim_brain || human_victim.isSynthetic()) + to_chat(user, SPAN_WARNING("\The [human_victim] cannot be imprinted.")) return FALSE - if(!(B.parent_organ == check_zone(target_zone, H))) - to_chat(user, "\The [src] must be implanted in [GET_EXTERNAL_ORGAN(H, B.parent_organ)].") + if(!(victim_brain.parent_organ == check_zone(target_zone, human_victim))) + to_chat(user, SPAN_WARNING("\The [src] must be implanted in [GET_EXTERNAL_ORGAN(human_victim, victim_brain.parent_organ)].")) return FALSE return TRUE diff --git a/code/modules/implants/implant_types/loyalty.dm b/code/modules/implants/implant_types/loyalty.dm index f7cc12b1abb0..e373a0e53abd 100644 --- a/code/modules/implants/implant_types/loyalty.dm +++ b/code/modules/implants/implant_types/loyalty.dm @@ -1,8 +1,8 @@ /obj/item/implant/loyalty name = "loyalty implant" - desc = "Makes you loyal or such." + desc = "Contains a small pod of nanobots that manipulate the host's mental functions. Personnel injected with this device tend to be much more loyal to the company." origin_tech = @'{"materials":1,"biotech":2,"esoteric":3}' - known = 1 + known = TRUE // identifiable by scanners /obj/item/implant/loyalty/get_data() return {" @@ -16,19 +16,20 @@ Special Features: Will prevent and cure most forms of brainwashing.
Integrity: Implant will last so long as the nanobots are inside the bloodstream."} -/obj/item/implant/loyalty/implanted(mob/M) - if(!ishuman(M)) +/obj/item/implant/loyalty/implanted(mob/living/victim) + if(!ishuman(victim)) return FALSE - var/decl/special_role/antag_data = GET_DECL(M.mind?.assigned_special_role) + var/decl/special_role/antag_data = GET_DECL(victim.mind?.assigned_special_role) if(istype(antag_data) && (antag_data.flags & ANTAG_IMPLANT_IMMUNE)) - M.visible_message( - "\The [M] seems to resist the implant!", - "You feel the corporate tendrils of [global.using_map.company_name] try to invade your mind!" + victim.visible_message( + "\The [victim] seems to resist the implant!", + SPAN_WARNING("You feel the corporate tendrils of [global.using_map.company_name] try to invade your mind!") ) return FALSE else - clear_antag_roles(M.mind, 1) - to_chat(M, SPAN_NOTICE("You feel a surge of loyalty towards [global.using_map.company_name].")) + clear_antag_roles(victim.mind, implanted = TRUE) + to_chat(victim, SPAN_NOTICE("You feel a surge of loyalty towards [global.using_map.company_name].")) + BITSET(victim.hud_updateflag, IMPLOYAL_HUD) return TRUE /obj/item/implanter/loyalty diff --git a/code/modules/implants/implant_types/tracking.dm b/code/modules/implants/implant_types/tracking.dm index 0b317737c4b3..eac7218ef8a8 100644 --- a/code/modules/implants/implant_types/tracking.dm +++ b/code/modules/implants/implant_types/tracking.dm @@ -4,7 +4,7 @@ var/global/list/tracking_implants = list() name = "tracking implant" desc = "Track with this." origin_tech = @'{"materials":1,"biotech":2,"wormholes":2}' - known = 1 + known = TRUE var/id = 1 /obj/item/implant/tracking/Initialize(ml, material_key) @@ -36,11 +36,11 @@ var/global/list/tracking_implants = list() + +
"} -/obj/item/implant/tracking/Topic(href, href_list) - ..() +/obj/item/implant/tracking/OnTopic(mob/user, href_list, datum/topic_state/state) if (href_list["tracking_id"]) id = clamp(id+text2num(href_list["tracking_id"]), 1, 100) - interact(usr) + return TOPIC_REFRESH + return TOPIC_NOACTION /obj/item/implant/tracking/islegal() return TRUE @@ -50,7 +50,7 @@ var/global/list/tracking_implants = list() if(prob(power * 15)) meltdown() else if(prob(power * 40)) - disable(rand(power*500,power*5000))//adds in extra time because this is the only other way to sabotage it + disable(rand(power*50 SECONDS,power*500 SECONDS))//adds in extra time because this is the only other way to sabotage it /obj/item/implantcase/tracking name = "glass case - 'tracking'" diff --git a/code/modules/implants/implant_types/translator.dm b/code/modules/implants/implant_types/translator.dm index f4c540ddb7d4..0dbcc41231d8 100644 --- a/code/modules/implants/implant_types/translator.dm +++ b/code/modules/implants/implant_types/translator.dm @@ -4,7 +4,7 @@ desc = "A small implant with a microphone on it." icon_state = "implant_evil" origin_tech = @'{"materials":1,"biotech":2,"esoteric":3}' - hidden = 1 + hidden = TRUE var/list/languages = list() var/learning_threshold = 20 //need to hear language spoken this many times to learn it var/max_languages = 5 @@ -16,15 +16,13 @@ . = ..() global.listening_objects += src -/obj/item/implant/translator/hear_talk(mob/M, msg, verb, decl/language/speaking) +/obj/item/implant/translator/hear_talk(mob/speaker, msg, verb, decl/language/speaking) if(!imp_in) return if(length(languages) == max_languages) return - if(!languages[speaking.name]) - languages[speaking.name] = 1 - languages[speaking.name] = languages[speaking.name] + 1 - if(!imp_in.say_understands(M, speaking) && languages[speaking.name] > learning_threshold) + languages[speaking.name] += 1 + if(!imp_in.say_understands(speaker, speaking) && languages[speaking.name] > learning_threshold) to_chat(imp_in, SPAN_NOTICE("You feel like you can understand [speaking.name] now...")) imp_in.add_language(speaking.type) diff --git a/code/modules/implants/implant_types/uplink.dm b/code/modules/implants/implant_types/uplink.dm index 27e733c583aa..40574a97529f 100644 --- a/code/modules/implants/implant_types/uplink.dm +++ b/code/modules/implants/implant_types/uplink.dm @@ -2,7 +2,7 @@ name = "uplink implant" desc = "Summon things." origin_tech = @'{"materials":1,"biotech":2,"esoteric":3}' - hidden = 1 + hidden = TRUE var/activation_emote /obj/item/implant/uplink/Initialize(mapload, var/amount) @@ -13,8 +13,9 @@ /obj/item/implant/uplink/implanted(mob/source) var/emote_options = list("blink", "blink_r", "eyebrow", "chuckle", "twitch_v", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink") activation_emote = source.client ? (input(source, "Choose activation emote:", "Uplink Implant Setup") in emote_options) : emote_options[1] - source.StoreMemory("\A [src] can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", /decl/memory_options/system) - to_chat(source, "\The [src] can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.") + var/activation_string = "can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate." + source.StoreMemory("\A [src] [activation_string]", /decl/memory_options/system) + to_chat(source, "\The [src] [activation_string]") hidden_uplink.uplink_owner = source.mind return TRUE diff --git a/code/modules/implants/implantcase.dm b/code/modules/implants/implantcase.dm index 9f754b9c8685..2714c948265f 100644 --- a/code/modules/implants/implantcase.dm +++ b/code/modules/implants/implantcase.dm @@ -42,15 +42,16 @@ // TODO: the name stuff here probably doesn't work, this needs an update_name override /obj/item/implantcase/attackby(obj/item/used_item, mob/user) if (IS_PEN(used_item)) - var/t = input(user, "What would you like the label to be?", src.name, null) + var/label = input(user, "What would you like the label to be?", src.name, null) + // As input() blocks, we need to do some sanity checks if (user.get_active_held_item() != used_item) return TRUE - if((!in_range(src, usr) && loc != user)) + if(!CanPhysicallyInteract(user)) return TRUE - t = sanitize_safe(t, MAX_NAME_LEN) - if(t) - SetName("glass case - '[t]'") - desc = "A case containing \a [t] implant." + label = sanitize_safe(label, MAX_NAME_LEN) + if(label) + SetName("glass case - '[label]'") + desc = "A case containing \a [label] implant." else SetName(initial(name)) desc = "A case containing an implant." @@ -72,7 +73,7 @@ M.update_icon() return TRUE else if (istype(used_item, /obj/item/implant) && user.try_unequip(used_item, src)) - to_chat(usr, "You slide \the [used_item] into \the [src].") + to_chat(user, SPAN_NOTICE("You slide \the [used_item] into \the [src].")) imp = used_item update_description() update_icon() diff --git a/code/modules/implants/implanter.dm b/code/modules/implants/implanter.dm index 409c2cb362a3..6ca6d7a546b0 100644 --- a/code/modules/implants/implanter.dm +++ b/code/modules/implants/implanter.dm @@ -75,8 +75,8 @@ user.do_attack_animation(target) var/target_zone = user.get_target_zone() if(imp.can_implant(target, user, target_zone)) - var/imp_name = imp.name - if(do_after(user, 50, target) && imp.implant_in_mob(target, target_zone)) + var/imp_name = imp.name // cache this in case implanting it changes its name + if(do_after(user, 5 SECONDS, target) && imp.implant_in_mob(target, user, target_zone)) user.visible_message(SPAN_NOTICE("\The [target] has been implanted by \the [user].")) admin_attack_log(user, target, "Implanted using \the [src] ([imp_name])", "Implanted with \the [src] ([imp_name])", "used an implanter, \the [src] ([imp_name]), on") imp = null diff --git a/code/modules/implants/implantpad.dm b/code/modules/implants/implantpad.dm index 4e6f78b10013..db7bb8fbc41f 100644 --- a/code/modules/implants/implantpad.dm +++ b/code/modules/implants/implantpad.dm @@ -13,7 +13,7 @@ add_overlay("[icon_state]-imp") /obj/item/implantpad/attack_hand(mob/user) - if(!imp || (src in user.get_held_items()) || !user.check_dexterity(DEXTERITY_HOLD_ITEM, TRUE)) + if(!imp || !(src in user.get_held_items()) || !user.check_dexterity(DEXTERITY_HOLD_ITEM, TRUE)) return ..() user.put_in_active_hand(imp) imp.add_fingerprint(user) @@ -24,28 +24,28 @@ /obj/item/implantpad/attackby(obj/item/used_item, mob/user) if(istype(used_item, /obj/item/implantcase)) - var/obj/item/implantcase/C = used_item - if(!imp && C.imp) - C.imp.forceMove(src) - imp = C.imp - C.imp = null - else if (imp && !C.imp) - imp.forceMove(C) - C.imp = imp + var/obj/item/implantcase/case = used_item + if(!imp && case.imp) + case.imp.forceMove(src) + imp = case.imp + case.imp = null + else if (imp && !case.imp) + imp.forceMove(case) + case.imp = imp imp = null - C.update_icon() + case.update_icon() . = TRUE else if(istype(used_item, /obj/item/implanter)) - var/obj/item/implanter/C = used_item - if(!imp && C.imp) - C.imp.forceMove(src) - imp = C.imp - C.imp = null - else if (imp && !C.imp) - imp.forceMove(C) - C.imp = imp + var/obj/item/implanter/implanter = used_item + if(!imp && implanter.imp) + implanter.imp.forceMove(src) + imp = implanter.imp + implanter.imp = null + else if (imp && !implanter.imp) + imp.forceMove(implanter) + implanter.imp = imp imp = null - C.update_icon() + implanter.update_icon() . = TRUE else if(istype(used_item, /obj/item/implant) && user.try_unequip(used_item, src)) imp = used_item @@ -59,4 +59,4 @@ if (imp) imp.interact(user) else - to_chat(user,"There's no implant loaded in \the [src].") \ No newline at end of file + to_chat(user,SPAN_WARNING("There's no implant loaded in \the [src].")) \ No newline at end of file diff --git a/code/modules/mob/living/human/human.dm b/code/modules/mob/living/human/human.dm index b8c583973e6b..14fd42f76b5c 100644 --- a/code/modules/mob/living/human/human.dm +++ b/code/modules/mob/living/human/human.dm @@ -100,24 +100,25 @@ cell_status = "[rig.cell.charge]/[rig.cell.maxcharge]" stat(null, "Hardsuit charge: [cell_status]") -/mob/living/human/proc/implant_loyalty(mob/living/human/M, override = FALSE) // Won't override by default. - if(!get_config_value(/decl/config/toggle/use_loyalty_implants) && !override) return // Nuh-uh. - - var/obj/item/implant/loyalty/L = new/obj/item/implant/loyalty(M) - L.imp_in = M - L.implanted = 1 - var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(M, BP_HEAD) - LAZYDISTINCTADD(affected.implants, L) - L.part = affected - L.implanted(src) - -/mob/living/human/proc/is_loyalty_implanted(mob/living/human/M) - for(var/L in M.contents) - if(istype(L, /obj/item/implant/loyalty)) - for(var/obj/item/organ/external/O in M.get_external_organs()) - if(L in O.implants) - return 1 - return 0 +/mob/living/human/proc/implant_loyalty(mob/living/human/victim, override = FALSE) // Won't override by default. + if(!get_config_value(/decl/config/toggle/use_loyalty_implants) && !override) + return // Nuh-uh. + + var/obj/item/implant/loyalty/loyalty_implant = new/obj/item/implant/loyalty(victim) + loyalty_implant.imp_in = victim + loyalty_implant.implanted = TRUE + var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(victim, BP_HEAD) + LAZYDISTINCTADD(affected.implants, loyalty_implant) + loyalty_implant.part = affected + loyalty_implant.implanted(src) + +/mob/living/human/proc/is_loyalty_implanted(mob/living/human/victim) + for(var/obj/item/implant/loyalty/loyalty_implant in victim.contents) + // Make sure the implant is actually implanted in the expected part, + // and that the part is in the victim (should always be, but just in case) + if(victim.get_organ(loyalty_implant.part?.organ_tag) == loyalty_implant.part) + return TRUE + return FALSE /mob/living/human/get_additional_stripping_options() . = ..() diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 5e738a6f7c98..36f1ba370c4c 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -440,7 +440,7 @@ /mob/living/silicon/get_dexterity(var/silent) return dexterity -/mob/living/silicon/robot/remove_implant(var/obj/item/implant, var/surgical_removal = FALSE, obj/item/organ/external/affected) +/mob/living/silicon/robot/remove_implant(obj/item/implant, surgical_removal = FALSE, obj/item/organ/external/affected) . = ..() if(.) adjustBruteLoss(5, do_update_health = FALSE) diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm index a453faec0031..d90193ec82a3 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -16,8 +16,8 @@ /decl/surgery_step/cavity/fail_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - user.visible_message("[user]'s hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!", \ - "Your hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!") + user.visible_message(SPAN_WARNING("[user]'s hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!"), \ + SPAN_WARNING("Your hand slips, scraping around inside [target]'s [affected.name] with \the [tool]!")) affected.take_damage(20, damage_flags = (DAM_SHARP|DAM_EDGE), inflicter = tool) ..() @@ -52,8 +52,8 @@ /decl/surgery_step/cavity/make_space/end_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - user.visible_message("[user] makes some space inside [target]'s \the [affected.cavity_name] with \the [tool].", \ - "You make some space inside [target]'s \the [affected.cavity_name] with \the [tool]." ) + user.visible_message(SPAN_NOTICE("[user] makes some space inside [target]'s \the [affected.cavity_name] with \the [tool]."), \ + SPAN_NOTICE("You make some space inside [target]'s \the [affected.cavity_name] with \the [tool].") ) ..() ////////////////////////////////////////////////////////////////// @@ -83,8 +83,8 @@ /decl/surgery_step/cavity/close_space/end_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - user.visible_message("[user] mends [target]'s \the [affected.cavity_name] walls with \the [tool].", \ - "You mend [target]'s \the [affected.cavity_name] walls with \the [tool]." ) + user.visible_message(SPAN_NOTICE("[user] mends [target]'s \the [affected.cavity_name] walls with \the [tool]."), \ + SPAN_NOTICE("You mend [target]'s \the [affected.cavity_name] walls with \the [tool].") ) affected.cavity = FALSE ..() @@ -140,10 +140,10 @@ var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) if(!user.try_unequip(tool, affected)) return - user.visible_message("[user] puts \the [tool] inside [target]'s \the [affected.cavity_name].", \ - "You put \the [tool] inside [target]'s \the [affected.cavity_name]." ) + user.visible_message(SPAN_NOTICE("[user] puts \the [tool] inside [target]'s \the [affected.cavity_name]."), \ + SPAN_NOTICE("You put \the [tool] inside [target]'s \the [affected.cavity_name].") ) if (tool.w_class > affected.cavity_max_w_class/2 && prob(50) && !BP_IS_PROSTHETIC(affected) && affected.sever_artery()) - to_chat(user, "You tear some blood vessels trying to fit such a big object in this cavity.") + to_chat(user, SPAN_WARNING("You tear some blood vessels trying to fit such a big object in this cavity.")) affected.owner.custom_pain("You feel something rip in your [affected.name]!", 1,affecting = affected) LAZYDISTINCTADD(affected.implants, tool) affected.cavity = 0 @@ -180,11 +180,12 @@ /decl/surgery_step/cavity/implant_removal/end_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - var/exposed = 0 + // Whether or not we can access implants/items inside the organ, or just ones embedded in wounds. + var/exposed = FALSE if(affected.how_open() >= (affected.encased ? SURGERY_ENCASED : SURGERY_RETRACTED)) - exposed = 1 - if(BP_IS_PROSTHETIC(affected) && affected.hatch_state == HATCH_OPENED) - exposed = 1 + exposed = TRUE + else if(BP_IS_PROSTHETIC(affected) && affected.hatch_state == HATCH_OPENED) + exposed = TRUE var/find_prob = 0 var/list/loot = list() @@ -203,26 +204,26 @@ if(istype(obj,/obj/item/implant)) var/obj/item/implant/imp = obj if (imp.islegal()) - find_prob +=60 + find_prob += 60 else - find_prob +=40 + find_prob += 40 else - find_prob +=50 + find_prob += 50 if (prob(find_prob)) - user.visible_message("[user] takes something out of incision on [target]'s [affected.name] with \the [tool].", \ - "You take \the [obj] out of incision on \the [target]'s [affected.name] with \the [tool]." ) + user.visible_message(SPAN_NOTICE("[user] takes something out of the incision on [target]'s [affected.name] with \the [tool]."), \ + SPAN_NOTICE("You take \the [obj] out of the incision on \the [target]'s [affected.name] with \the [tool].") ) target.remove_implant(obj, TRUE, affected) BITSET(target.hud_updateflag, IMPLOYAL_HUD) ..() else - user.visible_message("[user] removes \the [tool] from [target]'s [affected.name].", \ - "There's something inside [target]'s [affected.name], but you just missed it this time." ) - playsound(target.loc, "rustle", 15, 1) + user.visible_message(SPAN_NOTICE("[user] removes \the [tool] from [target]'s [affected.name]."), \ + SPAN_NOTICE("There's something inside [target]'s [affected.name], but you just missed it this time.") ) + playsound(target.loc, "rustle", 15, TRUE) else - user.visible_message("[user] could not find anything inside [target]'s [affected.name], and pulls \the [tool] out.", \ - "You could not find anything inside [target]'s [affected.name]." ) - playsound(target.loc, "rustle", 15, 1) + user.visible_message(SPAN_NOTICE("[user] could not find anything inside [target]'s [affected.name], and pulls \the [tool] out."), \ + SPAN_NOTICE("You could not find anything inside [target]'s [affected.name].") ) + playsound(target.loc, "rustle", 15, TRUE) /decl/surgery_step/cavity/implant_removal/fail_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) @@ -232,8 +233,7 @@ var/fail_prob = 10 fail_prob += 100 - tool_quality(tool) if (prob(fail_prob)) - user.visible_message("Something beeps inside [target]'s [affected.name]!") - playsound(imp.loc, 'sound/items/countdown.ogg', 75, 1, -3) - spawn(25) - imp.activate() + user.visible_message(SPAN_WARNING("Something beeps inside [target]'s [affected.name]!")) + playsound(imp.loc, 'sound/items/countdown.ogg', 75, TRUE, -3) + addtimer(CALLBACK(imp, TYPE_PROC_REF(/obj/item/implant, activate)), 2.5 SECONDS) diff --git a/mods/content/pheromones/pheromone_mob.dm b/mods/content/pheromones/pheromone_mob.dm index fef81e3e234b..ad1efceb03b8 100644 --- a/mods/content/pheromones/pheromone_mob.dm +++ b/mods/content/pheromones/pheromone_mob.dm @@ -15,7 +15,7 @@ if(istype(gland) && !gland.is_broken()) return TRUE var/obj/item/implant/pheromone/imp = locate() in get_organ(BP_HEAD) - if(imp && imp.implanted && !imp.malfunction) + if(imp?.implanted && !imp.malfunction) return TRUE return FALSE diff --git a/mods/content/psionics/items/foundation_implanter.dm b/mods/content/psionics/items/foundation_implanter.dm index a05e4b57fc86..4fdbc478749f 100644 --- a/mods/content/psionics/items/foundation_implanter.dm +++ b/mods/content/psionics/items/foundation_implanter.dm @@ -4,13 +4,14 @@ /obj/item/implanter/psi/attack_self(var/mob/user) var/choice = input("Select a new implant mode.", "Psi Dampener") as null|anything in list(PSI_IMPLANT_AUTOMATIC, PSI_IMPLANT_SHOCK, PSI_IMPLANT_WARN, PSI_IMPLANT_LOG, PSI_IMPLANT_DISABLED) - if(!choice || user != loc) return + if(!choice || user != loc) + return var/obj/item/implant/psi_control/implant = imp if(!istype(implant)) - to_chat(user, "The implanter reports there is no compatible implant loaded.") + to_chat(user, SPAN_WARNING("The implanter reports there is no compatible implant loaded.")) return implant.psi_mode = choice - to_chat(user, "You set \the [src] to configure implants with the '[implant.psi_mode]' setting.") + to_chat(user, SPAN_NOTICE("You set \the [src] to configure implants with the '[implant.psi_mode]' setting.")) /obj/item/implanter/psi/Initialize() . = ..() diff --git a/mods/content/psionics/machines/psimonitor.dm b/mods/content/psionics/machines/psimonitor.dm index 600966267172..31855efdb533 100644 --- a/mods/content/psionics/machines/psimonitor.dm +++ b/mods/content/psionics/machines/psimonitor.dm @@ -25,7 +25,7 @@ emagged = TRUE remaining_charges-- req_access.Cut() - to_chat(user, "You short out the access protocols.") + to_chat(user, SPAN_NOTICE("You short out the access protocols.")) return TRUE return FALSE @@ -37,7 +37,7 @@ if(href_list["login"]) var/obj/item/card/id/ID = user.GetIdCard() if(!ID || !allowed(user)) - to_chat(user, "Access denied.") + to_chat(user, SPAN_WARNING("Access denied.")) return TOPIC_HANDLED else authorized = "[ID.registered_name] ([ID.assignment])" diff --git a/mods/content/xenobiology/slime/items.dm b/mods/content/xenobiology/slime/items.dm index 6c175cc88f5d..769f8c631d61 100644 --- a/mods/content/xenobiology/slime/items.dm +++ b/mods/content/xenobiology/slime/items.dm @@ -20,10 +20,10 @@ /obj/item/slime_extract/attackby(obj/item/used_item, mob/user) if(istype(used_item, /obj/item/slime_extract_enhancer)) if(enhanced == 1) - to_chat(user, " This extract has already been enhanced!") + to_chat(user, SPAN_WARNING("This extract has already been enhanced!")) return ..() if(Uses == 0) - to_chat(user, " You can't enhance a used extract!") + to_chat(user, SPAN_WARNING("You can't enhance a used extract!")) return ..() to_chat(user, "You apply the enhancer. It now has triple the amount of uses.") Uses = 3 @@ -103,7 +103,7 @@ G.key = ghost.key var/obj/item/implant/translator/natural/I = new() - I.implant_in_mob(G, BP_HEAD) + I.implant_in_mob(G, user, BP_HEAD) if (user.languages.len) var/decl/language/lang = user.languages[1] G.add_language(lang.type) From de3e782dfca76b6e4478c880427d23b399c93740 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 26 Sep 2025 14:23:48 -0400 Subject: [PATCH 15/36] Replace spawns in effect trail with timers and waitfor=FALSE --- code/game/objects/effects/effect_system.dm | 49 +++++++++++----------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index 3b5ef1fd60b7..52c615b4daeb 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -385,31 +385,30 @@ steam.start() -- spawns the effect /datum/effect/effect/system/trail/start() - if(!src.on) - src.on = 1 - src.processing = 1 - if(src.processing) - src.processing = 0 - spawn(0) - var/turf/T = get_turf(src.holder) - if(T != src.oldposition) - if(is_type_in_list(T, specific_turfs) && (!max_number || number < max_number)) - var/obj/effect/effect/trail = new trail_type(oldposition) - src.oldposition = T - effect(trail) - number++ - spawn( duration_of_effect ) - number-- - qdel(trail) - spawn(2) - if(src.on) - src.processing = 1 - src.start() - else - spawn(2) - if(src.on) - src.processing = 1 - src.start() + set waitfor = FALSE + if(!on) + on = TRUE + processing = TRUE + if(processing) + processing = FALSE + var/turf/our_turf = get_turf(holder) + if(our_turf != oldposition) + if(is_type_in_list(our_turf, specific_turfs) && (!max_number || number < max_number)) + var/obj/effect/effect/trail = new trail_type(oldposition) + oldposition = our_turf + effect(trail) + number++ + addtimer(CALLBACK(src, PROC_REF(end_trail_effect), trail), duration_of_effect) + addtimer(CALLBACK(src, PROC_REF(try_start)), 0.2 SECONDS) + +/datum/effect/effect/system/trail/proc/try_start() + if(on) + processing = TRUE + start() + +/datum/effect/effect/system/trail/proc/end_trail_effect(obj/effect/effect/trail) + number-- + qdel(trail) /datum/effect/effect/system/trail/proc/stop() src.processing = 0 From 540104bd11095ee87114119a9364656d0fcd4ce1 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 26 Sep 2025 14:24:10 -0400 Subject: [PATCH 16/36] Replace spawn in nurse spider AI with timer --- .../hostile/giant_spiders/ai_nurse.dm | 63 ++++++++++--------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spiders/ai_nurse.dm b/code/modules/mob/living/simple_animal/hostile/giant_spiders/ai_nurse.dm index 5d2dd604740f..6b280878a5f0 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spiders/ai_nurse.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spiders/ai_nurse.dm @@ -83,35 +83,40 @@ body.visible_message(SPAN_NOTICE("\The [body] begins to secrete a sticky substance around \the [cocoon_target].")) stop_wandering() body.stop_automove() - spawn(5 SECONDS) - if(get_activity() == AI_ACTIVITY_BUILDING) - if(cocoon_target && isturf(cocoon_target.loc) && get_dist(body, cocoon_target) <= 1) - var/obj/effect/spider/cocoon/C = new(cocoon_target.loc) - var/large_cocoon = 0 - C.pixel_x = cocoon_target.pixel_x - C.pixel_y = cocoon_target.pixel_y - for(var/mob/living/M in C.loc) - large_cocoon = 1 - spooder.fed++ - spooder.max_eggs++ - body.visible_message(SPAN_WARNING("\The [body] sticks a proboscis into \the [cocoon_target] and sucks a viscous substance out.")) - M.forceMove(C) - C.pixel_x = M.pixel_x - C.pixel_y = M.pixel_y - break - for(var/obj/item/I in C.loc) - I.forceMove(C) - for(var/obj/structure/S in C.loc) - if(!S.anchored) - S.forceMove(C) - for(var/obj/machinery/M in C.loc) - if(!M.anchored) - M.forceMove(C) - if(large_cocoon) - C.icon_state = pick("cocoon_large1","cocoon_large2","cocoon_large3") - cocoon_target = null - set_activity(AI_ACTIVITY_IDLE) - resume_wandering() + addtimer(CALLBACK(src, PROC_REF(build_cocoon)), 5 SECONDS) + +/datum/mob_controller/aggressive/giant_spider/nurse/proc/build_cocoon() + if(get_activity() != AI_ACTIVITY_BUILDING) + return FALSE + var/mob/living/simple_animal/hostile/giant_spider/nurse/spooder = body + if(cocoon_target && isturf(cocoon_target.loc) && get_dist(body, cocoon_target) <= 1) + var/obj/effect/spider/cocoon/C = new(cocoon_target.loc) + var/large_cocoon = 0 + C.pixel_x = cocoon_target.pixel_x + C.pixel_y = cocoon_target.pixel_y + for(var/mob/living/M in C.loc) + large_cocoon = 1 + spooder.fed++ + spooder.max_eggs++ + body.visible_message(SPAN_WARNING("\The [body] sticks a proboscis into \the [cocoon_target] and sucks a viscous substance out.")) + M.forceMove(C) + C.pixel_x = M.pixel_x + C.pixel_y = M.pixel_y + break + for(var/obj/item/I in C.loc) + I.forceMove(C) + for(var/obj/structure/S in C.loc) + if(!S.anchored) + S.forceMove(C) + for(var/obj/machinery/M in C.loc) + if(!M.anchored) + M.forceMove(C) + if(large_cocoon) + C.icon_state = pick("cocoon_large1","cocoon_large2","cocoon_large3") + cocoon_target = null + set_activity(AI_ACTIVITY_IDLE) + resume_wandering() + return TRUE /datum/mob_controller/aggressive/giant_spider/nurse/handle_death(gibbed) . = ..() From 91657e1262e71523483651f8f5a48aaf0f7fbef7 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 13 Jun 2025 19:46:42 -0400 Subject: [PATCH 17/36] Move custom circuit system into a modpack --- code/__defines/machinery_public_vars.dm | 11 ++++ .../_machines_base/machinery_public_vars.dm | 22 ++++---- .../machinery_public_vars_common.dm | 18 +++---- code/game/machinery/air_sensor.dm | 6 +-- code/game/machinery/buttons.dm | 2 +- code/game/machinery/doors/airlock_control.dm | 12 ++--- .../objects/items/devices/paint_sprayer.dm | 5 ++ code/game/objects/items/weapons/cards_ids.dm | 34 ++++++------ code/game/objects/random/subtypes/multi.dm | 5 -- code/game/objects/random/subtypes/tech.dm | 15 ------ code/modules/admin/create_object.dm | 2 +- code/modules/atmospherics/atmos_primitives.dm | 4 +- .../components/binary_devices/passive_gate.dm | 8 +-- .../components/binary_devices/pump.dm | 2 +- .../components/unary/outlet_injector.dm | 2 +- .../components/unary/vent_pump.dm | 6 +-- .../components/unary/vent_scrubber.dm | 6 +-- .../designs/general/designs_tools.dm | 9 ---- .../protolathe/designs_hardsuit_modules.dm | 3 -- .../designs/protolathe/designs_misc.dm | 7 --- .../designs/robotics/designs_augments.dm | 3 -- .../integrated_electronics/_defines.dm | 4 -- .../core/_electronics.dm | 5 -- code/modules/mob/living/silicon/pai/pai.dm | 4 +- .../silicon/robot/modules/module_research.dm | 1 - .../device_types/_network_device.dm | 16 +++--- code/unit_tests/json.dm | 21 ++++---- maps/__map_modpack_compatibility.dm | 4 +- maps/antag_spawn/ert/ert_base.dmm | 2 +- maps/away/unishi/unishi.dm | 1 + maps/exodus/exodus-2.dmm | 2 +- maps/exodus/exodus.dm | 1 + maps/ministation/ministation.dm | 1 + maps/modpack_testing/modpack_testing.dm | 1 + maps/tradeship/tradeship.dm | 1 + maps/~mapsystem/maps_antagonism.dm | 1 - mods/content/dungeon_loot/subtypes/maint.dm | 1 - .../_integrated_electronics.dm | 21 ++++---- .../_integrated_electronics.dme | 54 +++++++++++++++++++ .../assemblies/_assemblies.dm | 12 ++--- .../assemblies/circuit_augment.dm | 8 ++- .../circuit_serialization.dm | 0 .../integrated_electronics/circuit_tests.dm | 13 ++++- .../components/_integrated_circuit.dm | 6 +-- .../components}/access.dm | 0 .../components}/arithmetic.dm | 0 .../components}/converters.dm | 0 .../components}/data_transfer.dm | 0 .../components}/filter.dm | 0 .../components}/input.dm | 0 .../components}/lists.dm | 0 .../components}/logic.dm | 0 .../components}/manipulation.dm | 0 .../components}/memory.dm | 0 .../components}/output.dm | 0 .../components}/passive.dm | 2 +- .../components}/power.dm | 2 +- .../components/power_passive.dm | 1 - .../components}/reagents.dm | 0 .../components}/smart.dm | 0 .../components}/time.dm | 0 .../components}/trig.dm | 0 .../fabricator_designs.dm | 20 +++++++ .../integrated_electronics}/helpers.dm | 0 .../integrated_electronics/overrides.dm | 12 +++++ .../integrated_electronics/pins/_pins.dm | 10 ++-- .../pins}/boolean_pin.dm | 2 +- .../integrated_electronics/pins}/char_pin.dm | 2 +- .../integrated_electronics/pins}/color_pin.dm | 2 +- .../integrated_electronics/pins}/dir_pin.dm | 2 +- .../integrated_electronics/pins}/index_pin.dm | 2 +- .../integrated_electronics/pins}/list_pin.dm | 2 +- .../pins}/number_pin.dm | 2 +- .../integrated_electronics/pins}/ref_pin.dm | 2 +- .../pins}/string_pin.dm | 2 +- .../integrated_electronics}/prefab/prefab.dm | 6 +-- .../integrated_electronics}/prefab/prefabs.dm | 6 ++- .../prefab/test/testprefabs.dm | 2 +- mods/content/integrated_electronics/random.dm | 4 ++ .../subsystems}/circuit.dm | 8 +-- .../subsystems/circuit_component.dm | 0 .../toggle_circuits_secret.dm | 0 .../integrated_electronics/tools}/analyzer.dm | 7 ++- .../integrated_electronics/tools}/debugger.dm | 12 ++--- .../integrated_electronics/tools}/detailer.dm | 15 +++--- .../integrated_electronics/tools}/printer.dm | 0 .../integrated_electronics/tools}/wirer.dm | 15 +++--- mods/content/xenobiology/_xenobiology.dme | 1 - mods/~compatibility/patches/circuits.dm | 8 +++ .../patches/circuits/loot_circuits.dm | 6 +++ .../patches/circuits/xenobio_circuits.dm} | 0 mods/~compatibility/~compatibility.dm | 4 ++ nebula.dme | 49 +---------------- tools/map_migrations/0000_legacy.txt | 2 +- 94 files changed, 309 insertions(+), 263 deletions(-) create mode 100644 code/__defines/machinery_public_vars.dm delete mode 100644 code/modules/integrated_electronics/_defines.dm delete mode 100644 code/modules/integrated_electronics/core/_electronics.dm rename code/__defines/integrated_circuits.dm => mods/content/integrated_electronics/_integrated_electronics.dm (78%) create mode 100644 mods/content/integrated_electronics/_integrated_electronics.dme rename code/modules/integrated_electronics/core/assemblies.dm => mods/content/integrated_electronics/assemblies/_assemblies.dm (98%) rename code/modules/augment/active/circuit.dm => mods/content/integrated_electronics/assemblies/circuit_augment.dm (79%) rename code/modules/integrated_electronics/core/saved_circuits.dm => mods/content/integrated_electronics/circuit_serialization.dm (100%) rename code/unit_tests/integrated_circuits.dm => mods/content/integrated_electronics/circuit_tests.dm (91%) rename code/modules/integrated_electronics/core/integrated_circuit.dm => mods/content/integrated_electronics/components/_integrated_circuit.dm (98%) rename {code/modules/integrated_electronics/subtypes => mods/content/integrated_electronics/components}/access.dm (100%) rename {code/modules/integrated_electronics/subtypes => mods/content/integrated_electronics/components}/arithmetic.dm (100%) rename {code/modules/integrated_electronics/subtypes => mods/content/integrated_electronics/components}/converters.dm (100%) rename {code/modules/integrated_electronics/subtypes => mods/content/integrated_electronics/components}/data_transfer.dm (100%) rename {code/modules/integrated_electronics/subtypes => mods/content/integrated_electronics/components}/filter.dm (100%) rename {code/modules/integrated_electronics/subtypes => mods/content/integrated_electronics/components}/input.dm (100%) rename {code/modules/integrated_electronics/subtypes => mods/content/integrated_electronics/components}/lists.dm (100%) rename {code/modules/integrated_electronics/subtypes => mods/content/integrated_electronics/components}/logic.dm (100%) rename {code/modules/integrated_electronics/subtypes => mods/content/integrated_electronics/components}/manipulation.dm (100%) rename {code/modules/integrated_electronics/subtypes => mods/content/integrated_electronics/components}/memory.dm (100%) rename {code/modules/integrated_electronics/subtypes => mods/content/integrated_electronics/components}/output.dm (100%) rename {code/modules/integrated_electronics/passive => mods/content/integrated_electronics/components}/passive.dm (54%) rename {code/modules/integrated_electronics/subtypes => mods/content/integrated_electronics/components}/power.dm (99%) rename code/modules/integrated_electronics/passive/power.dm => mods/content/integrated_electronics/components/power_passive.dm (99%) rename {code/modules/integrated_electronics/subtypes => mods/content/integrated_electronics/components}/reagents.dm (100%) rename {code/modules/integrated_electronics/subtypes => mods/content/integrated_electronics/components}/smart.dm (100%) rename {code/modules/integrated_electronics/subtypes => mods/content/integrated_electronics/components}/time.dm (100%) rename {code/modules/integrated_electronics/subtypes => mods/content/integrated_electronics/components}/trig.dm (100%) create mode 100644 mods/content/integrated_electronics/fabricator_designs.dm rename {code/modules/integrated_electronics/core => mods/content/integrated_electronics}/helpers.dm (100%) create mode 100644 mods/content/integrated_electronics/overrides.dm rename code/modules/integrated_electronics/core/pins.dm => mods/content/integrated_electronics/pins/_pins.dm (95%) rename {code/modules/integrated_electronics/core/special_pins => mods/content/integrated_electronics/pins}/boolean_pin.dm (96%) rename {code/modules/integrated_electronics/core/special_pins => mods/content/integrated_electronics/pins}/char_pin.dm (97%) rename {code/modules/integrated_electronics/core/special_pins => mods/content/integrated_electronics/pins}/color_pin.dm (98%) rename {code/modules/integrated_electronics/core/special_pins => mods/content/integrated_electronics/pins}/dir_pin.dm (97%) rename {code/modules/integrated_electronics/core/special_pins => mods/content/integrated_electronics/pins}/index_pin.dm (96%) rename {code/modules/integrated_electronics/core/special_pins => mods/content/integrated_electronics/pins}/list_pin.dm (99%) rename {code/modules/integrated_electronics/core/special_pins => mods/content/integrated_electronics/pins}/number_pin.dm (96%) rename {code/modules/integrated_electronics/core/special_pins => mods/content/integrated_electronics/pins}/ref_pin.dm (94%) rename {code/modules/integrated_electronics/core/special_pins => mods/content/integrated_electronics/pins}/string_pin.dm (97%) rename {code/modules/integrated_electronics/core => mods/content/integrated_electronics}/prefab/prefab.dm (91%) rename {code/modules/integrated_electronics/core => mods/content/integrated_electronics}/prefab/prefabs.dm (72%) rename {code/modules/integrated_electronics/core => mods/content/integrated_electronics}/prefab/test/testprefabs.dm (97%) create mode 100644 mods/content/integrated_electronics/random.dm rename {code/controllers/subsystems/processing => mods/content/integrated_electronics/subsystems}/circuit.dm (93%) rename {code/controllers => mods/content/integrated_electronics}/subsystems/circuit_component.dm (100%) rename code/modules/admin/secrets/admin_secrets/toggle_circuits.dm => mods/content/integrated_electronics/toggle_circuits_secret.dm (100%) rename {code/modules/integrated_electronics/core => mods/content/integrated_electronics/tools}/analyzer.dm (83%) rename {code/modules/integrated_electronics/core => mods/content/integrated_electronics/tools}/debugger.dm (91%) rename {code/modules/integrated_electronics/core => mods/content/integrated_electronics/tools}/detailer.dm (84%) rename {code/modules/integrated_electronics/core => mods/content/integrated_electronics/tools}/printer.dm (100%) rename {code/modules/integrated_electronics/core => mods/content/integrated_electronics/tools}/wirer.dm (91%) create mode 100644 mods/~compatibility/patches/circuits.dm create mode 100644 mods/~compatibility/patches/circuits/loot_circuits.dm rename mods/{content/xenobiology/circuit.dm => ~compatibility/patches/circuits/xenobio_circuits.dm} (100%) diff --git a/code/__defines/machinery_public_vars.dm b/code/__defines/machinery_public_vars.dm new file mode 100644 index 000000000000..80937653bf53 --- /dev/null +++ b/code/__defines/machinery_public_vars.dm @@ -0,0 +1,11 @@ +// Displayed along with the pin name to show what type of pin it is. +#define VAR_FORMAT_ANY "\" +#define VAR_FORMAT_STRING "\" +#define VAR_FORMAT_CHAR "\" +#define VAR_FORMAT_COLOR "\" +#define VAR_FORMAT_NUMBER "\" +#define VAR_FORMAT_DIR "\" +#define VAR_FORMAT_BOOLEAN "\" +#define VAR_FORMAT_REF "\" +#define VAR_FORMAT_LIST "\" +#define VAR_FORMAT_INDEX "\" diff --git a/code/game/machinery/_machines_base/machinery_public_vars.dm b/code/game/machinery/_machines_base/machinery_public_vars.dm index 594aa0238e02..81871d962fa5 100644 --- a/code/game/machinery/_machines_base/machinery_public_vars.dm +++ b/code/game/machinery/_machines_base/machinery_public_vars.dm @@ -5,7 +5,7 @@ /decl/public_access/public_variable var/expected_type var/can_write = FALSE - var/var_type = IC_FORMAT_BOOLEAN // Reuses IC defines for better compatibility. + var/var_type = VAR_FORMAT_BOOLEAN // Reuses IC defines for better compatibility. var/has_updates = FALSE // Can register listeners for updates on change. var/list/listeners = list() @@ -40,27 +40,27 @@ Must be implemented by subtypes. /decl/public_access/public_variable/proc/check_input_type(new_value) . = FALSE switch(var_type) - if(IC_FORMAT_ANY) + if(VAR_FORMAT_ANY) return TRUE - if(IC_FORMAT_STRING) + if(VAR_FORMAT_STRING) return istext(new_value) - if(IC_FORMAT_CHAR) + if(VAR_FORMAT_CHAR) return istext(new_value) && length(new_value) == 1 - if(IC_FORMAT_COLOR) + if(VAR_FORMAT_COLOR) return sanitize_hexcolor(new_value, null) == new_value - if(IC_FORMAT_NUMBER) + if(VAR_FORMAT_NUMBER) return isnum(new_value) - if(IC_FORMAT_DIR) + if(VAR_FORMAT_DIR) return new_value in global.alldirs - if(IC_FORMAT_BOOLEAN) + if(VAR_FORMAT_BOOLEAN) return new_value == !!new_value - if(IC_FORMAT_REF) + if(VAR_FORMAT_REF) return isweakref(new_value) // Public variables of these types need to against the contents of the list and the index for validity themselves. - if(IC_FORMAT_LIST) + if(VAR_FORMAT_LIST) return islist(new_value) - if(IC_FORMAT_INDEX) + if(VAR_FORMAT_INDEX) return isnum(new_value) /* diff --git a/code/game/machinery/_machines_base/machinery_public_vars_common.dm b/code/game/machinery/_machines_base/machinery_public_vars_common.dm index 30de5ce9da63..8906b31d08c5 100644 --- a/code/game/machinery/_machines_base/machinery_public_vars_common.dm +++ b/code/game/machinery/_machines_base/machinery_public_vars_common.dm @@ -36,7 +36,7 @@ Public vars at /obj/machinery level. Just because they are here does not mean th desc = "An automatically generated area id, if this machine is tied to an area controller." can_write = FALSE has_updates = FALSE - var_type = IC_FORMAT_STRING + var_type = VAR_FORMAT_STRING /decl/public_access/public_variable/area_uid/access_var(obj/machinery/machine) return machine.area_uid() @@ -51,7 +51,7 @@ Public vars at /obj/machinery level. Just because they are here does not mean th desc = "A generic variable intended to give machines a text designator to sort them into categories by function." can_write = TRUE has_updates = TRUE - var_type = IC_FORMAT_STRING + var_type = VAR_FORMAT_STRING /decl/public_access/public_variable/identifier/access_var(obj/machinery/machine) return machine.identifier @@ -67,7 +67,7 @@ Public vars at /obj/machinery level. Just because they are here does not mean th desc = "Whether the machine is off (0) or on (positive). Some machines have multiple power states. Writing to this variable may turn the machine off or on." can_write = TRUE has_updates = FALSE - var_type = IC_FORMAT_NUMBER + var_type = VAR_FORMAT_NUMBER /decl/public_access/public_variable/use_power/access_var(obj/machinery/machine) return machine.use_power @@ -85,7 +85,7 @@ Public vars at /obj/machinery level. Just because they are here does not mean th desc = "The machine's name." can_write = TRUE has_updates = FALSE - var_type = IC_FORMAT_STRING + var_type = VAR_FORMAT_STRING /decl/public_access/public_variable/name/access_var(obj/machinery/machine) return machine.name @@ -101,7 +101,7 @@ Public vars at /obj/machinery level. Just because they are here does not mean th desc = "Obtain the list of reagents and their data in the machine." can_write = FALSE has_updates = TRUE - var_type = IC_FORMAT_LIST + var_type = VAR_FORMAT_LIST /decl/public_access/public_variable/reagents/access_var(obj/machinery/machine) return machine?.reagents?.reagent_data @@ -109,7 +109,7 @@ Public vars at /obj/machinery level. Just because they are here does not mean th /decl/public_access/public_variable/reagents/volumes name = "reagents volumes" desc = "Obtain the list of reagents and their volumes in the machine." - var_type = IC_FORMAT_LIST + var_type = VAR_FORMAT_LIST /decl/public_access/public_variable/reagents/volumes/access_var(obj/machinery/machine) return machine?.reagents?.reagent_volumes @@ -117,7 +117,7 @@ Public vars at /obj/machinery level. Just because they are here does not mean th /decl/public_access/public_variable/reagents/free_space name = "reagents free space" desc = "Obtain the volume of free space left for reagents in the machine." - var_type = IC_FORMAT_NUMBER + var_type = VAR_FORMAT_NUMBER /decl/public_access/public_variable/reagents/free_space/access_var(obj/machinery/machine) return REAGENTS_FREE_SPACE(machine?.reagents) @@ -125,7 +125,7 @@ Public vars at /obj/machinery level. Just because they are here does not mean th /decl/public_access/public_variable/reagents/total_volume name = "reagents total volume" desc = "Obtain the total volume of reagents in the machine." - var_type = IC_FORMAT_NUMBER + var_type = VAR_FORMAT_NUMBER /decl/public_access/public_variable/reagents/total_volume/access_var(obj/machinery/machine) return machine?.reagents?.total_volume @@ -133,7 +133,7 @@ Public vars at /obj/machinery level. Just because they are here does not mean th /decl/public_access/public_variable/reagents/maximum_volume name = "reagents maximum volume" desc = "Obtain the maximum volume of reagents that can fit in the machine." - var_type = IC_FORMAT_NUMBER + var_type = VAR_FORMAT_NUMBER /decl/public_access/public_variable/reagents/maximum_volume/access_var(obj/machinery/machine) return machine?.reagents?.maximum_volume diff --git a/code/game/machinery/air_sensor.dm b/code/game/machinery/air_sensor.dm index aa53b70818e9..bfbb9236ed3e 100644 --- a/code/game/machinery/air_sensor.dm +++ b/code/game/machinery/air_sensor.dm @@ -36,7 +36,7 @@ desc = "A list of gas data from the sensor location; the list entries are two-entry lists with \"symbol\" and \"percent\" fields." can_write = FALSE has_updates = FALSE - var_type = IC_FORMAT_LIST + var_type = VAR_FORMAT_LIST /decl/public_access/public_variable/gas/access_var(obj/machinery/sensor) var/datum/gas_mixture/air_sample = sensor.return_air() @@ -58,7 +58,7 @@ desc = "The pressure of the gas at the sensor." can_write = FALSE has_updates = FALSE - var_type = IC_FORMAT_STRING + var_type = VAR_FORMAT_STRING /decl/public_access/public_variable/pressure/access_var(obj/machinery/sensor) var/datum/gas_mixture/air_sample = sensor.return_air() @@ -70,7 +70,7 @@ desc = "The temperature of the gas at the sensor." can_write = FALSE has_updates = FALSE - var_type = IC_FORMAT_NUMBER + var_type = VAR_FORMAT_NUMBER /decl/public_access/public_variable/temperature/access_var(obj/machinery/sensor) var/datum/gas_mixture/air_sample = sensor.return_air() diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 9e19104b483a..eda811c59e8f 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -120,7 +120,7 @@ desc = "Whether the button is currently in the on state." can_write = TRUE has_updates = FALSE - var_type = IC_FORMAT_BOOLEAN + var_type = VAR_FORMAT_BOOLEAN /decl/public_access/public_variable/button_state/access_var(obj/machinery/button/button) return button.state diff --git a/code/game/machinery/doors/airlock_control.dm b/code/game/machinery/doors/airlock_control.dm index c1f9b50ebf6d..3ac2040598f2 100644 --- a/code/game/machinery/doors/airlock_control.dm +++ b/code/game/machinery/doors/airlock_control.dm @@ -74,7 +74,7 @@ desc = "Whether the door is closed (\"closed\") or not (\"open\")." can_write = FALSE has_updates = FALSE - var_type = IC_FORMAT_STRING + var_type = VAR_FORMAT_STRING /decl/public_access/public_variable/airlock_door_state/access_var(obj/machinery/door/airlock/door) return door.density ? "closed" : "open" @@ -85,7 +85,7 @@ desc = "Whether the door is bolted (\"locked\") or not (\"unlocked\")." can_write = FALSE has_updates = FALSE - var_type = IC_FORMAT_STRING + var_type = VAR_FORMAT_STRING /decl/public_access/public_variable/airlock_bolt_state/access_var(obj/machinery/door/airlock/door) return door.locked ? "locked" : "unlocked" @@ -190,7 +190,7 @@ desc = "The pressure of the location where the sensor is placed." can_write = FALSE has_updates = TRUE - var_type = IC_FORMAT_NUMBER + var_type = VAR_FORMAT_NUMBER /decl/public_access/public_variable/airlock_pressure/access_var(obj/machinery/airlock_sensor/sensor) return sensor.pressure @@ -209,7 +209,7 @@ /decl/public_access/public_variable/set_airlock_cycling/airlock_sensor expected_type = /obj/machinery/airlock_sensor can_write = TRUE - var_type = IC_FORMAT_BOOLEAN + var_type = VAR_FORMAT_BOOLEAN /decl/public_access/public_variable/set_airlock_cycling/airlock_sensor/access_var(obj/machinery/airlock_sensor/owner) return owner.master_cycling @@ -359,7 +359,7 @@ /decl/public_access/public_variable/set_airlock_cycling/access_button expected_type = /obj/machinery/button/access can_write = TRUE - var_type = IC_FORMAT_BOOLEAN + var_type = VAR_FORMAT_BOOLEAN /decl/public_access/public_variable/set_airlock_cycling/access_button/access_var(obj/machinery/button/access/owner) return owner.master_cycling @@ -376,7 +376,7 @@ desc = "The command this access button sends when pressed." can_write = TRUE has_updates = FALSE - var_type = IC_FORMAT_STRING + var_type = VAR_FORMAT_STRING /decl/public_access/public_variable/button_command/access_var(obj/machinery/button/access/button) return button.command diff --git a/code/game/objects/items/devices/paint_sprayer.dm b/code/game/objects/items/devices/paint_sprayer.dm index 33f49ba11395..a6c34a1707b9 100644 --- a/code/game/objects/items/devices/paint_sprayer.dm +++ b/code/game/objects/items/devices/paint_sprayer.dm @@ -114,6 +114,11 @@ else change_color(new_color, user) + else if(istype(A, /obj/item/card/data)) // TODO: un-hardcode this please. better yet redo how this entire proc is done + var/obj/item/card/data/data_card = A + data_card.detail_color = spray_color + . = TRUE + else if (istype(A, /turf/wall)) . = paint_wall(A, user) diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 2dadd2bbf4d5..5bca85e73be3 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -1,16 +1,11 @@ /* Cards * Contains: - * DATA CARD - * ID CARD - * FINGERPRINT CARD HOLDER - * FINGERPRINT CARD + * UNION CARD + * DATA CARDS + * EMAG & BROKEN EMAG + * ID CARDS */ - - -/* - * DATA CARDS - Used for the IC data card reader - */ /obj/item/card name = "card" desc = "Does card things." @@ -21,6 +16,10 @@ drop_sound = 'sound/foley/paperpickup1.ogg' pickup_sound = 'sound/foley/paperpickup2.ogg' +/* + * UNION CARD + */ + /obj/item/card/union name = "union card" desc = "A card showing membership in the local worker's union." @@ -47,6 +46,10 @@ return TRUE return ..() +/* + * DATA CARDS - Used for the IC data card reader and, for some reason, faxes and teleporters. + */ +// Please modpack this once those last two are made to use data disks instead. /obj/item/card/data name = "data card" desc = "A plastic magstripe card for simple and speedy data storage and transfer. This one has a stripe running down the middle." @@ -63,13 +66,6 @@ . = ..() add_overlay(overlay_image(icon, "[icon_state]-color", detail_color)) -/obj/item/card/data/attackby(obj/item/used_item, mob/user) - if(istype(used_item, /obj/item/integrated_electronics/detailer)) - var/obj/item/integrated_electronics/detailer/D = used_item - detail_color = D.detail_color - update_icon() - return ..() - /obj/item/card/data/full_color desc = "A plastic magstripe card for simple and speedy data storage and transfer. This one has the entire card colored." icon_state = "data_2" @@ -82,7 +78,7 @@ return detail_color /* - * ID CARDS + * EMAG & BROKEN EMAG */ /obj/item/card/emag_broken @@ -149,6 +145,10 @@ var/global/const/NO_EMAG_ACT = -50 if(user.skill_check(SKILL_DEVICES,SKILL_ADEPT)) . += SPAN_WARNING("This ID card has some form of non-standard modifications.") +/* + * ID CARDS + */ + /obj/item/card/id name = "identification card" desc = "A card used to provide ID and determine access." diff --git a/code/game/objects/random/subtypes/multi.dm b/code/game/objects/random/subtypes/multi.dm index a0268faecaeb..ca95e015af2c 100644 --- a/code/game/objects/random/subtypes/multi.dm +++ b/code/game/objects/random/subtypes/multi.dm @@ -19,8 +19,3 @@ name = "Multi Point - Captain's Spare" id = "Captain's spare id" item_path = /obj/item/card/id/captains_spare - -/obj/random_multi/single_item/hand_tele - name = "Multi Point - Hand Teleporter" - id = "Hand teleporter" - item_path = /obj/prefab/hand_teleporter diff --git a/code/game/objects/random/subtypes/tech.dm b/code/game/objects/random/subtypes/tech.dm index 23c298283fae..a1b1ab86e65d 100644 --- a/code/game/objects/random/subtypes/tech.dm +++ b/code/game/objects/random/subtypes/tech.dm @@ -94,21 +94,6 @@ ) return spawnable_choices -/obj/random/assembly - name = "random assembly" - desc = "This is a random circuit assembly." - icon = 'icons/obj/items/gift_wrapped.dmi' - icon_state = "gift_1" - -/obj/random/assembly/spawn_choices() - var/static/list/spawnable_choices = list( - /obj/item/electronic_assembly, - /obj/item/electronic_assembly/medium, - /obj/item/electronic_assembly/large, - /obj/item/electronic_assembly/drone - ) - return spawnable_choices - /obj/random/advdevice name = "random advanced device" desc = "This is a random advanced device." diff --git a/code/modules/admin/create_object.dm b/code/modules/admin/create_object.dm index 23da2d37f267..4852f28a58e6 100644 --- a/code/modules/admin/create_object.dm +++ b/code/modules/admin/create_object.dm @@ -13,7 +13,7 @@ var/global/create_object_html = null /datum/admins/proc/quick_create_object(var/mob/user) var/quick_create_object_html = null - var/path = input("Select the path of the object you wish to create.", "Path", /obj) as null|anything in list(/obj,/obj/structure,/obj/item,/obj/item,/obj/item/clothing,/obj/machinery,/obj/prefab) + var/path = input("Select the path of the object you wish to create.", "Path", /obj) as null|anything in list(/obj,/obj/structure,/obj/item,/obj/item,/obj/item/clothing,/obj/machinery) if(!path) return diff --git a/code/modules/atmospherics/atmos_primitives.dm b/code/modules/atmospherics/atmos_primitives.dm index 720b2ac3ff76..4d78c3a4553a 100644 --- a/code/modules/atmospherics/atmos_primitives.dm +++ b/code/modules/atmospherics/atmos_primitives.dm @@ -517,7 +517,7 @@ desc = "The most recent data on the amount of power the machine used." can_write = FALSE has_updates = FALSE - var_type = IC_FORMAT_NUMBER + var_type = VAR_FORMAT_NUMBER /decl/public_access/public_variable/power_draw/access_var(obj/machinery/atmospherics/machine) return machine.last_power_draw @@ -528,7 +528,7 @@ desc = "The most recent data on the volume of air the machine moved." can_write = FALSE has_updates = FALSE - var_type = IC_FORMAT_NUMBER + var_type = VAR_FORMAT_NUMBER /decl/public_access/public_variable/flow_rate/access_var(obj/machinery/atmospherics/machine) return machine.last_flow_rate \ No newline at end of file diff --git a/code/modules/atmospherics/components/binary_devices/passive_gate.dm b/code/modules/atmospherics/components/binary_devices/passive_gate.dm index c55ea099f96c..caacc188ddab 100644 --- a/code/modules/atmospherics/components/binary_devices/passive_gate.dm +++ b/code/modules/atmospherics/components/binary_devices/passive_gate.dm @@ -196,7 +196,7 @@ desc = "Whether or not the valve is open, allowing gas to pass in one direction." can_write = TRUE has_updates = FALSE - var_type = IC_FORMAT_BOOLEAN + var_type = VAR_FORMAT_BOOLEAN /decl/public_access/public_variable/passive_gate_unlocked/access_var(obj/machinery/atmospherics/binary/passive_gate/machine) return machine.unlocked @@ -213,7 +213,7 @@ desc = "A cap on the volume flow rate of the gate." can_write = TRUE has_updates = FALSE - var_type = IC_FORMAT_NUMBER + var_type = VAR_FORMAT_NUMBER /decl/public_access/public_variable/passive_gate_flow_rate/access_var(obj/machinery/atmospherics/binary/passive_gate/machine) return machine.set_flow_rate @@ -230,7 +230,7 @@ desc = "A number describing the form of regulation the gate is attempting. The possible values are 0 (no air passed), 1 (regulates input pressure), or 2 (regulates output pressure)." can_write = TRUE has_updates = FALSE - var_type = IC_FORMAT_NUMBER + var_type = VAR_FORMAT_NUMBER /decl/public_access/public_variable/passive_gate_mode/access_var(obj/machinery/atmospherics/binary/passive_gate/machine) return machine.regulate_mode @@ -247,7 +247,7 @@ desc = "The input or output pressure the gate aims to stay below." can_write = TRUE has_updates = FALSE - var_type = IC_FORMAT_NUMBER + var_type = VAR_FORMAT_NUMBER /decl/public_access/public_variable/passive_gate_target_pressure/access_var(obj/machinery/atmospherics/binary/passive_gate/machine) return machine.target_pressure diff --git a/code/modules/atmospherics/components/binary_devices/pump.dm b/code/modules/atmospherics/components/binary_devices/pump.dm index b1ec04c332d7..eeb70c699672 100644 --- a/code/modules/atmospherics/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/components/binary_devices/pump.dm @@ -173,7 +173,7 @@ Thus, the two variables affect pump operation are set in New(): desc = "The output pressure of the pump." can_write = TRUE has_updates = FALSE - var_type = IC_FORMAT_NUMBER + var_type = VAR_FORMAT_NUMBER /decl/public_access/public_variable/pump_target_output/access_var(obj/machinery/atmospherics/binary/pump/machine) return machine.target_pressure diff --git a/code/modules/atmospherics/components/unary/outlet_injector.dm b/code/modules/atmospherics/components/unary/outlet_injector.dm index 20a9ee0a3b24..1ed273483573 100644 --- a/code/modules/atmospherics/components/unary/outlet_injector.dm +++ b/code/modules/atmospherics/components/unary/outlet_injector.dm @@ -141,7 +141,7 @@ desc = "The rate at which the machine pumps (a number)." can_write = TRUE has_updates = FALSE - var_type = IC_FORMAT_NUMBER + var_type = VAR_FORMAT_NUMBER /decl/public_access/public_variable/volume_rate/access_var(obj/machinery/atmospherics/unary/outlet_injector/machine) return machine.volume_rate diff --git a/code/modules/atmospherics/components/unary/vent_pump.dm b/code/modules/atmospherics/components/unary/vent_pump.dm index 20f4d41f2594..c463a0687ce1 100644 --- a/code/modules/atmospherics/components/unary/vent_pump.dm +++ b/code/modules/atmospherics/components/unary/vent_pump.dm @@ -368,7 +368,7 @@ desc = "The pump mode of the vent. Expected values are \"siphon\" or \"release\"." can_write = TRUE has_updates = TRUE - var_type = IC_FORMAT_STRING + var_type = VAR_FORMAT_STRING /decl/public_access/public_variable/pump_dir/access_var(obj/machinery/atmospherics/unary/vent_pump/machine) return machine.pump_direction ? "release" : "siphon" @@ -386,7 +386,7 @@ desc = "Numerical codes for whether the pump checks internal or internal pressure (or both) prior to operating. Can also be supplied the string keyword \"default\"." can_write = TRUE has_updates = FALSE - var_type = IC_FORMAT_ANY + var_type = VAR_FORMAT_ANY /decl/public_access/public_variable/pump_checks/access_var(obj/machinery/atmospherics/unary/vent_pump/machine) return machine.pressure_checks @@ -405,7 +405,7 @@ desc = "The bound on internal pressure used in checks (a number). When writing, can be supplied the string keyword \"default\" instead." can_write = TRUE has_updates = FALSE - var_type = IC_FORMAT_ANY + var_type = VAR_FORMAT_ANY /decl/public_access/public_variable/pressure_bound/access_var(obj/machinery/atmospherics/unary/vent_pump/machine) return machine.internal_pressure_bound diff --git a/code/modules/atmospherics/components/unary/vent_scrubber.dm b/code/modules/atmospherics/components/unary/vent_scrubber.dm index 4ff8c0e85b87..9ab3bc3e4976 100644 --- a/code/modules/atmospherics/components/unary/vent_scrubber.dm +++ b/code/modules/atmospherics/components/unary/vent_scrubber.dm @@ -266,7 +266,7 @@ desc = "The scrubbing mode code, which identifies what the scrubber is doing." can_write = TRUE has_updates = FALSE - var_type = IC_FORMAT_STRING + var_type = VAR_FORMAT_STRING /decl/public_access/public_variable/scrubbing/access_var(obj/machinery/atmospherics/unary/vent_scrubber/machine) return machine.scrubbing @@ -286,7 +286,7 @@ desc = "Whether or not the scrubber is in panic mode." can_write = TRUE has_updates = FALSE - var_type = IC_FORMAT_BOOLEAN + var_type = VAR_FORMAT_BOOLEAN /decl/public_access/public_variable/panic/access_var(obj/machinery/atmospherics/unary/vent_scrubber/machine) return machine.panic @@ -308,7 +308,7 @@ desc = "A list of gases that this scrubber is scrubbing." can_write = FALSE has_updates = FALSE - var_type = IC_FORMAT_LIST + var_type = VAR_FORMAT_LIST /decl/public_access/public_variable/scrubbing_gas/access_var(obj/machinery/atmospherics/unary/vent_scrubber/machine) return machine.scrubbing_gas.Copy() diff --git a/code/modules/fabrication/designs/general/designs_tools.dm b/code/modules/fabrication/designs/general/designs_tools.dm index a7893fe4e1bd..1c9fc7d94818 100644 --- a/code/modules/fabrication/designs/general/designs_tools.dm +++ b/code/modules/fabrication/designs/general/designs_tools.dm @@ -2,15 +2,6 @@ path = /obj/item/crowbar category = "Tools" -/datum/fabricator_recipe/tool/int_wirer - path = /obj/item/integrated_electronics/wirer - -/datum/fabricator_recipe/tool/int_debugger - path = /obj/item/integrated_electronics/debugger - -/datum/fabricator_recipe/tool/int_analyzer - path = /obj/item/integrated_electronics/analyzer - /datum/fabricator_recipe/tool/multitool path = /obj/item/multitool diff --git a/code/modules/fabrication/designs/protolathe/designs_hardsuit_modules.dm b/code/modules/fabrication/designs/protolathe/designs_hardsuit_modules.dm index 8faa81dd4ddc..219883e737e1 100644 --- a/code/modules/fabrication/designs/protolathe/designs_hardsuit_modules.dm +++ b/code/modules/fabrication/designs/protolathe/designs_hardsuit_modules.dm @@ -61,6 +61,3 @@ /datum/fabricator_recipe/protolathe/rig/cooling_unit path = /obj/item/rig_module/cooling_unit - -/datum/fabricator_recipe/protolathe/rig/integrated_printer - path = /obj/item/integrated_circuit_printer diff --git a/code/modules/fabrication/designs/protolathe/designs_misc.dm b/code/modules/fabrication/designs/protolathe/designs_misc.dm index ae9ad75f43ef..0d406749fae2 100644 --- a/code/modules/fabrication/designs/protolathe/designs_misc.dm +++ b/code/modules/fabrication/designs/protolathe/designs_misc.dm @@ -55,10 +55,3 @@ /datum/fabricator_recipe/protolathe/misc/radio_beacon path = /obj/item/radio_beacon - - -/datum/fabricator_recipe/protolathe/integrated_printer_upgrade_advanced - path = /obj/item/disk/integrated_circuit/upgrade/advanced - -/datum/fabricator_recipe/protolathe/integrated_printer_upgrade_clone - path = /obj/item/disk/integrated_circuit/upgrade/clone diff --git a/code/modules/fabrication/designs/robotics/designs_augments.dm b/code/modules/fabrication/designs/robotics/designs_augments.dm index 85cc0d421d51..8ca2afdfe5ed 100644 --- a/code/modules/fabrication/designs/robotics/designs_augments.dm +++ b/code/modules/fabrication/designs/robotics/designs_augments.dm @@ -28,6 +28,3 @@ /datum/fabricator_recipe/robotics/augment/nanounit path = /obj/item/organ/internal/augment/active/nanounit - -/datum/fabricator_recipe/robotics/augment/circuit - path = /obj/item/organ/internal/augment/active/simple/circuit diff --git a/code/modules/integrated_electronics/_defines.dm b/code/modules/integrated_electronics/_defines.dm deleted file mode 100644 index 69c2b2eb593d..000000000000 --- a/code/modules/integrated_electronics/_defines.dm +++ /dev/null @@ -1,4 +0,0 @@ -#define IC_TOPIC_UNHANDLED 0 -#define IC_TOPIC_HANDLED 1 -#define IC_TOPIC_REFRESH 2 -#define IC_FLAG_CAN_FIRE 1 \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/_electronics.dm b/code/modules/integrated_electronics/core/_electronics.dm deleted file mode 100644 index d96c32f9aec4..000000000000 --- a/code/modules/integrated_electronics/core/_electronics.dm +++ /dev/null @@ -1,5 +0,0 @@ -/obj/item/integrated_electronics - abstract_type = /obj/item/integrated_electronics - obj_flags = OBJ_FLAG_CONDUCTIBLE - w_class = ITEM_SIZE_SMALL - material = /decl/material/solid/metal/aluminium diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index db413c265061..8a5bc7ae6728 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -181,7 +181,7 @@ var/global/list/possible_say_verbs = list( return set_special_ability_cooldown(10 SECONDS) //I'm not sure how much of this is necessary, but I would rather avoid issues. - if(istype(card.loc,/obj/item/rig_module) || istype(card.loc,/obj/item/integrated_circuit/manipulation/ai/)) + if(isitem(card.loc) && !card.loc.storage) // this used to be a more specific check for ai holder parts but this should cover them still to_chat(src, "There is no room to unfold inside \the [card.loc]. You're good and stuck.") return 0 else if(ismob(card.loc)) @@ -192,7 +192,7 @@ var/global/list/possible_say_verbs = list( if(card in affecting.implants) affecting.take_damage(rand(30,50)) LAZYREMOVE(affecting.implants, card) - H.visible_message("\The [src] explodes out of \the [H]'s [affecting.name] in a shower of gore!") + H.visible_message(SPAN_DANGER("\The [src] explodes out of \the [H]'s [affecting.name] in a shower of gore!")) break holder.drop_from_inventory(card) diff --git a/code/modules/mob/living/silicon/robot/modules/module_research.dm b/code/modules/mob/living/silicon/robot/modules/module_research.dm index 3b02f263e528..78de4222ad41 100644 --- a/code/modules/mob/living/silicon/robot/modules/module_research.dm +++ b/code/modules/mob/living/silicon/robot/modules/module_research.dm @@ -32,7 +32,6 @@ synths = list( /datum/matter_synth/nanite = 10000 ) - emag = /obj/prefab/hand_teleporter skills = list( SKILL_LITERACY = SKILL_ADEPT, SKILL_FINANCE = SKILL_EXPERT, diff --git a/code/modules/modular_computers/networking/device_types/_network_device.dm b/code/modules/modular_computers/networking/device_types/_network_device.dm index 71a3eb7c1e78..292b7c9b0c87 100644 --- a/code/modules/modular_computers/networking/device_types/_network_device.dm +++ b/code/modules/modular_computers/networking/device_types/_network_device.dm @@ -394,29 +394,29 @@ /datum/extension/network_device/proc/sanitize_command_args(command_args, var_type) // First check if the command is a list; if it is, only accept it if the expected type is a list. if(islist(command_args)) - if(var_type == IC_FORMAT_LIST) + if(var_type == VAR_FORMAT_LIST) return command_args else return null switch(var_type) - if(IC_FORMAT_ANY) + if(VAR_FORMAT_ANY) return command_args - if(IC_FORMAT_STRING) + if(VAR_FORMAT_STRING) return "[command_args]" - if(IC_FORMAT_CHAR) + if(VAR_FORMAT_CHAR) if(istext(command_args) && length(command_args) == 1) return command_args - if(IC_FORMAT_COLOR) + if(VAR_FORMAT_COLOR) return sanitize_hexcolor(command_args, null) - if(IC_FORMAT_NUMBER, IC_FORMAT_INDEX) + if(VAR_FORMAT_NUMBER, VAR_FORMAT_INDEX) if(istext(command_args)) return text2num(command_args) if(isnum(command_args)) return command_args - if(IC_FORMAT_DIR) + if(VAR_FORMAT_DIR) if(istext(command_args)) return text2dir(command_args) - if(IC_FORMAT_BOOLEAN) + if(VAR_FORMAT_BOOLEAN) if(istext(command_args)) switch(uppertext(command_args)) if("TRUE") diff --git a/code/unit_tests/json.dm b/code/unit_tests/json.dm index 1ac8aa5cb571..f08cbbf6c7ed 100644 --- a/code/unit_tests/json.dm +++ b/code/unit_tests/json.dm @@ -31,12 +31,10 @@ /datum/unit_test/atoms_should_use_valid_json name = "JSON: Atoms using JSON should have valid JSON values" -/datum/unit_test/atoms_should_use_valid_json/start_test() - // Tried doing this with a list, but accessing initial vars is noodly - // without an object instance so I'm being slack and hardcoding it. - var/list/failures +// This exists so that modpacks can easily add their own JSON tests. +// TODO: declize this or something +/datum/unit_test/atoms_should_use_valid_json/proc/get_json_to_check() var/list/json_to_check - for(var/atom/movable/subtype as anything in typesof(/obj)) if(TYPE_IS_ABSTRACT(subtype)) continue @@ -82,12 +80,13 @@ var/check_json = quad_bodytype.riding_offset if(istext(check_json)) LAZYSET(json_to_check, "[quad_bodytype_path].riding_offset", check_json) - var/list/prefabs = decls_repository.get_decls_of_subtype(/decl/prefab/ic_assembly) - for(var/assembly_path in prefabs) - var/decl/prefab/ic_assembly/assembly = prefabs[assembly_path] - var/check_json = assembly.data - if(!isnull(check_json)) - LAZYSET(json_to_check, "[assembly_path].data", check_json) + return json_to_check + +/datum/unit_test/atoms_should_use_valid_json/start_test() + // Tried doing this with a list, but accessing initial vars is noodly + // without an object instance so I'm being slack and hardcoding it. + var/list/failures + var/list/json_to_check = get_json_to_check() // Validate JSON. for(var/check_key in json_to_check) try diff --git a/maps/__map_modpack_compatibility.dm b/maps/__map_modpack_compatibility.dm index 288644f46e27..27024354094b 100644 --- a/maps/__map_modpack_compatibility.dm +++ b/maps/__map_modpack_compatibility.dm @@ -22,4 +22,6 @@ } /// This spawner is used to optionally spawn the aliumizer if the random aliens modpack is included. -OPTIONAL_SPAWNER(aliumizer, null) \ No newline at end of file +OPTIONAL_SPAWNER(aliumizer, null) +/// This spawner is used to optionally spawn the hand teleporter if the integrated electronics modpack is included. +OPTIONAL_SPAWNER(hand_tele, null) // todo: add a non-prefab hand tele variant for use without the modpack? \ No newline at end of file diff --git a/maps/antag_spawn/ert/ert_base.dmm b/maps/antag_spawn/ert/ert_base.dmm index 445cad5e6ae8..331f3bca8288 100644 --- a/maps/antag_spawn/ert/ert_base.dmm +++ b/maps/antag_spawn/ert/ert_base.dmm @@ -1340,7 +1340,7 @@ /area/map_template/rescue_base/base) "dE" = ( /obj/structure/table/reinforced, -/obj/prefab/hand_teleporter, +/obj/abstract/modpack_compat/hand_tele, /turf/unsimulated/floor/vault, /area/map_template/rescue_base/base) "dF" = ( diff --git a/maps/away/unishi/unishi.dm b/maps/away/unishi/unishi.dm index bb5d0d2d9572..9876826f1ff6 100644 --- a/maps/away/unishi/unishi.dm +++ b/maps/away/unishi/unishi.dm @@ -1,5 +1,6 @@ #include "unishi_areas.dm" #include "unishi_jobs.dm" +#include "../../../mods/content/integrated_electronics/_integrated_electronics.dme" // this is used for just one prop, todo: remove? #include "../../../mods/content/xenobiology/_xenobiology.dme" #include "../../../mods/content/supermatter/_supermatter.dme" #include "../../../mods/content/beekeeping/_beekeeping.dme" diff --git a/maps/exodus/exodus-2.dmm b/maps/exodus/exodus-2.dmm index c83892c7fd92..83affb57b561 100644 --- a/maps/exodus/exodus-2.dmm +++ b/maps/exodus/exodus-2.dmm @@ -39141,7 +39141,7 @@ /area/exodus/turret_protected/ai_cyborg_station) "bEE" = ( /obj/structure/table, -/obj/prefab/hand_teleporter, +/obj/abstract/prefab/hand_teleporter, /obj/machinery/light, /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 1 diff --git a/maps/exodus/exodus.dm b/maps/exodus/exodus.dm index 676c84a62503..5a5d207d3c62 100644 --- a/maps/exodus/exodus.dm +++ b/maps/exodus/exodus.dm @@ -8,6 +8,7 @@ #include "../../mods/content/blob/_blob.dme" #include "../../mods/content/corporate/_corporate.dme" #include "../../mods/content/government/_government.dme" + #include "../../mods/content/integrated_electronics/_integrated_electronics.dme" #include "../../mods/content/matchmaking/_matchmaking.dme" #include "../../mods/content/modern_earth/_modern_earth.dme" #include "../../mods/content/mouse_highlights/_mouse_highlight.dme" diff --git a/maps/ministation/ministation.dm b/maps/ministation/ministation.dm index 9c62ac3bdccf..87ebbd49b8d8 100644 --- a/maps/ministation/ministation.dm +++ b/maps/ministation/ministation.dm @@ -24,6 +24,7 @@ Twice... #include "../../mods/content/blob/_blob.dme" #include "../../mods/content/corporate/_corporate.dme" #include "../../mods/content/government/_government.dme" + #include "../../mods/content/integrated_electronics/_integrated_electronics.dme" #include "../../mods/content/matchmaking/_matchmaking.dme" #include "../../mods/content/modern_earth/_modern_earth.dme" #include "../../mods/content/mouse_highlights/_mouse_highlight.dme" diff --git a/maps/modpack_testing/modpack_testing.dm b/maps/modpack_testing/modpack_testing.dm index 0c77a158eb9f..52d46b1e1396 100644 --- a/maps/modpack_testing/modpack_testing.dm +++ b/maps/modpack_testing/modpack_testing.dm @@ -18,6 +18,7 @@ #include "../../mods/content/generic_shuttles/_generic_shuttles.dme" #include "../../mods/content/government/_government.dme" #include "../../mods/content/inertia/_inertia.dme" + #include "../../mods/content/integrated_electronics/_integrated_electronics.dme" #include "../../mods/content/item_sharpening/_item_sharpening.dme" #include "../../mods/content/matchmaking/_matchmaking.dme" #include "../../mods/content/modern_earth/_modern_earth.dme" diff --git a/maps/tradeship/tradeship.dm b/maps/tradeship/tradeship.dm index ec261eac45aa..95820435eef9 100644 --- a/maps/tradeship/tradeship.dm +++ b/maps/tradeship/tradeship.dm @@ -21,6 +21,7 @@ #include "../../mods/content/corporate/_corporate.dme" #include "../../mods/content/dungeon_loot/_dungeon_loot.dme" #include "../../mods/content/government/_government.dme" + #include "../../mods/content/integrated_electronics/_integrated_electronics.dme" #include "../../mods/content/matchmaking/_matchmaking.dme" #include "../../mods/content/modern_earth/_modern_earth.dme" #include "../../mods/content/mouse_highlights/_mouse_highlight.dme" diff --git a/maps/~mapsystem/maps_antagonism.dm b/maps/~mapsystem/maps_antagonism.dm index b2a1741eaa16..db59a1035aee 100644 --- a/maps/~mapsystem/maps_antagonism.dm +++ b/maps/~mapsystem/maps_antagonism.dm @@ -1,7 +1,6 @@ /datum/map var/list/potential_theft_targets = list( "the captain's antique laser gun" = /obj/item/gun/energy/captain, - "a wormhole generator" = /obj/item/integrated_circuit/manipulation/wormhole, "an RCD" = /obj/item/rcd, "a jetpack" = /obj/item/tank/jetpack, "a captain's jumpsuit" = /obj/item/clothing/jumpsuit/captain, diff --git a/mods/content/dungeon_loot/subtypes/maint.dm b/mods/content/dungeon_loot/subtypes/maint.dm index dd04faa5a42f..c4a3d31a6bed 100644 --- a/mods/content/dungeon_loot/subtypes/maint.dm +++ b/mods/content/dungeon_loot/subtypes/maint.dm @@ -312,7 +312,6 @@ /obj/item/aiModule/reset, /obj/item/stock_parts/smes_coil/super_capacity, /obj/item/stock_parts/smes_coil/super_io, - /obj/item/disk/integrated_circuit/upgrade/advanced, /obj/item/camera/tvcamera, /obj/item/aicard, /obj/item/borg/upgrade/jetpack, diff --git a/code/__defines/integrated_circuits.dm b/mods/content/integrated_electronics/_integrated_electronics.dm similarity index 78% rename from code/__defines/integrated_circuits.dm rename to mods/content/integrated_electronics/_integrated_electronics.dm index a7681271e397..5da63a6e255b 100644 --- a/code/__defines/integrated_circuits.dm +++ b/mods/content/integrated_electronics/_integrated_electronics.dm @@ -1,3 +1,8 @@ +#define IC_TOPIC_UNHANDLED 0 +#define IC_TOPIC_HANDLED 1 +#define IC_TOPIC_REFRESH 2 +#define IC_FLAG_CAN_FIRE 1 + #define IC_INPUT "I" #define IC_OUTPUT "O" #define IC_ACTIVATOR "A" @@ -15,18 +20,7 @@ #define IC_ACTION_COMBAT BITFLAG(1) // If the circuit can cause harm #define IC_ACTION_LONG_RANGE BITFLAG(2) // If the circuit communicate with something outside of the assembly -// Displayed along with the pin name to show what type of pin it is. -#define IC_FORMAT_ANY "\" -#define IC_FORMAT_STRING "\" -#define IC_FORMAT_CHAR "\" -#define IC_FORMAT_COLOR "\" -#define IC_FORMAT_NUMBER "\" -#define IC_FORMAT_DIR "\" -#define IC_FORMAT_BOOLEAN "\" -#define IC_FORMAT_REF "\" -#define IC_FORMAT_LIST "\" -#define IC_FORMAT_INDEX "\" - +// extra format type just for ICs #define IC_FORMAT_PULSE "\" // Used inside input/output list to tell the constructor what pin to make. @@ -46,3 +40,6 @@ // Data limits. #define IC_MAX_LIST_LENGTH 500 + +/decl/modpack/integrated_electronics + name = "Custom Circuits Content" diff --git a/mods/content/integrated_electronics/_integrated_electronics.dme b/mods/content/integrated_electronics/_integrated_electronics.dme new file mode 100644 index 000000000000..7a5c25290367 --- /dev/null +++ b/mods/content/integrated_electronics/_integrated_electronics.dme @@ -0,0 +1,54 @@ +#ifndef CONTENT_PACK_CIRCUITS +#define CONTENT_PACK_CIRCUITS +// BEGIN_INCLUDE +#include "_integrated_electronics.dm" +#include "circuit_serialization.dm" +#include "circuit_tests.dm" +#include "fabricator_designs.dm" +#include "helpers.dm" +#include "overrides.dm" +#include "random.dm" +#include "toggle_circuits_secret.dm" +#include "assemblies\_assemblies.dm" +#include "assemblies\circuit_augment.dm" +#include "components\_integrated_circuit.dm" +#include "components\access.dm" +#include "components\arithmetic.dm" +#include "components\converters.dm" +#include "components\data_transfer.dm" +#include "components\filter.dm" +#include "components\input.dm" +#include "components\lists.dm" +#include "components\logic.dm" +#include "components\manipulation.dm" +#include "components\memory.dm" +#include "components\output.dm" +#include "components\passive.dm" +#include "components\power.dm" +#include "components\power_passive.dm" +#include "components\reagents.dm" +#include "components\smart.dm" +#include "components\time.dm" +#include "components\trig.dm" +#include "pins\_pins.dm" +#include "pins\boolean_pin.dm" +#include "pins\char_pin.dm" +#include "pins\color_pin.dm" +#include "pins\dir_pin.dm" +#include "pins\index_pin.dm" +#include "pins\list_pin.dm" +#include "pins\number_pin.dm" +#include "pins\ref_pin.dm" +#include "pins\string_pin.dm" +#include "prefab\prefab.dm" +#include "prefab\prefabs.dm" +#include "prefab\test\testprefabs.dm" +#include "subsystems\circuit.dm" +#include "subsystems\circuit_component.dm" +#include "tools\analyzer.dm" +#include "tools\debugger.dm" +#include "tools\detailer.dm" +#include "tools\printer.dm" +#include "tools\wirer.dm" +// END_INCLUDE +#endif diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/mods/content/integrated_electronics/assemblies/_assemblies.dm similarity index 98% rename from code/modules/integrated_electronics/core/assemblies.dm rename to mods/content/integrated_electronics/assemblies/_assemblies.dm index 4e784c115474..86339c892428 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/mods/content/integrated_electronics/assemblies/_assemblies.dm @@ -413,7 +413,7 @@ for(var/obj/item/integrated_circuit/input/S in assembly_components) S.attackby_react(used_item, user, user.get_intent()) return ..() - else if(IS_MULTITOOL(used_item) || istype(used_item, /obj/item/integrated_electronics/wirer) || istype(used_item, /obj/item/integrated_electronics/debugger)) + else if(IS_MULTITOOL(used_item) || istype(used_item, /obj/item/wirer) || istype(used_item, /obj/item/debugger)) if(opened) interact(user) return TRUE @@ -442,8 +442,8 @@ to_chat(user, "You slot \the [cell] inside \the [src]'s power supplier.") return TRUE return FALSE - else if(istype(used_item, /obj/item/integrated_electronics/detailer)) - var/obj/item/integrated_electronics/detailer/D = used_item + else if(istype(used_item, /obj/item/detailer)) + var/obj/item/detailer/D = used_item detail_color = D.detail_color update_icon() else if(IS_SCREWDRIVER(used_item)) @@ -543,12 +543,6 @@ desc = "It's a case, for building small electronics with. This one resembles a PDA." slot_flags = SLOT_LOWER_BODY | SLOT_ID -/obj/item/electronic_assembly/augment - name = "augment electronic assembly" - icon_state = "setup_augment" - desc = "It's a case, for building small electronics with. This one is designed to go inside a cybernetic augment." - circuit_flags = IC_FLAG_CAN_FIRE - /obj/item/electronic_assembly/medium name = "electronic mechanism" icon_state = "setup_medium" diff --git a/code/modules/augment/active/circuit.dm b/mods/content/integrated_electronics/assemblies/circuit_augment.dm similarity index 79% rename from code/modules/augment/active/circuit.dm rename to mods/content/integrated_electronics/assemblies/circuit_augment.dm index a6a86bd6ad61..cc3b522aa6ee 100644 --- a/code/modules/augment/active/circuit.dm +++ b/mods/content/integrated_electronics/assemblies/circuit_augment.dm @@ -1,3 +1,9 @@ +/obj/item/electronic_assembly/augment + name = "augment electronic assembly" + icon_state = "setup_augment" + desc = "It's a case, for building small electronics with. This one is designed to go inside a cybernetic augment." + circuit_flags = IC_FLAG_CAN_FIRE + /obj/item/organ/internal/augment/active/simple/circuit name = "integrated circuit frame" action_button_name = "Activate Circuit" @@ -6,7 +12,7 @@ holding = null //We must get the holding item externally //Limited to robolimbs augment_flags = AUGMENTATION_MECHANIC - desc = "A DIY modular assembly. Circuitry not included" + desc = "A DIY modular assembly. Circuitry not included." material = /decl/material/solid/metal/steel origin_tech = @'{"materials":1,"magnets":1,"engineering":1,"programming":2}' diff --git a/code/modules/integrated_electronics/core/saved_circuits.dm b/mods/content/integrated_electronics/circuit_serialization.dm similarity index 100% rename from code/modules/integrated_electronics/core/saved_circuits.dm rename to mods/content/integrated_electronics/circuit_serialization.dm diff --git a/code/unit_tests/integrated_circuits.dm b/mods/content/integrated_electronics/circuit_tests.dm similarity index 91% rename from code/unit_tests/integrated_circuits.dm rename to mods/content/integrated_electronics/circuit_tests.dm index 84de2ac2ff34..8188d49a3010 100644 --- a/code/unit_tests/integrated_circuits.dm +++ b/mods/content/integrated_electronics/circuit_tests.dm @@ -121,4 +121,15 @@ all_expected_outputs = list(list(5,null,null,null),list(null,6,null,null),list(null,null,7,null),list(null,null,null,8)) circuit_type = /obj/item/integrated_circuit/transfer/demultiplexer/medium -#undef IC_TEST_ANY_OUTPUT \ No newline at end of file +#undef IC_TEST_ANY_OUTPUT + +// Check prefab json. +/datum/unit_test/atoms_should_use_valid_json/get_json_to_check() + var/list/json_to_check = ..() + var/list/prefabs = decls_repository.get_decls_of_subtype(/decl/prefab/ic_assembly) + for(var/assembly_path in prefabs) + var/decl/prefab/ic_assembly/assembly = prefabs[assembly_path] + var/check_json = assembly.data + if(!isnull(check_json)) + LAZYSET(json_to_check, "[assembly_path].data", check_json) + return json_to_check \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/mods/content/integrated_electronics/components/_integrated_circuit.dm similarity index 98% rename from code/modules/integrated_electronics/core/integrated_circuit.dm rename to mods/content/integrated_electronics/components/_integrated_circuit.dm index fe377c2824e9..454b80a3b6ae 100644 --- a/code/modules/integrated_electronics/core/integrated_circuit.dm +++ b/mods/content/integrated_electronics/components/_integrated_circuit.dm @@ -253,7 +253,7 @@ a creative player the means to solve many problems. Circuits are held inside an if(href_list["link"]) linked = locate(href_list["link"]) in pin.linked - if(istype(held_item, /obj/item/integrated_electronics)) + if(istype(held_item, /obj/item/wirer) || istype(held_item, /obj/item/debugger)) pin.handle_wire(linked, held_item, href_list["act"], usr) . = IC_TOPIC_REFRESH else @@ -263,8 +263,8 @@ a creative player the means to solve many problems. Circuits are held inside an assembly.add_allowed_scanner(usr.ckey) else if(href_list["scan"]) - if(istype(held_item, /obj/item/integrated_electronics/debugger)) - var/obj/item/integrated_electronics/debugger/D = held_item + if(istype(held_item, /obj/item/debugger)) + var/obj/item/debugger/D = held_item if(D.accepting_refs) D.afterattack(src, usr, TRUE) . = IC_TOPIC_REFRESH diff --git a/code/modules/integrated_electronics/subtypes/access.dm b/mods/content/integrated_electronics/components/access.dm similarity index 100% rename from code/modules/integrated_electronics/subtypes/access.dm rename to mods/content/integrated_electronics/components/access.dm diff --git a/code/modules/integrated_electronics/subtypes/arithmetic.dm b/mods/content/integrated_electronics/components/arithmetic.dm similarity index 100% rename from code/modules/integrated_electronics/subtypes/arithmetic.dm rename to mods/content/integrated_electronics/components/arithmetic.dm diff --git a/code/modules/integrated_electronics/subtypes/converters.dm b/mods/content/integrated_electronics/components/converters.dm similarity index 100% rename from code/modules/integrated_electronics/subtypes/converters.dm rename to mods/content/integrated_electronics/components/converters.dm diff --git a/code/modules/integrated_electronics/subtypes/data_transfer.dm b/mods/content/integrated_electronics/components/data_transfer.dm similarity index 100% rename from code/modules/integrated_electronics/subtypes/data_transfer.dm rename to mods/content/integrated_electronics/components/data_transfer.dm diff --git a/code/modules/integrated_electronics/subtypes/filter.dm b/mods/content/integrated_electronics/components/filter.dm similarity index 100% rename from code/modules/integrated_electronics/subtypes/filter.dm rename to mods/content/integrated_electronics/components/filter.dm diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/mods/content/integrated_electronics/components/input.dm similarity index 100% rename from code/modules/integrated_electronics/subtypes/input.dm rename to mods/content/integrated_electronics/components/input.dm diff --git a/code/modules/integrated_electronics/subtypes/lists.dm b/mods/content/integrated_electronics/components/lists.dm similarity index 100% rename from code/modules/integrated_electronics/subtypes/lists.dm rename to mods/content/integrated_electronics/components/lists.dm diff --git a/code/modules/integrated_electronics/subtypes/logic.dm b/mods/content/integrated_electronics/components/logic.dm similarity index 100% rename from code/modules/integrated_electronics/subtypes/logic.dm rename to mods/content/integrated_electronics/components/logic.dm diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/mods/content/integrated_electronics/components/manipulation.dm similarity index 100% rename from code/modules/integrated_electronics/subtypes/manipulation.dm rename to mods/content/integrated_electronics/components/manipulation.dm diff --git a/code/modules/integrated_electronics/subtypes/memory.dm b/mods/content/integrated_electronics/components/memory.dm similarity index 100% rename from code/modules/integrated_electronics/subtypes/memory.dm rename to mods/content/integrated_electronics/components/memory.dm diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/mods/content/integrated_electronics/components/output.dm similarity index 100% rename from code/modules/integrated_electronics/subtypes/output.dm rename to mods/content/integrated_electronics/components/output.dm diff --git a/code/modules/integrated_electronics/passive/passive.dm b/mods/content/integrated_electronics/components/passive.dm similarity index 54% rename from code/modules/integrated_electronics/passive/passive.dm rename to mods/content/integrated_electronics/components/passive.dm index 02f03d48d7c4..9f635f56cc84 100644 --- a/code/modules/integrated_electronics/passive/passive.dm +++ b/mods/content/integrated_electronics/components/passive.dm @@ -1,4 +1,4 @@ -// 'Passive' components do not have any pins, and instead contribute in some form to the assembly holding them. +// 'Passive' components do not have any inputs, and instead contribute in some form to the assembly holding them. /obj/item/integrated_circuit/passive inputs = list() outputs = list() diff --git a/code/modules/integrated_electronics/subtypes/power.dm b/mods/content/integrated_electronics/components/power.dm similarity index 99% rename from code/modules/integrated_electronics/subtypes/power.dm rename to mods/content/integrated_electronics/components/power.dm index 527e9f751eb0..15e7214f6f34 100644 --- a/code/modules/integrated_electronics/subtypes/power.dm +++ b/mods/content/integrated_electronics/components/power.dm @@ -1,4 +1,4 @@ -/obj/item/integrated_circuit/power/ +/obj/item/integrated_circuit/power category_text = "Power - Active" /obj/item/integrated_circuit/power/transmitter diff --git a/code/modules/integrated_electronics/passive/power.dm b/mods/content/integrated_electronics/components/power_passive.dm similarity index 99% rename from code/modules/integrated_electronics/passive/power.dm rename to mods/content/integrated_electronics/components/power_passive.dm index 69ae5bae034c..f33dab219d4d 100644 --- a/code/modules/integrated_electronics/passive/power.dm +++ b/mods/content/integrated_electronics/components/power_passive.dm @@ -92,7 +92,6 @@ ethanol, nutriment, and blood in order of decreasing efficiency. It will consume fuel only if the battery can take more energy." atom_flags = ATOM_FLAG_OPEN_CONTAINER complexity = 4 - inputs = list() outputs = list("volume used" = IC_PINTYPE_NUMBER, "self reference" = IC_PINTYPE_REF) activators = list("push ref" = IC_PINTYPE_PULSE_IN) spawn_flags = IC_SPAWN_DEFAULT|IC_SPAWN_RESEARCH diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/mods/content/integrated_electronics/components/reagents.dm similarity index 100% rename from code/modules/integrated_electronics/subtypes/reagents.dm rename to mods/content/integrated_electronics/components/reagents.dm diff --git a/code/modules/integrated_electronics/subtypes/smart.dm b/mods/content/integrated_electronics/components/smart.dm similarity index 100% rename from code/modules/integrated_electronics/subtypes/smart.dm rename to mods/content/integrated_electronics/components/smart.dm diff --git a/code/modules/integrated_electronics/subtypes/time.dm b/mods/content/integrated_electronics/components/time.dm similarity index 100% rename from code/modules/integrated_electronics/subtypes/time.dm rename to mods/content/integrated_electronics/components/time.dm diff --git a/code/modules/integrated_electronics/subtypes/trig.dm b/mods/content/integrated_electronics/components/trig.dm similarity index 100% rename from code/modules/integrated_electronics/subtypes/trig.dm rename to mods/content/integrated_electronics/components/trig.dm diff --git a/mods/content/integrated_electronics/fabricator_designs.dm b/mods/content/integrated_electronics/fabricator_designs.dm new file mode 100644 index 000000000000..2018e9d5bae0 --- /dev/null +++ b/mods/content/integrated_electronics/fabricator_designs.dm @@ -0,0 +1,20 @@ +/datum/fabricator_recipe/tool/int_wirer + path = /obj/item/wirer + +/datum/fabricator_recipe/tool/int_debugger + path = /obj/item/debugger + +/datum/fabricator_recipe/tool/int_analyzer + path = /obj/item/analyzer + +/datum/fabricator_recipe/protolathe/integrated_printer + path = /obj/item/integrated_circuit_printer + +/datum/fabricator_recipe/protolathe/integrated_printer_upgrade_advanced + path = /obj/item/disk/integrated_circuit/upgrade/advanced + +/datum/fabricator_recipe/protolathe/integrated_printer_upgrade_clone + path = /obj/item/disk/integrated_circuit/upgrade/clone + +/datum/fabricator_recipe/robotics/augment/circuit + path = /obj/item/organ/internal/augment/active/simple/circuit diff --git a/code/modules/integrated_electronics/core/helpers.dm b/mods/content/integrated_electronics/helpers.dm similarity index 100% rename from code/modules/integrated_electronics/core/helpers.dm rename to mods/content/integrated_electronics/helpers.dm diff --git a/mods/content/integrated_electronics/overrides.dm b/mods/content/integrated_electronics/overrides.dm new file mode 100644 index 000000000000..f6fae6639ac8 --- /dev/null +++ b/mods/content/integrated_electronics/overrides.dm @@ -0,0 +1,12 @@ +// Allows the detailer to be used to set data cards' detail color, in addition to the paint sprayer. +/obj/item/card/data/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/detailer)) + var/obj/item/detailer/D = used_item + detail_color = D.detail_color + update_icon() + return TRUE + return ..() + +// Gives the research borg a hand tele. +/obj/item/robot_module/research + emag = /obj/abstract/prefab/hand_teleporter \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/pins.dm b/mods/content/integrated_electronics/pins/_pins.dm similarity index 95% rename from code/modules/integrated_electronics/core/pins.dm rename to mods/content/integrated_electronics/pins/_pins.dm index 14d5b38e1bfd..08f9194f2ca7 100644 --- a/code/modules/integrated_electronics/core/pins.dm +++ b/mods/content/integrated_electronics/pins/_pins.dm @@ -87,7 +87,7 @@ D [1]/ || return "(\[pulse\])" /datum/integrated_io/proc/display_pin_type() - return IC_FORMAT_ANY + return VAR_FORMAT_ANY /datum/integrated_io/activate/display_pin_type() return IC_FORMAT_PULSE @@ -105,16 +105,16 @@ D [1]/ || push_data() /datum/integrated_io/proc/handle_wire(datum/integrated_io/linked_pin, obj/item/tool, action, mob/living/user) - if(istype(tool, /obj/item/integrated_electronics/wirer)) - var/obj/item/integrated_electronics/wirer/wirer = tool + if(istype(tool, /obj/item/wirer)) + var/obj/item/wirer/wirer = tool if(linked_pin) wirer.wire(linked_pin, user) else wirer.wire(src, user) return TRUE - else if(istype(tool, /obj/item/integrated_electronics/debugger)) - var/obj/item/integrated_electronics/debugger/debugger = tool + else if(istype(tool, /obj/item/debugger)) + var/obj/item/debugger/debugger = tool debugger.write_data(src, user) return TRUE diff --git a/code/modules/integrated_electronics/core/special_pins/boolean_pin.dm b/mods/content/integrated_electronics/pins/boolean_pin.dm similarity index 96% rename from code/modules/integrated_electronics/core/special_pins/boolean_pin.dm rename to mods/content/integrated_electronics/pins/boolean_pin.dm index da59434b6534..b775aa9f8f89 100644 --- a/code/modules/integrated_electronics/core/special_pins/boolean_pin.dm +++ b/mods/content/integrated_electronics/pins/boolean_pin.dm @@ -18,7 +18,7 @@ push_data() /datum/integrated_io/boolean/display_pin_type() - return IC_FORMAT_BOOLEAN + return VAR_FORMAT_BOOLEAN /datum/integrated_io/boolean/display_data(var/input) if(data) diff --git a/code/modules/integrated_electronics/core/special_pins/char_pin.dm b/mods/content/integrated_electronics/pins/char_pin.dm similarity index 97% rename from code/modules/integrated_electronics/core/special_pins/char_pin.dm rename to mods/content/integrated_electronics/pins/char_pin.dm index 20f4190c71a2..0ab9a1c0f231 100644 --- a/code/modules/integrated_electronics/core/special_pins/char_pin.dm +++ b/mods/content/integrated_electronics/pins/char_pin.dm @@ -25,4 +25,4 @@ push_data() /datum/integrated_io/char/display_pin_type() - return IC_FORMAT_CHAR + return VAR_FORMAT_CHAR diff --git a/code/modules/integrated_electronics/core/special_pins/color_pin.dm b/mods/content/integrated_electronics/pins/color_pin.dm similarity index 98% rename from code/modules/integrated_electronics/core/special_pins/color_pin.dm rename to mods/content/integrated_electronics/pins/color_pin.dm index f7543de2f40b..39935b40ce14 100644 --- a/code/modules/integrated_electronics/core/special_pins/color_pin.dm +++ b/mods/content/integrated_electronics/pins/color_pin.dm @@ -35,7 +35,7 @@ push_data() /datum/integrated_io/color/display_pin_type() - return IC_FORMAT_COLOR + return VAR_FORMAT_COLOR /datum/integrated_io/color/display_data(var/input) if(!isnull(data)) diff --git a/code/modules/integrated_electronics/core/special_pins/dir_pin.dm b/mods/content/integrated_electronics/pins/dir_pin.dm similarity index 97% rename from code/modules/integrated_electronics/core/special_pins/dir_pin.dm rename to mods/content/integrated_electronics/pins/dir_pin.dm index 552479163590..d850514d2e74 100644 --- a/code/modules/integrated_electronics/core/special_pins/dir_pin.dm +++ b/mods/content/integrated_electronics/pins/dir_pin.dm @@ -23,7 +23,7 @@ holder.on_data_written() /datum/integrated_io/dir/display_pin_type() - return IC_FORMAT_DIR + return VAR_FORMAT_DIR /datum/integrated_io/dir/display_data(var/input) if(!isnull(data)) diff --git a/code/modules/integrated_electronics/core/special_pins/index_pin.dm b/mods/content/integrated_electronics/pins/index_pin.dm similarity index 96% rename from code/modules/integrated_electronics/core/special_pins/index_pin.dm rename to mods/content/integrated_electronics/pins/index_pin.dm index e904c4c6d00e..e0820c1888b3 100644 --- a/code/modules/integrated_electronics/core/special_pins/index_pin.dm +++ b/mods/content/integrated_electronics/pins/index_pin.dm @@ -18,4 +18,4 @@ holder.on_data_written() /datum/integrated_io/index/display_pin_type() - return IC_FORMAT_INDEX + return VAR_FORMAT_INDEX diff --git a/code/modules/integrated_electronics/core/special_pins/list_pin.dm b/mods/content/integrated_electronics/pins/list_pin.dm similarity index 99% rename from code/modules/integrated_electronics/core/special_pins/list_pin.dm rename to mods/content/integrated_electronics/pins/list_pin.dm index 60f7561e46e2..3c032fde965c 100644 --- a/code/modules/integrated_electronics/core/special_pins/list_pin.dm +++ b/mods/content/integrated_electronics/pins/list_pin.dm @@ -120,7 +120,7 @@ holder.on_data_written() /datum/integrated_io/lists/display_pin_type() - return IC_FORMAT_LIST + return VAR_FORMAT_LIST /datum/integrated_io/lists/Topic(href, href_list) if(!holder.check_interactivity(usr)) diff --git a/code/modules/integrated_electronics/core/special_pins/number_pin.dm b/mods/content/integrated_electronics/pins/number_pin.dm similarity index 96% rename from code/modules/integrated_electronics/core/special_pins/number_pin.dm rename to mods/content/integrated_electronics/pins/number_pin.dm index e37eea3d9342..827cb1bec5f6 100644 --- a/code/modules/integrated_electronics/core/special_pins/number_pin.dm +++ b/mods/content/integrated_electronics/pins/number_pin.dm @@ -14,4 +14,4 @@ holder.on_data_written() /datum/integrated_io/number/display_pin_type() - return IC_FORMAT_NUMBER \ No newline at end of file + return VAR_FORMAT_NUMBER \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/special_pins/ref_pin.dm b/mods/content/integrated_electronics/pins/ref_pin.dm similarity index 94% rename from code/modules/integrated_electronics/core/special_pins/ref_pin.dm rename to mods/content/integrated_electronics/pins/ref_pin.dm index 461965f254bc..b3f73205a715 100644 --- a/code/modules/integrated_electronics/core/special_pins/ref_pin.dm +++ b/mods/content/integrated_electronics/pins/ref_pin.dm @@ -11,4 +11,4 @@ holder.on_data_written() /datum/integrated_io/ref/display_pin_type() - return IC_FORMAT_REF \ No newline at end of file + return VAR_FORMAT_REF \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/special_pins/string_pin.dm b/mods/content/integrated_electronics/pins/string_pin.dm similarity index 97% rename from code/modules/integrated_electronics/core/special_pins/string_pin.dm rename to mods/content/integrated_electronics/pins/string_pin.dm index 30403c4bccc5..7b44e6951a5c 100644 --- a/code/modules/integrated_electronics/core/special_pins/string_pin.dm +++ b/mods/content/integrated_electronics/pins/string_pin.dm @@ -25,4 +25,4 @@ push_data() /datum/integrated_io/string/display_pin_type() - return IC_FORMAT_STRING + return VAR_FORMAT_STRING diff --git a/code/modules/integrated_electronics/core/prefab/prefab.dm b/mods/content/integrated_electronics/prefab/prefab.dm similarity index 91% rename from code/modules/integrated_electronics/core/prefab/prefab.dm rename to mods/content/integrated_electronics/prefab/prefab.dm index 7cc153f10a1c..ae769b301a79 100644 --- a/code/modules/integrated_electronics/core/prefab/prefab.dm +++ b/mods/content/integrated_electronics/prefab/prefab.dm @@ -25,15 +25,15 @@ return assembly return null -/obj/prefab +/obj/abstract/prefab name = "prefab spawn" icon = 'icons/misc/mark.dmi' icon_state = "X" color = COLOR_PURPLE - abstract_type = /obj/prefab + abstract_type = /obj/abstract/prefab var/prefab_type -/obj/prefab/Initialize() +/obj/abstract/prefab/Initialize() ..() if(loc) var/decl/prefab/prefab = GET_DECL(prefab_type) diff --git a/code/modules/integrated_electronics/core/prefab/prefabs.dm b/mods/content/integrated_electronics/prefab/prefabs.dm similarity index 72% rename from code/modules/integrated_electronics/core/prefab/prefabs.dm rename to mods/content/integrated_electronics/prefab/prefabs.dm index 0efa5181a661..41d1d8b8b4a1 100644 --- a/code/modules/integrated_electronics/core/prefab/prefabs.dm +++ b/mods/content/integrated_electronics/prefab/prefabs.dm @@ -3,6 +3,8 @@ data = @'{"assembly":{"type":"type-a electronic mechanism","name":"Hand Teleporter", "detail_color":"#5d99be"},"components":[{"type":"teleporter locator"},{"type":"wormhole generator"},{"type":"button","name":"Open Wormhole"}],"wires":[[[1,"O",1],[2,"I",1]],[[2,"A",1],[3,"A",1]]]}' power_cell_type = /obj/item/cell/hyper -/obj/prefab/hand_teleporter +/obj/abstract/prefab/hand_teleporter name = "hand teleporter" - prefab_type = /decl/prefab/ic_assembly/hand_teleporter \ No newline at end of file + prefab_type = /decl/prefab/ic_assembly/hand_teleporter + +OPTIONAL_SPAWNER(hand_tele, /obj/abstract/prefab/hand_teleporter) \ No newline at end of file diff --git a/code/modules/integrated_electronics/core/prefab/test/testprefabs.dm b/mods/content/integrated_electronics/prefab/test/testprefabs.dm similarity index 97% rename from code/modules/integrated_electronics/core/prefab/test/testprefabs.dm rename to mods/content/integrated_electronics/prefab/test/testprefabs.dm index c045f16f4a65..983536b1c873 100644 --- a/code/modules/integrated_electronics/core/prefab/test/testprefabs.dm +++ b/mods/content/integrated_electronics/prefab/test/testprefabs.dm @@ -3,6 +3,6 @@ data = @'{"assembly":{"type":"type-c electronic machine"},"components":[{"type":"starter"},{"type":"reagent funnel"},{"type":"big reagent storage"},{"type":"reagent pump","name":"Hot Pump","inputs":[[3,0,5]]},{"type":"reagent pump","name":"Cool Pump","inputs":[[3,0,5]]},{"type":"reagent heater","name":"Heater","inputs":[[1,0,80]]},{"type":"reagent cooler","name":"Cooler","inputs":[[1,0,-50]]},{"type":"button","name":"Heat And Cool"},{"type":"and gate","name":"Heater Active Check","inputs":[[1,0,0],[2,0,1]]},{"type":"and gate","name":"Cooler Active Check","inputs":[[1,0,0],[2,0,1]]},{"type":"custom delay circuit","name":"Heater Delay","inputs":[[1,0,100]]},{"type":"custom delay circuit","name":"Cooler Delay","inputs":[[1,0,100]]}],"wires":[[[1,"A",1],[3,"A",1]],[[1,"A",1],[6,"A",3]],[[1,"A",1],[7,"A",3]],[[2,"I",1],[3,"O",2]],[[3,"O",2],[4,"I",1]],[[3,"O",2],[5,"I",1]],[[4,"I",2],[6,"O",4]],[[4,"A",1],[8,"A",1]],[[4,"A",2],[6,"A",1]],[[5,"I",2],[7,"O",4]],[[5,"A",1],[8,"A",1]],[[5,"A",2],[7,"A",1]],[[6,"O",3],[9,"I",1]],[[6,"A",1],[11,"A",2]],[[6,"A",2],[9,"A",1]],[[7,"O",3],[10,"I",1]],[[7,"A",1],[12,"A",2]],[[7,"A",2],[10,"A",1]],[[9,"A",2],[11,"A",1]],[[10,"A",2],[12,"A",1]]]}' power_cell_type = /obj/item/cell/hyper -/obj/prefab/test_heatcool +/obj/abstract/prefab/test_heatcool name = "heating-cooling test" prefab_type = /decl/prefab/ic_assembly/test_heatercooler diff --git a/mods/content/integrated_electronics/random.dm b/mods/content/integrated_electronics/random.dm new file mode 100644 index 000000000000..34f557071fb4 --- /dev/null +++ b/mods/content/integrated_electronics/random.dm @@ -0,0 +1,4 @@ +/obj/random_multi/single_item/hand_tele + name = "Multi Point - Hand Teleporter" + id = "Hand teleporter" + item_path = /obj/abstract/prefab/hand_teleporter \ No newline at end of file diff --git a/code/controllers/subsystems/processing/circuit.dm b/mods/content/integrated_electronics/subsystems/circuit.dm similarity index 93% rename from code/controllers/subsystems/processing/circuit.dm rename to mods/content/integrated_electronics/subsystems/circuit.dm index 4151434dfe61..ccc6d5356e99 100644 --- a/code/controllers/subsystems/processing/circuit.dm +++ b/mods/content/integrated_electronics/subsystems/circuit.dm @@ -50,10 +50,10 @@ PROCESSING_SUBSYSTEM_DEF(circuit) circuit_fabricator_recipe_list["Assemblies"] = subtypesof(/obj/item/electronic_assembly) - list(/obj/item/electronic_assembly/medium, /obj/item/electronic_assembly/large, /obj/item/electronic_assembly/drone, /obj/item/electronic_assembly/wallmount) circuit_fabricator_recipe_list["Tools"] = list( - /obj/item/integrated_electronics/wirer, - /obj/item/integrated_electronics/debugger, - /obj/item/integrated_electronics/analyzer, - /obj/item/integrated_electronics/detailer, + /obj/item/wirer, + /obj/item/debugger, + /obj/item/analyzer, + /obj/item/detailer, /obj/item/card/data, /obj/item/card/data/full_color, /obj/item/card/data/disk diff --git a/code/controllers/subsystems/circuit_component.dm b/mods/content/integrated_electronics/subsystems/circuit_component.dm similarity index 100% rename from code/controllers/subsystems/circuit_component.dm rename to mods/content/integrated_electronics/subsystems/circuit_component.dm diff --git a/code/modules/admin/secrets/admin_secrets/toggle_circuits.dm b/mods/content/integrated_electronics/toggle_circuits_secret.dm similarity index 100% rename from code/modules/admin/secrets/admin_secrets/toggle_circuits.dm rename to mods/content/integrated_electronics/toggle_circuits_secret.dm diff --git a/code/modules/integrated_electronics/core/analyzer.dm b/mods/content/integrated_electronics/tools/analyzer.dm similarity index 83% rename from code/modules/integrated_electronics/core/analyzer.dm rename to mods/content/integrated_electronics/tools/analyzer.dm index ecc918cf4c26..6be5bec11856 100644 --- a/code/modules/integrated_electronics/core/analyzer.dm +++ b/mods/content/integrated_electronics/tools/analyzer.dm @@ -1,15 +1,18 @@ -/obj/item/integrated_electronics/analyzer +/obj/item/analyzer name = "circuit analyzer" desc = "This tool can scan an assembly and generate code necessary to recreate it in a circuit printer." icon = 'icons/obj/assemblies/circuit_analyzer.dmi' icon_state = ICON_STATE_WORLD + obj_flags = OBJ_FLAG_CONDUCTIBLE + w_class = ITEM_SIZE_SMALL + material = /decl/material/solid/metal/aluminium matter = list( /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/fiberglass = MATTER_AMOUNT_TRACE, /decl/material/solid/organic/plastic = MATTER_AMOUNT_TRACE ) -/obj/item/integrated_electronics/analyzer/afterattack(var/atom/A, var/mob/living/user) +/obj/item/analyzer/afterattack(var/atom/A, var/mob/living/user) . = ..() if(istype(A, /obj/item/electronic_assembly)) var/saved = "[A.name] analyzed! On circuit printers with cloning enabled, you may use the code below to clone the circuit:

[SScircuit.save_electronic_assembly(A)]" diff --git a/code/modules/integrated_electronics/core/debugger.dm b/mods/content/integrated_electronics/tools/debugger.dm similarity index 91% rename from code/modules/integrated_electronics/core/debugger.dm rename to mods/content/integrated_electronics/tools/debugger.dm index 2c74e56a5c9a..32e88b5cfa28 100644 --- a/code/modules/integrated_electronics/core/debugger.dm +++ b/mods/content/integrated_electronics/tools/debugger.dm @@ -1,14 +1,14 @@ -/obj/item/integrated_electronics/debugger +/obj/item/debugger name = "circuit debugger" desc = "This small tool allows one working with custom machinery to directly set data to a specific pin, useful for writing \ settings to specific circuits, or for debugging purposes. It can also pulse activation pins." icon = 'icons/obj/assemblies/electronic_tools.dmi' icon_state = "debugger" - obj_flags = OBJ_FLAG_CONDUCTIBLE item_flags = ITEM_FLAG_NO_BLUDGEON - w_class = ITEM_SIZE_SMALL var/data_to_write = null var/accepting_refs = FALSE + obj_flags = OBJ_FLAG_CONDUCTIBLE + w_class = ITEM_SIZE_SMALL material = /decl/material/solid/metal/aluminium matter = list( /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT, @@ -16,7 +16,7 @@ /decl/material/solid/organic/plastic = MATTER_AMOUNT_TRACE ) -/obj/item/integrated_electronics/debugger/attack_self(mob/user) +/obj/item/debugger/attack_self(mob/user) var/type_to_use = input("Please choose a type to use.","[src] type setting") as null|anything in list("string","number","ref", "null") var/new_data = null @@ -42,7 +42,7 @@ data_to_write = null to_chat(user, "You set \the [src]'s memory to absolutely nothing.") -/obj/item/integrated_electronics/debugger/afterattack(atom/target, mob/living/user, proximity) +/obj/item/debugger/afterattack(atom/target, mob/living/user, proximity) . = ..() if(accepting_refs && proximity) data_to_write = weakref(target) @@ -51,7 +51,7 @@ now off.") accepting_refs = FALSE -/obj/item/integrated_electronics/debugger/proc/write_data(var/datum/integrated_io/io, mob/user) +/obj/item/debugger/proc/write_data(var/datum/integrated_io/io, mob/user) if(io.io_type == DATA_CHANNEL) io.write_data_to_pin(data_to_write) var/data_to_show = data_to_write diff --git a/code/modules/integrated_electronics/core/detailer.dm b/mods/content/integrated_electronics/tools/detailer.dm similarity index 84% rename from code/modules/integrated_electronics/core/detailer.dm rename to mods/content/integrated_electronics/tools/detailer.dm index 302140e38ce5..fe71e09208d4 100644 --- a/code/modules/integrated_electronics/core/detailer.dm +++ b/mods/content/integrated_electronics/tools/detailer.dm @@ -1,11 +1,14 @@ #define SCAN_COLOR "SCAN" -/obj/item/integrated_electronics/detailer +/obj/item/detailer name = "assembly detailer" desc = "A combination autopainter and flash anodizer designed to give electronic assemblies a colorful, wear-resistant finish." icon = 'icons/obj/assemblies/electronic_tools.dmi' icon_state = "detailer" item_flags = ITEM_FLAG_NO_BLUDGEON + obj_flags = OBJ_FLAG_CONDUCTIBLE + w_class = ITEM_SIZE_SMALL + material = /decl/material/solid/metal/aluminium matter = list( /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/fiberglass = MATTER_AMOUNT_TRACE, @@ -33,15 +36,15 @@ "\[SCAN FROM ASSEMBLY\]" = SCAN_COLOR ) -/obj/item/integrated_electronics/detailer/Initialize() +/obj/item/detailer/Initialize() .=..() update_icon() -/obj/item/integrated_electronics/detailer/on_update_icon() +/obj/item/detailer/on_update_icon() . = ..() add_overlay(overlay_image('icons/obj/assemblies/electronic_tools.dmi', "detailer-color", detail_color)) -/obj/item/integrated_electronics/detailer/attack_self(mob/user) +/obj/item/detailer/attack_self(mob/user) var/color_choice = input(user, "Select color.", "Assembly Detailer") as null|anything in color_list if(!color_list[color_choice]) return @@ -55,7 +58,7 @@ detail_color = color_list[color_choice] update_icon() -/obj/item/integrated_electronics/detailer/afterattack(atom/target, mob/living/user, proximity) +/obj/item/detailer/afterattack(atom/target, mob/living/user, proximity) . = ..() if(!scanning_color || !proximity) return . @@ -67,5 +70,5 @@ var/obj/item/I = target detail_color = I.get_assembly_detail_color() -/obj/item/integrated_electronics/detailer/get_assembly_detail_color() +/obj/item/detailer/get_assembly_detail_color() return detail_color diff --git a/code/modules/integrated_electronics/core/printer.dm b/mods/content/integrated_electronics/tools/printer.dm similarity index 100% rename from code/modules/integrated_electronics/core/printer.dm rename to mods/content/integrated_electronics/tools/printer.dm diff --git a/code/modules/integrated_electronics/core/wirer.dm b/mods/content/integrated_electronics/tools/wirer.dm similarity index 91% rename from code/modules/integrated_electronics/core/wirer.dm rename to mods/content/integrated_electronics/tools/wirer.dm index 4b0b6749ca3f..365660a1ac58 100644 --- a/code/modules/integrated_electronics/core/wirer.dm +++ b/mods/content/integrated_electronics/tools/wirer.dm @@ -3,13 +3,16 @@ #define UNWIRE "unwire" #define UNWIRING "unwiring" -/obj/item/integrated_electronics/wirer +/obj/item/wirer name = "circuit wirer" desc = "It's a small wiring tool, with a wire roll, electric soldering iron, wire cutter, and more in one package. \ The wires used are generally useful for small electronics, such as circuitboards and breadboards, as opposed to larger wires \ used for power or data transmission." icon = 'icons/obj/assemblies/electronic_tools.dmi' icon_state = "wirer-wire" + obj_flags = OBJ_FLAG_CONDUCTIBLE + w_class = ITEM_SIZE_SMALL + material = /decl/material/solid/metal/aluminium matter = list( /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/fiberglass = MATTER_AMOUNT_TRACE, @@ -18,11 +21,11 @@ var/datum/integrated_io/selected_io = null var/mode = WIRE -/obj/item/integrated_electronics/wirer/on_update_icon() +/obj/item/wirer/on_update_icon() . = ..() icon_state = "wirer-[mode]" -/obj/item/integrated_electronics/wirer/proc/wire(var/datum/integrated_io/io, mob/user) +/obj/item/wirer/proc/wire(var/datum/integrated_io/io, mob/user) if(!io.holder.assembly) to_chat(user, "\The [io.holder] needs to be secured inside an assembly first.") return @@ -80,7 +83,7 @@ to_chat(user, "\The [selected_io.holder]'s [selected_io.name] and \the [io.holder]'s \ [io.name] are not connected.") -/obj/item/integrated_electronics/wirer/proc/select_io(datum/integrated_io/io) +/obj/item/wirer/proc/select_io(datum/integrated_io/io) if(selected_io) unselect_io(selected_io) selected_io = io @@ -91,7 +94,7 @@ if(WIRE) mode = WIRING -/obj/item/integrated_electronics/wirer/proc/unselect_io(datum/integrated_io/io) +/obj/item/wirer/proc/unselect_io(datum/integrated_io/io) if(selected_io != io) return events_repository.unregister(/decl/observ/destroyed, selected_io, src) @@ -102,7 +105,7 @@ if(WIRING) mode = WIRE -/obj/item/integrated_electronics/wirer/attack_self(mob/user) +/obj/item/wirer/attack_self(mob/user) switch(mode) if(WIRE) mode = UNWIRE diff --git a/mods/content/xenobiology/_xenobiology.dme b/mods/content/xenobiology/_xenobiology.dme index 4057d6b485bd..a2d03305ef6a 100644 --- a/mods/content/xenobiology/_xenobiology.dme +++ b/mods/content/xenobiology/_xenobiology.dme @@ -3,7 +3,6 @@ // BEGIN_INCLUDE #include "_xenobiology.dm" #include "achievement.dm" -#include "circuit.dm" #include "emotes.dm" #include "food.dm" #include "overrides.dm" diff --git a/mods/~compatibility/patches/circuits.dm b/mods/~compatibility/patches/circuits.dm new file mode 100644 index 000000000000..457c3b4f855f --- /dev/null +++ b/mods/~compatibility/patches/circuits.dm @@ -0,0 +1,8 @@ +// Add xenobiology/slimes modpack circuits. +#ifdef CONTENT_PACK_XENOBIO +#include "circuits/xenobio_circuits.dm" +#endif +// Add circuit items to dungeon loot. +#ifdef MODPACK_DUNGEON_LOOT +#include "circuits/loot_circuits.dm" +#endif \ No newline at end of file diff --git a/mods/~compatibility/patches/circuits/loot_circuits.dm b/mods/~compatibility/patches/circuits/loot_circuits.dm new file mode 100644 index 000000000000..671660dbd2ce --- /dev/null +++ b/mods/~compatibility/patches/circuits/loot_circuits.dm @@ -0,0 +1,6 @@ +/obj/structure/loot_pile/maint/technical/get_uncommon_loot() + var/static/injected = FALSE + . = ..() + if(!injected) + . += /obj/item/disk/integrated_circuit/upgrade/advanced + injected = TRUE \ No newline at end of file diff --git a/mods/content/xenobiology/circuit.dm b/mods/~compatibility/patches/circuits/xenobio_circuits.dm similarity index 100% rename from mods/content/xenobiology/circuit.dm rename to mods/~compatibility/patches/circuits/xenobio_circuits.dm diff --git a/mods/~compatibility/~compatibility.dm b/mods/~compatibility/~compatibility.dm index b1c3329ee77a..84f09c182555 100644 --- a/mods/~compatibility/~compatibility.dm +++ b/mods/~compatibility/~compatibility.dm @@ -25,4 +25,8 @@ #ifdef MODPACK_CORPORATE #include "patches/corporate.dm" +#endif + +#ifdef CONTENT_PACK_CIRCUITS +#include "patches/circuits.dm" #endif \ No newline at end of file diff --git a/nebula.dme b/nebula.dme index a897c4435032..3a87fe3149e2 100644 --- a/nebula.dme +++ b/nebula.dme @@ -54,7 +54,6 @@ #include "code\__defines\holomap.dm" #include "code\__defines\hud.dm" #include "code\__defines\hydroponics.dm" -#include "code\__defines\integrated_circuits.dm" #include "code\__defines\intent.dm" #include "code\__defines\interactions.dm" #include "code\__defines\inventory_sizes.dm" @@ -66,6 +65,7 @@ #include "code\__defines\lighting.dm" #include "code\__defines\lists.dm" #include "code\__defines\machinery.dm" +#include "code\__defines\machinery_public_vars.dm" #include "code\__defines\mapping.dm" #include "code\__defines\materials.dm" #include "code\__defines\math_physics.dm" @@ -271,7 +271,6 @@ #include "code\controllers\subsystems\ambience.dm" #include "code\controllers\subsystems\ao.dm" #include "code\controllers\subsystems\atoms.dm" -#include "code\controllers\subsystems\circuit_component.dm" #include "code\controllers\subsystems\configuration.dm" #include "code\controllers\subsystems\daycycle.dm" #include "code\controllers\subsystems\disposals.dm" @@ -333,7 +332,6 @@ #include "code\controllers\subsystems\mob_ai\mob_ai.dm" #include "code\controllers\subsystems\processing\airflow.dm" #include "code\controllers\subsystems\processing\chatter.dm" -#include "code\controllers\subsystems\processing\circuit.dm" #include "code\controllers\subsystems\processing\fast_process.dm" #include "code\controllers\subsystems\processing\graphs.dm" #include "code\controllers\subsystems\processing\mobs.dm" @@ -1688,7 +1686,6 @@ #include "code\modules\admin\secrets\admin_secrets\show_crew_manifest.dm" #include "code\modules\admin\secrets\admin_secrets\show_game_mode.dm" #include "code\modules\admin\secrets\admin_secrets\show_law_changes.dm" -#include "code\modules\admin\secrets\admin_secrets\toggle_circuits.dm" #include "code\modules\admin\secrets\admin_secrets\toggle_overmap_movement.dm" #include "code\modules\admin\secrets\admin_secrets\traitors_and_objectives.dm" #include "code\modules\admin\secrets\debug\toggle_harddel.dm" @@ -1790,7 +1787,6 @@ #include "code\modules\augment\helping_hands.dm" #include "code\modules\augment\simple.dm" #include "code\modules\augment\active\armblades.dm" -#include "code\modules\augment\active\circuit.dm" #include "code\modules\augment\active\cyberbrain.dm" #include "code\modules\augment\active\polytool.dm" #include "code\modules\augment\active\tool\engineering.dm" @@ -2607,48 +2603,6 @@ #include "code\modules\implants\implant_types\tracking.dm" #include "code\modules\implants\implant_types\translator.dm" #include "code\modules\implants\implant_types\uplink.dm" -#include "code\modules\integrated_electronics\_defines.dm" -#include "code\modules\integrated_electronics\core\_electronics.dm" -#include "code\modules\integrated_electronics\core\analyzer.dm" -#include "code\modules\integrated_electronics\core\assemblies.dm" -#include "code\modules\integrated_electronics\core\debugger.dm" -#include "code\modules\integrated_electronics\core\detailer.dm" -#include "code\modules\integrated_electronics\core\helpers.dm" -#include "code\modules\integrated_electronics\core\integrated_circuit.dm" -#include "code\modules\integrated_electronics\core\pins.dm" -#include "code\modules\integrated_electronics\core\printer.dm" -#include "code\modules\integrated_electronics\core\saved_circuits.dm" -#include "code\modules\integrated_electronics\core\wirer.dm" -#include "code\modules\integrated_electronics\core\prefab\prefab.dm" -#include "code\modules\integrated_electronics\core\prefab\prefabs.dm" -#include "code\modules\integrated_electronics\core\prefab\test\testprefabs.dm" -#include "code\modules\integrated_electronics\core\special_pins\boolean_pin.dm" -#include "code\modules\integrated_electronics\core\special_pins\char_pin.dm" -#include "code\modules\integrated_electronics\core\special_pins\color_pin.dm" -#include "code\modules\integrated_electronics\core\special_pins\dir_pin.dm" -#include "code\modules\integrated_electronics\core\special_pins\index_pin.dm" -#include "code\modules\integrated_electronics\core\special_pins\list_pin.dm" -#include "code\modules\integrated_electronics\core\special_pins\number_pin.dm" -#include "code\modules\integrated_electronics\core\special_pins\ref_pin.dm" -#include "code\modules\integrated_electronics\core\special_pins\string_pin.dm" -#include "code\modules\integrated_electronics\passive\passive.dm" -#include "code\modules\integrated_electronics\passive\power.dm" -#include "code\modules\integrated_electronics\subtypes\access.dm" -#include "code\modules\integrated_electronics\subtypes\arithmetic.dm" -#include "code\modules\integrated_electronics\subtypes\converters.dm" -#include "code\modules\integrated_electronics\subtypes\data_transfer.dm" -#include "code\modules\integrated_electronics\subtypes\filter.dm" -#include "code\modules\integrated_electronics\subtypes\input.dm" -#include "code\modules\integrated_electronics\subtypes\lists.dm" -#include "code\modules\integrated_electronics\subtypes\logic.dm" -#include "code\modules\integrated_electronics\subtypes\manipulation.dm" -#include "code\modules\integrated_electronics\subtypes\memory.dm" -#include "code\modules\integrated_electronics\subtypes\output.dm" -#include "code\modules\integrated_electronics\subtypes\power.dm" -#include "code\modules\integrated_electronics\subtypes\reagents.dm" -#include "code\modules\integrated_electronics\subtypes\smart.dm" -#include "code\modules\integrated_electronics\subtypes\time.dm" -#include "code\modules\integrated_electronics\subtypes\trig.dm" #include "code\modules\interactions\_interactions.dm" #include "code\modules\interactions\interactions_atom.dm" #include "code\modules\interactions\interactions_reagents.dm" @@ -4066,7 +4020,6 @@ #include "code\unit_tests\fusion_plants.dm" #include "code\unit_tests\graph_tests.dm" #include "code\unit_tests\icon_tests.dm" -#include "code\unit_tests\integrated_circuits.dm" #include "code\unit_tests\items.dm" #include "code\unit_tests\job_tests.dm" #include "code\unit_tests\json.dm" diff --git a/tools/map_migrations/0000_legacy.txt b/tools/map_migrations/0000_legacy.txt index ccac8405c68a..7f3abebba23b 100644 --- a/tools/map_migrations/0000_legacy.txt +++ b/tools/map_migrations/0000_legacy.txt @@ -151,7 +151,7 @@ /obj/effect/decal/remains/@SUBTYPES : /obj/item/remains/@SUBTYPES{@OLD} # Circuit prefabs -/obj/item/hand_tele : /obj/prefab/hand_teleporter{@OLD} +/obj/item/hand_tele : /obj/abstract/prefab/hand_teleporter{@OLD} # Filing cabinets /obj/structure/filingcabinet : /obj/structure/filing_cabinet{@OLD} From ba8899240e48d08eaa091145a826b4716ec1984d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 9 Sep 2025 15:29:10 -0400 Subject: [PATCH 18/36] Add map migrations for circuit modpack changes --- tools/map_migrations/5056_circuit_repaths.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 tools/map_migrations/5056_circuit_repaths.txt diff --git a/tools/map_migrations/5056_circuit_repaths.txt b/tools/map_migrations/5056_circuit_repaths.txt new file mode 100644 index 000000000000..08bf6ca0318b --- /dev/null +++ b/tools/map_migrations/5056_circuit_repaths.txt @@ -0,0 +1,4 @@ +# PR #5056 removed `/obj/item/integrated_electronics` type +/obj/item/integrated_electronics/@SUBTYPES : /obj/item/@SUBTYPES{@OLD} +# PR #5056 repathed `/obj/prefab` to `/obj/abstract/prefab` +/obj/prefab/@SUBTYPES : /obj/abstract/prefab/@SUBTYPES{@OLD} From aed3446accbc7ada8f4523cee9df043532339e26 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 25 Sep 2025 21:03:53 -0400 Subject: [PATCH 19/36] Implement initial network ID and key on network receivers --- .../machinery/_machines_base/stock_parts/network_lock.dm | 6 ------ .../_machines_base/stock_parts/network_receiver.dm | 9 ++++++++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/code/game/machinery/_machines_base/stock_parts/network_lock.dm b/code/game/machinery/_machines_base/stock_parts/network_lock.dm index f3be2c31c429..b3a275a51b6c 100644 --- a/code/game/machinery/_machines_base/stock_parts/network_lock.dm +++ b/code/game/machinery/_machines_base/stock_parts/network_lock.dm @@ -8,8 +8,6 @@ base_type = /obj/item/stock_parts/network_receiver/network_lock var/auto_deny_all // Set this to TRUE to deny all access attempts if network connection is lost. - var/initial_network_id // The address to the network - var/initial_network_key // network KEY var/selected_parent_group // Current selected parent_group for access assignment. var/list/groups // List of lists of groups. In order to access the device, users must have membership in at least one @@ -22,10 +20,6 @@ var/interact_sounds = list("keyboard", "keystroke") var/interact_sound_volume = 40 -/obj/item/stock_parts/network_receiver/network_lock/modify_mapped_vars(map_hash) - ..() - ADJUST_TAG_VAR(initial_network_id, map_hash) - /obj/item/stock_parts/network_receiver/network_lock/emag_act(remaining_charges, mob/user, emag_source) . = ..() if(istype(loc, /obj/machinery)) // Don't emag it outside; you can just cut access without it anyway. diff --git a/code/game/machinery/_machines_base/stock_parts/network_receiver.dm b/code/game/machinery/_machines_base/stock_parts/network_receiver.dm index 1b09080e57c1..aca5dd651908 100644 --- a/code/game/machinery/_machines_base/stock_parts/network_receiver.dm +++ b/code/game/machinery/_machines_base/stock_parts/network_receiver.dm @@ -5,10 +5,17 @@ desc = "A network receiver designed for use with machinery otherwise disconnected from a network." icon_state = "net_lock" part_flags = PART_FLAG_QDEL + var/initial_network_id // The address to the network + var/initial_network_key // network KEY + +/obj/item/stock_parts/network_receiver/network_lock/modify_mapped_vars(map_hash) + ..() + ADJUST_TAG_VAR(initial_network_id, map_hash) + ADJUST_TAG_VAR(initial_network_key, map_hash) /obj/item/stock_parts/network_receiver/Initialize(ml, material_key) . = ..() - set_extension(src, /datum/extension/network_device/stock_part) + set_extension(src, /datum/extension/network_device/stock_part, initial_network_id, initial_network_key) /obj/item/stock_parts/network_receiver/on_install(obj/machinery/machine) . = ..() From 99be960e7e19e42bded1677d91e5e28e1a9e87c4 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 25 Sep 2025 21:04:25 -0400 Subject: [PATCH 20/36] Fix network key not adjusting based on map hash --- .../machinery/_machines_base/stock_parts/network_receiver.dm | 2 +- code/game/objects/items/devices/radio/radio.dm | 5 +++++ code/modules/fabrication/_fabricator.dm | 1 + code/modules/research/design_console.dm | 1 + code/modules/research/design_database.dm | 1 + code/modules/research/design_database_analyzer.dm | 1 + 6 files changed, 10 insertions(+), 1 deletion(-) diff --git a/code/game/machinery/_machines_base/stock_parts/network_receiver.dm b/code/game/machinery/_machines_base/stock_parts/network_receiver.dm index aca5dd651908..b240744fa3d7 100644 --- a/code/game/machinery/_machines_base/stock_parts/network_receiver.dm +++ b/code/game/machinery/_machines_base/stock_parts/network_receiver.dm @@ -8,7 +8,7 @@ var/initial_network_id // The address to the network var/initial_network_key // network KEY -/obj/item/stock_parts/network_receiver/network_lock/modify_mapped_vars(map_hash) +/obj/item/stock_parts/network_receiver/modify_mapped_vars(map_hash) ..() ADJUST_TAG_VAR(initial_network_id, map_hash) ADJUST_TAG_VAR(initial_network_key, map_hash) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 92c10b97b1bb..fd4ef2152a3c 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -95,6 +95,11 @@ if(analog && frequency) analog_radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT) +/obj/item/radio/modify_mapped_vars(map_hash) + ..() + ADJUST_TAG_VAR(initial_network_id, map_hash) + ADJUST_TAG_VAR(initial_network_key, map_hash) + /obj/item/radio/Initialize() . = ..() wires = new(src) diff --git a/code/modules/fabrication/_fabricator.dm b/code/modules/fabrication/_fabricator.dm index d10d5064bc4f..23123ebfbdbb 100644 --- a/code/modules/fabrication/_fabricator.dm +++ b/code/modules/fabrication/_fabricator.dm @@ -96,6 +96,7 @@ /obj/machinery/fabricator/modify_mapped_vars(map_hash) ..() ADJUST_TAG_VAR(initial_network_id, map_hash) + ADJUST_TAG_VAR(initial_network_key, map_hash) /obj/machinery/fabricator/handle_post_network_connection() ..() diff --git a/code/modules/research/design_console.dm b/code/modules/research/design_console.dm index 5e2e43978ad3..10af9ac6bc97 100644 --- a/code/modules/research/design_console.dm +++ b/code/modules/research/design_console.dm @@ -26,6 +26,7 @@ /obj/machinery/computer/design_console/modify_mapped_vars(map_hash) ..() ADJUST_TAG_VAR(initial_network_id, map_hash) + ADJUST_TAG_VAR(initial_network_key, map_hash) /obj/machinery/computer/design_console/RefreshParts() . = ..() diff --git a/code/modules/research/design_database.dm b/code/modules/research/design_database.dm index 5c5a6b3cc410..bc52c9d40f21 100644 --- a/code/modules/research/design_database.dm +++ b/code/modules/research/design_database.dm @@ -106,6 +106,7 @@ var/global/list/default_initial_tech_levels /obj/machinery/design_database/modify_mapped_vars(map_hash) ..() ADJUST_TAG_VAR(initial_network_id, map_hash) + ADJUST_TAG_VAR(initial_network_key, map_hash) /obj/machinery/design_database/handle_post_network_connection() ..() diff --git a/code/modules/research/design_database_analyzer.dm b/code/modules/research/design_database_analyzer.dm index e4d6d06669d5..6d57b82a0633 100644 --- a/code/modules/research/design_database_analyzer.dm +++ b/code/modules/research/design_database_analyzer.dm @@ -23,6 +23,7 @@ /obj/machinery/destructive_analyzer/modify_mapped_vars(map_hash) ..() ADJUST_TAG_VAR(initial_network_id, map_hash) + ADJUST_TAG_VAR(initial_network_key, map_hash) /obj/machinery/destructive_analyzer/RefreshParts() var/T = 0 From bde57a66fbcdf50bd5d59dcc17d3914d1f39f57a Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sat, 27 Sep 2025 23:22:03 +1000 Subject: [PATCH 21/36] Expanding mob controller handler-directing logic. --- code/datums/ai/_ai.dm | 24 ++++++++++++++++++++++-- code/datums/ai/hunter.dm | 40 ++++++++++++++++++++++------------------ 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/code/datums/ai/_ai.dm b/code/datums/ai/_ai.dm index 9c943dadb4fb..628dc3639b3c 100644 --- a/code/datums/ai/_ai.dm +++ b/code/datums/ai/_ai.dm @@ -2,7 +2,7 @@ * * 1. AI should not implement any bespoke mob logic within the proc it uses * to trigger or respond to game events. It should share entrypoints with - * action performed by players and should respect the same intents, etc. + * actions performed by players and should respect the same intents, etc. * that players have to manage, through the same procs players use. This * should mean that players can be slotted into the pilot seat of any mob, * suspending AI behavior, and should then be able to freely use any of the @@ -79,6 +79,9 @@ /// How long minimum between scans. var/target_scan_delay = 1 SECOND + /// Last mob to attempt to handle this mob. + var/weakref/last_handler + /datum/mob_controller/New(var/mob/living/target_body) body = target_body if(expected_type && !istype(body, expected_type)) @@ -215,4 +218,21 @@ if(!scary_grabber) return if(spooked_by_grab && !is_friend(scary_grabber)) - retaliate(scary_grabber) \ No newline at end of file + retaliate(scary_grabber) + +// General stubs for when another mob has directed this mob to attack. +/datum/mob_controller/proc/check_handler_can_order(mob/handler, atom/target, intent_flags) + return is_friend(handler) + +/datum/mob_controller/proc/process_handler_target(mob/handler, atom/target, intent_flags) + if(!check_handler_can_order(handler, target, intent_flags)) + return process_handler_failure(handler, target) + last_handler = weakref(handler) + return TRUE + +/datum/mob_controller/proc/process_handler_failure(mob/handler, atom/target) + return FALSE + +/datum/mob_controller/proc/process_holder_interaction(mob/handler) + last_handler = weakref(handler) + return body?.attack_hand_with_interaction_checks(handler) diff --git a/code/datums/ai/hunter.dm b/code/datums/ai/hunter.dm index e60294d4a87e..052d012fca3e 100644 --- a/code/datums/ai/hunter.dm +++ b/code/datums/ai/hunter.dm @@ -36,51 +36,55 @@ /datum/mob_controller/passive/hunter/get_target(atom/new_target) if(isnull(hunt_target)) return null - var/mob/living/prey = hunt_target.resolve() + var/atom/prey = hunt_target.resolve() if(!istype(prey) || QDELETED(prey)) set_target(null) return null return prey /datum/mob_controller/passive/hunter/set_target(atom/new_target) - if(isnull(new_target) || isliving(new_target)) - hunt_target = new_target ? weakref(new_target) : null - return TRUE - return FALSE + hunt_target = new_target ? weakref(new_target) : null + return TRUE /datum/mob_controller/passive/hunter/do_process(time_elapsed) - if(!(. = ..())) return - if(body.incapacitated() || body.current_posture?.prone || body.buckled || flee_target || !get_target()) return + process_hunting(get_target()) + +/datum/mob_controller/passive/hunter/proc/process_hunting(atom/target) - var/mob/living/target = get_target() if(!istype(target) || QDELETED(target) || !(target in view(body))) set_target(null) resume_wandering() - return + return FALSE // Find or pursue the target. if(!body.Adjacent(target)) stop_wandering() body.start_automove(target) - return + return FALSE - // Hunt/consume the target. - if(target.stat != DEAD) - try_attack_prey(target) + if(!ismob(target)) + return TRUE // Indicates a valid target that this base proc does not handle. - if(QDELETED(target)) + // Hunt/consume the target. + . = FALSE // we handle mobs already + var/mob/prey = target + if(prey.stat != DEAD && (!is_friend(prey) || !handle_friend_hunting(prey))) + try_attack_prey(prey) + if(QDELETED(prey)) set_target(null) resume_wandering() return - - if(target.stat != DEAD) + if(prey.stat != DEAD) return - // Eat the mob. set_target(null) resume_wandering() - consume_prey(target) + consume_prey(prey) + +// Stub for hawks to return to their handler and dock with the mothership. +/datum/mob_controller/passive/hunter/proc/handle_friend_hunting(mob/friend) + return FALSE From 6dc7aa0bbfa792b9c9b64e0bcab5c8c58686d18d Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sat, 27 Sep 2025 23:22:18 +1000 Subject: [PATCH 22/36] Allowing scooping of mobs to silence messages. --- code/modules/mob/grab/simple/simple_control.dm | 8 ++++---- .../mob/living/simple_animal/hostile/slug.dm | 5 +++-- code/modules/mob_holder/holder_mobs.dm | 18 +++++++++++------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/code/modules/mob/grab/simple/simple_control.dm b/code/modules/mob/grab/simple/simple_control.dm index 62eb60e27292..bcab5545f070 100644 --- a/code/modules/mob/grab/simple/simple_control.dm +++ b/code/modules/mob/grab/simple/simple_control.dm @@ -38,13 +38,13 @@ // Override these for mobs that will respond to instructions from a rider. /mob/living/proc/handle_rider_harm_order(mob/user, atom/target, proximity) - return FALSE + return istype(ai) ? ai.process_handler_target(user, target, I_FLAG_HARM) : FALSE /mob/living/proc/handle_rider_grab_order(mob/user, atom/target, proximity) - return FALSE + return istype(ai) ? ai.process_handler_target(user, target, I_FLAG_GRAB) : FALSE /mob/living/proc/handle_rider_disarm_order(mob/user, atom/target, proximity) - return FALSE + return istype(ai) ? ai.process_handler_target(user, target, I_FLAG_DISARM) : FALSE /mob/living/proc/handle_rider_help_order(mob/user, atom/target, proximity) - return FALSE + return istype(ai) ? ai.process_handler_target(user, target, I_FLAG_HELP) : FALSE diff --git a/code/modules/mob/living/simple_animal/hostile/slug.dm b/code/modules/mob/living/simple_animal/hostile/slug.dm index 4218f9176bfa..bd2d79349b23 100644 --- a/code/modules/mob/living/simple_animal/hostile/slug.dm +++ b/code/modules/mob/living/simple_animal/hostile/slug.dm @@ -35,10 +35,11 @@ /mob/living/simple_animal/hostile/slug/proc/check_friendly_species(var/mob/living/M) return istype(M) && M.faction == faction -/mob/living/simple_animal/hostile/slug/get_scooped(var/mob/living/target, var/mob/living/initiator) +/mob/living/simple_animal/hostile/slug/get_scooped(mob/living/target, mob/living/initiator, silent = FALSE) if(target == initiator || check_friendly_species(initiator)) return ..() - to_chat(initiator, SPAN_WARNING("\The [src] wriggles out of your hands before you can pick it up!")) + if(!silent) + to_chat(initiator, SPAN_WARNING("\The [src] wriggles out of your hands before you can pick it up!")) /mob/living/simple_animal/hostile/slug/proc/attach(var/mob/living/human/H) var/obj/item/clothing/suit/space/S = H.get_covering_equipped_item_by_zone(BP_CHEST) diff --git a/code/modules/mob_holder/holder_mobs.dm b/code/modules/mob_holder/holder_mobs.dm index ec0527a41edf..f2539c7de24e 100644 --- a/code/modules/mob_holder/holder_mobs.dm +++ b/code/modules/mob_holder/holder_mobs.dm @@ -11,7 +11,7 @@ return species.get_holder_color(src) //Mob procs for scooping up -/mob/living/proc/get_scooped(var/mob/living/target, var/mob/living/initiator) +/mob/living/proc/get_scooped(mob/living/target, mob/living/initiator, silent = FALSE) if(!holder_type || buckled || LAZYLEN(pinned)) return FALSE @@ -23,20 +23,24 @@ H.w_class = get_object_size() if(initiator == src) if(!target.equip_to_slot_if_possible(H, slot_back_str, del_on_fail=0, disable_warning=1)) - to_chat(initiator, SPAN_WARNING("You can't climb onto [target]!")) + if(!silent) + to_chat(initiator, SPAN_WARNING("You can't climb onto [target]!")) return FALSE - to_chat(target, SPAN_NOTICE("\The [src] clambers onto you!")) - to_chat(initiator, SPAN_NOTICE("You climb up onto \the [target]!")) + if(!silent) + to_chat(target, SPAN_NOTICE("\The [src] clambers onto you!")) + to_chat(initiator, SPAN_NOTICE("You climb up onto \the [target]!")) else if(!ai?.scooped_by(initiator)) return FALSE // The AI canceled the scooping. if(!target.put_in_hands(H)) - to_chat(initiator, SPAN_WARNING("Your hands are full!")) + if(!silent) + to_chat(initiator, SPAN_WARNING("Your hands are full!")) return FALSE - to_chat(initiator, SPAN_NOTICE("You scoop up \the [src]!")) - to_chat(src, SPAN_NOTICE("\The [initiator] scoops you up!")) + if(!silent) + to_chat(initiator, SPAN_NOTICE("You scoop up \the [src]!")) + to_chat(src, SPAN_NOTICE("\The [initiator] scoops you up!")) forceMove(H) reset_offsets(0) From 69a55232199e59acba34ad5f1484d4620ed0e58e Mon Sep 17 00:00:00 2001 From: mistakenot4892 Date: Tue, 30 Sep 2025 11:48:06 +1000 Subject: [PATCH 23/36] Shifted rabbits down one size category. --- code/modules/mob/living/simple_animal/passive/rabbit.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/passive/rabbit.dm b/code/modules/mob/living/simple_animal/passive/rabbit.dm index 06169581056f..44afe0ed8698 100644 --- a/code/modules/mob/living/simple_animal/passive/rabbit.dm +++ b/code/modules/mob/living/simple_animal/passive/rabbit.dm @@ -5,7 +5,7 @@ max_health = 20 natural_weapon = /obj/item/natural_weapon/bite/weak speak_emote = list("chitters") - mob_size = MOB_SIZE_SMALL + mob_size = MOB_SIZE_TINY butchery_data = /decl/butchery_data/animal/rabbit holder_type = /obj/item/holder ai = /datum/mob_controller/passive/rabbit From 90298d0da033e69139550fd209b1adbbc462d3dc Mon Sep 17 00:00:00 2001 From: mistakenot4892 Date: Wed, 1 Oct 2025 11:57:26 +1000 Subject: [PATCH 24/36] Tweaking hunter AI params. --- code/datums/ai/hunter.dm | 10 +++++----- code/modules/mob/living/simple_animal/friendly/cat.dm | 4 ++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/code/datums/ai/hunter.dm b/code/datums/ai/hunter.dm index 052d012fca3e..ef15d3226515 100644 --- a/code/datums/ai/hunter.dm +++ b/code/datums/ai/hunter.dm @@ -21,6 +21,8 @@ body.ClickOn(prey) /datum/mob_controller/passive/hunter/proc/consume_prey(mob/living/prey) + if(prey.stat != DEAD) + return body.visible_message(SPAN_DANGER("\The [body] consumes the body of \the [prey]!")) var/remains_type = prey.get_remains_type() if(remains_type) @@ -32,6 +34,8 @@ prey.gib() else qdel(prey) + set_target(null) + resume_wandering() /datum/mob_controller/passive/hunter/get_target(atom/new_target) if(isnull(hunt_target)) @@ -78,13 +82,9 @@ set_target(null) resume_wandering() return - if(prey.stat != DEAD) - return // Eat the mob. - set_target(null) - resume_wandering() consume_prey(prey) // Stub for hawks to return to their handler and dock with the mothership. -/datum/mob_controller/passive/hunter/proc/handle_friend_hunting(mob/friend) +/datum/mob_controller/passive/hunter/proc/handle_friend_hunting(mob/user) return FALSE diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index c36ff3e143b3..985e71554779 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -13,7 +13,11 @@ return ..() /datum/mob_controller/passive/hunter/cat/consume_prey(mob/living/prey) + if(prey.stat != DEAD) + return next_hunt = world.time + rand(1 SECONDS, 10 SECONDS) + set_target(null) + resume_wandering() /datum/mob_controller/passive/hunter/cat/can_hunt(mob/living/victim) return istype(victim, /mob/living/simple_animal/passive/mouse) && !victim.stat From b8069b1c50dcf42f922af6c75fabec1136d1e1d5 Mon Sep 17 00:00:00 2001 From: mistakenot4892 Date: Wed, 1 Oct 2025 11:57:55 +1000 Subject: [PATCH 25/36] Adding fadeout effect to go with fadein. --- code/game/objects/items/devices/fadein.dm | 17 +++++++++++++++++ code/game/objects/items/devices/fadeout.dm | 16 ++++++++++++++++ mods/content/fantasy/props/signpost.dm | 16 +--------------- nebula.dme | 2 ++ 4 files changed, 36 insertions(+), 15 deletions(-) create mode 100644 code/game/objects/items/devices/fadein.dm create mode 100644 code/game/objects/items/devices/fadeout.dm diff --git a/code/game/objects/items/devices/fadein.dm b/code/game/objects/items/devices/fadein.dm new file mode 100644 index 000000000000..3055f1bf3259 --- /dev/null +++ b/code/game/objects/items/devices/fadein.dm @@ -0,0 +1,17 @@ +/obj/effect/dummy/fadein/Initialize(mapload, fade_dir = SOUTH, atom/donor) + . = ..() + set_dir(fade_dir) + appearance = donor // grab appearance before ghostizing in case they fall over etc + var/initial_alpha = alpha + alpha = 0 + switch(dir) + if(NORTH) + pixel_z = -32 + if(SOUTH) + pixel_z = 32 + if(EAST) + pixel_w = -32 + if(WEST) + pixel_w = 32 + animate(src, pixel_z = 0, pixel_w = 0, alpha = initial_alpha, time = 1 SECOND) + QDEL_IN(src, 1 SECOND) diff --git a/code/game/objects/items/devices/fadeout.dm b/code/game/objects/items/devices/fadeout.dm new file mode 100644 index 000000000000..36ddf98facfe --- /dev/null +++ b/code/game/objects/items/devices/fadeout.dm @@ -0,0 +1,16 @@ +/obj/effect/dummy/fadeout/Initialize(mapload, fade_dir = SOUTH, atom/donor) + . = ..() + set_dir(fade_dir) + appearance = donor // grab appearance before ghostizing in case they fall over etc + switch(dir) + if(NORTH) + animate(src, pixel_z = 32, alpha = 0, time = 1 SECOND) + if(SOUTH) + animate(src, pixel_z = -32, alpha = 0, time = 1 SECOND) + if(EAST) + animate(src, pixel_w = 32, alpha = 0, time = 1 SECOND) + if(WEST) + animate(src, pixel_w = -32, alpha = 0, time = 1 SECOND) + else + animate(src, alpha = 0, time = 1 SECOND) + QDEL_IN(src, 1 SECOND) diff --git a/mods/content/fantasy/props/signpost.dm b/mods/content/fantasy/props/signpost.dm index 569657c72231..bcfddc878029 100644 --- a/mods/content/fantasy/props/signpost.dm +++ b/mods/content/fantasy/props/signpost.dm @@ -35,21 +35,7 @@ var/choice = alert(user, "Are you sure you wish to depart? This will permanently remove your character from the round.", "Venture Forth?", "No", "Yes") if(choice != "Yes" || QDELETED(user) || user.incapacitated() || QDELETED(src) || !user.Adjacent(src)) return TRUE - var/obj/effect/dummy/fadeout = new(get_turf(user)) - fadeout.set_dir(dir) - fadeout.appearance = user // grab appearance before ghostizing in case they fall over etc - switch(dir) - if(NORTH) - animate(fadeout, pixel_z = 32, alpha = 0, time = 1 SECOND) - if(SOUTH) - animate(fadeout, pixel_z = -32, alpha = 0, time = 1 SECOND) - if(EAST) - animate(fadeout, pixel_w = 32, alpha = 0, time = 1 SECOND) - if(WEST) - animate(fadeout, pixel_w = -32, alpha = 0, time = 1 SECOND) - else - animate(fadeout, alpha = 0, time = 1 SECOND) - QDEL_IN(fadeout, 1 SECOND) + new /obj/effect/dummy/fadeout(get_turf(user), dir, user) despawn_character(user) return TRUE diff --git a/nebula.dme b/nebula.dme index 3a87fe3149e2..56b6858163c7 100644 --- a/nebula.dme +++ b/nebula.dme @@ -1177,6 +1177,8 @@ #include "code\game\objects\items\devices\cable_painter.dm" #include "code\game\objects\items\devices\chameleonproj.dm" #include "code\game\objects\items\devices\dociler.dm" +#include "code\game\objects\items\devices\fadein.dm" +#include "code\game\objects\items\devices\fadeout.dm" #include "code\game\objects\items\devices\flash.dm" #include "code\game\objects\items\devices\geiger.dm" #include "code\game\objects\items\devices\gps.dm" From a584f6c756de158d7c6262a4c94b6ed6e9e2637d Mon Sep 17 00:00:00 2001 From: mistakenot4892 Date: Wed, 1 Oct 2025 11:58:09 +1000 Subject: [PATCH 26/36] Holder examine will now examine contents. --- code/modules/mob_holder/_holder.dm | 5 +++++ code/modules/mob_holder/holder_mobs.dm | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/code/modules/mob_holder/_holder.dm b/code/modules/mob_holder/_holder.dm index 150f526f489b..3cc51f873e18 100644 --- a/code/modules/mob_holder/_holder.dm +++ b/code/modules/mob_holder/_holder.dm @@ -24,6 +24,11 @@ AM.vis_flags |= (VIS_INHERIT_ID|VIS_INHERIT_LAYER|VIS_INHERIT_PLANE) add_vis_contents(AM) +/obj/item/holder/examined_by(mob/user, distance, infix, suffix) + for(var/atom/thing in get_contained_external_atoms()) + thing.examined_by(user, distance, infix, suffix) + return TRUE + // No scooping mobs and handing them to people who can't scoop them. /obj/item/holder/equipped(mob/user, slot) . = ..() diff --git a/code/modules/mob_holder/holder_mobs.dm b/code/modules/mob_holder/holder_mobs.dm index f2539c7de24e..16ebd454351e 100644 --- a/code/modules/mob_holder/holder_mobs.dm +++ b/code/modules/mob_holder/holder_mobs.dm @@ -22,7 +22,7 @@ var/obj/item/holder/H = new holder_type(get_turf(src)) H.w_class = get_object_size() if(initiator == src) - if(!target.equip_to_slot_if_possible(H, slot_back_str, del_on_fail=0, disable_warning=1)) + if(!target.equip_to_slot_if_possible(H, slot_back_str, del_on_fail=0, disable_warning=1) && !target.put_in_hands(H)) if(!silent) to_chat(initiator, SPAN_WARNING("You can't climb onto [target]!")) return FALSE From fa51aec2f02e12a7f75931fc7703ca1c7f8e4b64 Mon Sep 17 00:00:00 2001 From: mistakenot4892 Date: Thu, 9 Oct 2025 12:13:24 +1100 Subject: [PATCH 27/36] Shirts are now named 'shirt'. --- code/modules/clothing/shirts/_shirts.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/clothing/shirts/_shirts.dm b/code/modules/clothing/shirts/_shirts.dm index 7b841100fd48..a98caa44df7a 100644 --- a/code/modules/clothing/shirts/_shirts.dm +++ b/code/modules/clothing/shirts/_shirts.dm @@ -1,4 +1,5 @@ /obj/item/clothing/shirt + name = "shirt" abstract_type = /obj/item/clothing/shirt body_parts_covered = SLOT_UPPER_BODY|SLOT_ARMS permeability_coefficient = 0.90 From 5dca5507118418f453cbc3947a0099ae8030bbf5 Mon Sep 17 00:00:00 2001 From: mistakenot4892 Date: Thu, 9 Oct 2025 12:13:32 +1100 Subject: [PATCH 28/36] Moved fade effects into effects folder. --- code/game/objects/{items/devices => effects}/fadein.dm | 0 code/game/objects/{items/devices => effects}/fadeout.dm | 0 nebula.dme | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) rename code/game/objects/{items/devices => effects}/fadein.dm (100%) rename code/game/objects/{items/devices => effects}/fadeout.dm (100%) diff --git a/code/game/objects/items/devices/fadein.dm b/code/game/objects/effects/fadein.dm similarity index 100% rename from code/game/objects/items/devices/fadein.dm rename to code/game/objects/effects/fadein.dm diff --git a/code/game/objects/items/devices/fadeout.dm b/code/game/objects/effects/fadeout.dm similarity index 100% rename from code/game/objects/items/devices/fadeout.dm rename to code/game/objects/effects/fadeout.dm diff --git a/nebula.dme b/nebula.dme index 56b6858163c7..cfc424bd5655 100644 --- a/nebula.dme +++ b/nebula.dme @@ -1025,6 +1025,8 @@ #include "code\game\objects\effects\dirty_floor.dm" #include "code\game\objects\effects\effect_system.dm" #include "code\game\objects\effects\explosion_particles.dm" +#include "code\game\objects\effects\fadein.dm" +#include "code\game\objects\effects\fadeout.dm" #include "code\game\objects\effects\fake_fire.dm" #include "code\game\objects\effects\footprints.dm" #include "code\game\objects\effects\force_portal.dm" @@ -1177,8 +1179,6 @@ #include "code\game\objects\items\devices\cable_painter.dm" #include "code\game\objects\items\devices\chameleonproj.dm" #include "code\game\objects\items\devices\dociler.dm" -#include "code\game\objects\items\devices\fadein.dm" -#include "code\game\objects\items\devices\fadeout.dm" #include "code\game\objects\items\devices\flash.dm" #include "code\game\objects\items\devices\geiger.dm" #include "code\game\objects\items\devices\gps.dm" From 9211c8ee79dddae294b6b8f6d5efef6de317d4ba Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 8 Oct 2025 21:33:28 -0400 Subject: [PATCH 29/36] Move mil_branches onto /datum/map --- code/controllers/subsystems/jobs.dm | 6 +-- code/datums/mil_ranks.dm | 4 +- code/game/jobs/job/_job.dm | 14 ++++--- code/game/movietitles.dm | 2 +- code/game/objects/items/weapons/cards_ids.dm | 4 +- .../items/weapons/cards_ids_syndicate.dm | 8 ++-- .../preference_setup/loadout/loadout.dm | 2 +- .../preference_setup/occupation/occupation.dm | 39 +++++++++++-------- .../occupation/skill_selection.dm | 2 +- .../mob/new_player/preferences_setup.dm | 4 +- .../modular_computers/file_system/manifest.dm | 4 +- .../file_system/reports/crew_record.dm | 6 +-- .../file_system/reports/people.dm | 2 +- code/modules/submaps/submap_join.dm | 7 ++-- maps/~mapsystem/map_ranks.dm | 1 + 15 files changed, 56 insertions(+), 49 deletions(-) diff --git a/code/controllers/subsystems/jobs.dm b/code/controllers/subsystems/jobs.dm index 722dd50bee4c..88e40e689d9b 100644 --- a/code/controllers/subsystems/jobs.dm +++ b/code/controllers/subsystems/jobs.dm @@ -387,7 +387,7 @@ SUBSYSTEM_DEF(jobs) if(player.client.prefs.alternate_option == BE_ASSISTANT) var/datum/job/ass = global.using_map.default_job_type if((global.using_map.flags & MAP_HAS_BRANCH) && player.client.prefs.branches[initial(ass.title)]) - var/datum/mil_branch/branch = mil_branches.get_branch(player.client.prefs.branches[initial(ass.title)]) + var/datum/mil_branch/branch = global.using_map.mil_branches.get_branch(player.client.prefs.branches[initial(ass.title)]) ass = branch.assistant_job assign_role(player, initial(ass.title), mode = mode) //For ones returning to lobby @@ -475,9 +475,9 @@ SUBSYSTEM_DEF(jobs) if(job) if(H.client) if(global.using_map.flags & MAP_HAS_BRANCH) - H.char_branch = mil_branches.get_branch(H.client.prefs.branches[job_title]) + H.char_branch = global.using_map.mil_branches.get_branch(H.client.prefs.branches[job_title]) if(global.using_map.flags & MAP_HAS_RANK) - H.char_rank = mil_branches.get_rank(H.client.prefs.branches[job_title], H.client.prefs.ranks[job_title]) + H.char_rank = global.using_map.mil_branches.get_rank(H.client.prefs.branches[job_title], H.client.prefs.ranks[job_title]) // Transfers the skill settings for the job to the mob H.skillset.obtain_from_client(job, H.client) diff --git a/code/datums/mil_ranks.dm b/code/datums/mil_ranks.dm index 136559c4aa7c..e0aa19bc4811 100644 --- a/code/datums/mil_ranks.dm +++ b/code/datums/mil_ranks.dm @@ -10,8 +10,6 @@ * and each branch datum definition, respectively. */ -var/global/datum/mil_branches/mil_branches = new() - /** * Global object for handling branches */ @@ -147,7 +145,7 @@ var/global/datum/mil_branches/mil_branches = new() /** * Populate the global branches list from global.using_map */ -/proc/populate_branches() +/datum/map/proc/populate_branches() if(!(global.using_map.flags & MAP_HAS_BRANCH) && !(global.using_map.flags & MAP_HAS_RANK)) mil_branches.branches = null mil_branches.spawn_branches_ = null diff --git a/code/game/jobs/job/_job.dm b/code/game/jobs/job/_job.dm index eb27bd7793e3..40e6b29f42b3 100644 --- a/code/game/jobs/job/_job.dm +++ b/code/game/jobs/job/_job.dm @@ -292,9 +292,11 @@ species_branch_rank_cache_[S] = list() . = species_branch_rank_cache_[S] - var/spawn_branches = mil_branches.spawn_branches(S) + var/datum/mil_branches/branches = global.using_map.mil_branches + + var/spawn_branches = branches.spawn_branches(S) for(var/branch_type in allowed_branches) - var/datum/mil_branch/branch = mil_branches.get_branch_by_type(branch_type) + var/datum/mil_branch/branch = branches.get_branch_by_type(branch_type) if(branch.name in spawn_branches) if(!allowed_ranks || !(global.using_map.flags & MAP_HAS_RANK)) LAZYADD(., branch.name) @@ -318,7 +320,7 @@ if(branch_name == "None") return 0 - var/datum/mil_branch/branch = mil_branches.get_branch(branch_name) + var/datum/mil_branch/branch = global.using_map.mil_branches.get_branch(branch_name) if(!branch) PRINT_STACK_TRACE("unknown branch \"[branch_name]\" passed to is_branch_allowed()") @@ -343,7 +345,7 @@ if(branch_name == "None" || rank_name == "None") return 0 - var/datum/mil_rank/rank = mil_branches.get_rank(branch_name, rank_name) + var/datum/mil_rank/rank = global.using_map.mil_branches.get_rank(branch_name, rank_name) if(!rank) PRINT_STACK_TRACE("unknown rank \"[rank_name]\" in branch \"[branch_name]\" passed to is_rank_allowed()") @@ -358,14 +360,14 @@ /datum/job/proc/get_branches() . = list() for(var/branch in allowed_branches) - var/datum/mil_branch/branch_datum = mil_branches.get_branch_by_type(branch) + var/datum/mil_branch/branch_datum = global.using_map.mil_branches.get_branch_by_type(branch) . += branch_datum.name return english_list(.) //Same as above but ranks /datum/job/proc/get_ranks(branch) . = list() - var/datum/mil_branch/branch_datum = mil_branches.get_branch(branch) + var/datum/mil_branch/branch_datum = global.using_map.mil_branches.get_branch(branch) for(var/datum/mil_rank/rank as anything in allowed_ranks) if(branch_datum && !(initial(rank.name) in branch_datum.ranks)) continue diff --git a/code/game/movietitles.dm b/code/game/movietitles.dm index e193fae03d2a..1fc735fc1306 100644 --- a/code/game/movietitles.dm +++ b/code/game/movietitles.dm @@ -68,7 +68,7 @@ var/global/list/end_titles var/used_name = H.real_name var/datum/computer_file/report/crew_record/record = get_crewmember_record(H.real_name) if(record && record.get_rank()) - var/datum/mil_rank/rank = mil_branches.get_rank(record.get_branch(), record.get_rank()) + var/datum/mil_rank/rank = global.using_map.mil_branches.get_rank(record.get_branch(), record.get_rank()) if(rank.name_short) used_name = "[rank.name_short] [used_name]" var/showckey = 0 diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 2dadd2bbf4d5..0fc57c0989d2 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -338,7 +338,7 @@ var/global/const/NO_EMAG_ACT = -50 return if(ispath(var_value, /datum/mil_branch) || istext(var_value)) - var/datum/mil_branch/new_branch = mil_branches.get_branch(var_value) + var/datum/mil_branch/new_branch = global.using_map.mil_branches.get_branch(var_value) if(new_branch) if(new_branch != id.military_branch) id.military_branch = new_branch @@ -369,7 +369,7 @@ var/global/const/NO_EMAG_ACT = -50 var_value = rank.name if(istext(var_value)) - var/new_rank = mil_branches.get_rank(id.military_branch.name, var_value) + var/new_rank = global.using_map.mil_branches.get_rank(id.military_branch.name, var_value) if(new_rank) id.military_rank = new_rank return diff --git a/code/game/objects/items/weapons/cards_ids_syndicate.dm b/code/game/objects/items/weapons/cards_ids_syndicate.dm index 37020adb925d..62fd8c26363b 100644 --- a/code/game/objects/items/weapons/cards_ids_syndicate.dm +++ b/code/game/objects/items/weapons/cards_ids_syndicate.dm @@ -214,15 +214,15 @@ to_chat(user, "All information has been deleted from \the [src].") . = 1 if("Branch") - var/new_branch = sanitize(input(user,"What branch of service would you like to put on this card?","Agent Card Branch") as null|anything in mil_branches.spawn_branches()) + var/new_branch = sanitize(input(user,"What branch of service would you like to put on this card?","Agent Card Branch") as null|anything in global.using_map.mil_branches.spawn_branches()) if(!isnull(new_branch) && CanUseTopic(user, state)) - src.military_branch = mil_branches.spawn_branches()[new_branch] + src.military_branch = global.using_map.mil_branches.spawn_branches()[new_branch] to_chat(user, "Branch changed to '[military_branch.name]'.") . = 1 if("Rank") - var/new_rank = sanitize(input(user,"What rank would you like to put on this card?","Agent Card Rank") as null|anything in mil_branches.spawn_ranks(military_branch.name)) + var/new_rank = sanitize(input(user,"What rank would you like to put on this card?","Agent Card Rank") as null|anything in global.using_map.mil_branches.spawn_ranks(military_branch.name)) if(!isnull(new_rank) && CanUseTopic(user, state)) - src.military_rank = mil_branches.spawn_ranks(military_branch.name)[new_rank] + src.military_rank = global.using_map.mil_branches.spawn_ranks(military_branch.name)[new_rank] to_chat(user, "Rank changed to '[military_rank.name]'.") . = 1 diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm index 17f52a97ce8a..4aab1de30764 100644 --- a/code/modules/client/preference_setup/loadout/loadout.dm +++ b/code/modules/client/preference_setup/loadout/loadout.dm @@ -243,7 +243,7 @@ var/good_branch = 0 entry += "
" for(var/branch in branches) - var/datum/mil_branch/player_branch = mil_branches.get_branch(branch) + var/datum/mil_branch/player_branch = global.using_map.mil_branches.get_branch(branch) if(player_branch.type in gear.allowed_branches) branch_checks += "[player_branch.name]" good_branch = 1 diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm index 3d1b29c1a54f..944bc128c249 100644 --- a/code/modules/client/preference_setup/occupation/occupation.dm +++ b/code/modules/client/preference_setup/occupation/occupation.dm @@ -81,6 +81,8 @@ if(!SSmapping || !SSjobs.job_lists_by_map_name) return + var/datum/mil_branches/using_branches = global.using_map.mil_branches + var/decl/species/S = pref.get_species_decl() . = list() . += "" @@ -119,9 +121,9 @@ var/datum/mil_branch/player_branch var/branch_string = "" var/rank_branch_string = "" - var/branch_rank = job.allowed_branches ? job.get_branch_rank(S) : mil_branches.spawn_branches(S) + var/branch_rank = job.allowed_branches ? job.get_branch_rank(S) : using_branches.spawn_branches(S) if(global.using_map && (global.using_map.flags & MAP_HAS_BRANCH) && LAZYLEN(branch_rank)) - player_branch = mil_branches.get_branch(pref.branches[job.title]) + player_branch = using_branches.get_branch(pref.branches[job.title]) if(player_branch) if(LAZYLEN(branch_rank) > 1) branch_string += "[player_branch.name_short || player_branch.name]" @@ -130,9 +132,9 @@ if(!branch_string) branch_string = "-" if(player_branch) - var/ranks = branch_rank[player_branch.name] || mil_branches.spawn_ranks(player_branch.name, S) + var/ranks = branch_rank[player_branch.name] || using_branches.spawn_ranks(player_branch.name, S) if(LAZYLEN(ranks)) - player_rank = mil_branches.get_rank(player_branch.name, pref.ranks[job.title]) + player_rank = using_branches.get_rank(player_branch.name, pref.ranks[job.title]) if(player_rank) if(LAZYLEN(ranks) > 1) rank_branch_string += "[player_rank.name_short || player_rank.name]" @@ -257,6 +259,8 @@ /datum/category_item/player_setup_item/proc/validate_branch_and_rank() + var/datum/mil_branches/using_branches = global.using_map.mil_branches + if(LAZYLEN(pref.branches)) for(var/job_name in pref.branches) if(!(job_name in SSjobs.titles_to_datums)) @@ -275,16 +279,16 @@ var/datum/job/job = SSjobs.get_by_title(job_name) - var/datum/mil_branch/player_branch = pref.branches[job.title] ? mil_branches.get_branch(pref.branches[job.title]) : null - var/branch_rank = job.allowed_branches ? job.get_branch_rank(S) : mil_branches.spawn_branches(S) + var/datum/mil_branch/player_branch = pref.branches[job.title] ? using_branches.get_branch(pref.branches[job.title]) : null + var/branch_rank = job.allowed_branches ? job.get_branch_rank(S) : using_branches.spawn_branches(S) if(!player_branch || !(player_branch.name in branch_rank)) - player_branch = LAZYLEN(branch_rank) ? mil_branches.get_branch(branch_rank[1]) : null + player_branch = LAZYLEN(branch_rank) ? using_branches.get_branch(branch_rank[1]) : null if(player_branch) - var/datum/mil_rank/player_rank = pref.ranks[job.title] ? mil_branches.get_rank(player_branch.name, pref.ranks[job.title]) : null - var/ranks = branch_rank[player_branch.name] || mil_branches.spawn_ranks(player_branch.name, S) + var/datum/mil_rank/player_rank = pref.ranks[job.title] ? using_branches.get_rank(player_branch.name, pref.ranks[job.title]) : null + var/ranks = branch_rank[player_branch.name] || using_branches.spawn_ranks(player_branch.name, S) if(!player_rank || !(player_rank.name in ranks)) - player_rank = LAZYLEN(ranks) ? mil_branches.get_rank(player_branch.name, ranks[1]) : null + player_rank = LAZYLEN(ranks) ? using_branches.get_rank(player_branch.name, ranks[1]) : null // Now make the assignments pref.branches[job.title] = player_branch.name @@ -297,6 +301,7 @@ pref.ranks -= job.title /datum/category_item/player_setup_item/occupation/OnTopic(href, href_list, user) + var/datum/mil_branches/using_branches = global.using_map.mil_branches if(href_list["reset_jobs"]) ResetJobs() return TOPIC_REFRESH @@ -340,9 +345,9 @@ var/datum/job/job = locate(href_list["checking_job"]) if(istype(job)) var/decl/species/S = pref.get_species_decl() - var/list/options = job.allowed_branches ? job.get_branch_rank(S) : mil_branches.spawn_branches(S) + var/list/options = job.allowed_branches ? job.get_branch_rank(S) : using_branches.spawn_branches(S) var/choice = input(user, "Choose your branch of service.", CHARACTER_PREFERENCE_INPUT_TITLE) as null|anything in options - if(choice && CanUseTopic(user) && mil_branches.is_spawn_branch(choice, S)) + if(choice && CanUseTopic(user) && using_branches.is_spawn_branch(choice, S)) pref.branches[job.title] = choice pref.ranks -= job.title pref.skills_allocated = pref.sanitize_skills(pref.skills_allocated) // Check our skillset is still valid @@ -353,12 +358,12 @@ else if(href_list["char_rank"]) var/datum/job/job = locate(href_list["checking_job"]) if(istype(job)) - var/datum/mil_branch/branch = mil_branches.get_branch(pref.branches[job.title]) + var/datum/mil_branch/branch = using_branches.get_branch(pref.branches[job.title]) var/decl/species/S = pref.get_species_decl() - var/list/branch_rank = job.allowed_branches ? job.get_branch_rank(S) : mil_branches.spawn_branches(S) - var/list/options = branch_rank[branch.name] || mil_branches.spawn_ranks(branch.name, S) + var/list/branch_rank = job.allowed_branches ? job.get_branch_rank(S) : using_branches.spawn_branches(S) + var/list/options = branch_rank[branch.name] || using_branches.spawn_ranks(branch.name, S) var/choice = input(user, "Choose your rank.", CHARACTER_PREFERENCE_INPUT_TITLE) as null|anything in options - if(choice && CanUseTopic(user) && mil_branches.is_spawn_rank(branch.name, choice, pref.get_species_decl())) + if(choice && CanUseTopic(user) && using_branches.is_spawn_rank(branch.name, choice, pref.get_species_decl())) pref.ranks[job.title] = choice pref.skills_allocated = pref.sanitize_skills(pref.skills_allocated) // Check our skillset is still valid validate_branch_and_rank() @@ -425,7 +430,7 @@ if(job.allowed_branches) dat += "You can be of following ranks:" for(var/T in job.allowed_branches) - var/datum/mil_branch/B = mil_branches.get_branch_by_type(T) + var/datum/mil_branch/B = using_branches.get_branch_by_type(T) dat += "
  • [B.name]: [job.get_ranks(B.name)]" dat += "
    " if(get_config_value(/decl/config/text/wikiurl)) diff --git a/code/modules/client/preference_setup/occupation/skill_selection.dm b/code/modules/client/preference_setup/occupation/skill_selection.dm index ec4b0ba348db..acb013ddc275 100644 --- a/code/modules/client/preference_setup/occupation/skill_selection.dm +++ b/code/modules/client/preference_setup/occupation/skill_selection.dm @@ -24,7 +24,7 @@ if(job && job.min_skill) . = job.min_skill[S.type] if(!.) - var/datum/mil_branch/branch = mil_branches.get_branch(branches[job.title]) + var/datum/mil_branch/branch = global.using_map.mil_branches.get_branch(branches[job.title]) if(branch && branch.min_skill) . = branch.min_skill[S.type] if(!.) diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index 02545d440181..7bc040ee5570 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -74,8 +74,8 @@ if((equip_preview_mob & EQUIP_PREVIEW_JOB) && previewJob) mannequin.job = previewJob.title - var/datum/mil_branch/branch = mil_branches.get_branch(branches[previewJob.title]) - var/datum/mil_rank/rank = mil_branches.get_rank(branches[previewJob.title], ranks[previewJob.title]) + var/datum/mil_branch/branch = global.using_map.mil_branches.get_branch(branches[previewJob.title]) + var/datum/mil_rank/rank = global.using_map.mil_branches.get_rank(branches[previewJob.title], ranks[previewJob.title]) previewJob.equip_preview(mannequin, player_alt_titles[previewJob.title], branch, rank) update_icon = TRUE diff --git a/code/modules/modular_computers/file_system/manifest.dm b/code/modules/modular_computers/file_system/manifest.dm index f6ec5a53e26b..9b07a16a2e1d 100644 --- a/code/modules/modular_computers/file_system/manifest.dm +++ b/code/modules/modular_computers/file_system/manifest.dm @@ -26,8 +26,8 @@ mil_ranks[name] = "" if(global.using_map.flags & MAP_HAS_RANK) - var/datum/mil_branch/branch_obj = mil_branches.get_branch(CR.get_branch()) - var/datum/mil_rank/rank_obj = mil_branches.get_rank(CR.get_branch(), CR.get_rank()) + var/datum/mil_branch/branch_obj = global.using_map.mil_branches.get_branch(CR.get_branch()) + var/datum/mil_rank/rank_obj = global.using_map.mil_branches.get_rank(CR.get_branch(), CR.get_rank()) if(branch_obj && rank_obj) mil_ranks[name] = "[rank_obj.name_short] " diff --git a/code/modules/modular_computers/file_system/reports/crew_record.dm b/code/modules/modular_computers/file_system/reports/crew_record.dm index fb6a7c6a233a..1570b210e6bb 100644 --- a/code/modules/modular_computers/file_system/reports/crew_record.dm +++ b/code/modules/modular_computers/file_system/reports/crew_record.dm @@ -266,7 +266,7 @@ FIELD_LONG("Exploitable Information", antag_record, access_hacked, access_hacked //Options builderes /datum/report_field/options/crew_record/rank/proc/record_ranks() var/datum/computer_file/report/crew_record/record = owner - var/datum/mil_branch/branch = mil_branches.get_branch(record.get_branch()) + var/datum/mil_branch/branch = global.using_map.mil_branches.get_branch(record.get_branch()) if(!branch) return . = list() @@ -287,8 +287,8 @@ FIELD_LONG("Exploitable Information", antag_record, access_hacked, access_hacked /datum/report_field/options/crew_record/branch/proc/record_branches() . = list() . |= "Unset" - for(var/branch in mil_branches.branches) - var/datum/mil_branch/branch_datum = mil_branches.branches[branch] + for(var/branch in global.using_map.mil_branches.branches) + var/datum/mil_branch/branch_datum = global.using_map.mil_branches.branches[branch] . |= branch_datum.name #undef GETTER_SETTER diff --git a/code/modules/modular_computers/file_system/reports/people.dm b/code/modules/modular_computers/file_system/reports/people.dm index 20b1597b1ff8..522c3e80c547 100644 --- a/code/modules/modular_computers/file_system/reports/people.dm +++ b/code/modules/modular_computers/file_system/reports/people.dm @@ -95,7 +95,7 @@ if(in_line && (global.using_map.flags & MAP_HAS_RANK)) var/datum/computer_file/report/crew_record/CR = get_crewmember_record(entry["name"]) if(CR) - var/datum/mil_rank/rank_obj = mil_branches.get_rank(CR.get_branch(), CR.get_rank()) + var/datum/mil_rank/rank_obj = global.using_map.mil_branches.get_rank(CR.get_branch(), CR.get_rank()) milrank = (rank_obj ? rank_obj.name_short : "") dat += format_output(entry["name"], in_line ? null : entry["rank"], milrank) return jointext(dat, in_line ? ", " : "
    ") diff --git a/code/modules/submaps/submap_join.dm b/code/modules/submaps/submap_join.dm index e4af7814f2fb..615f96a05d22 100644 --- a/code/modules/submaps/submap_join.dm +++ b/code/modules/submaps/submap_join.dm @@ -68,9 +68,10 @@ var/mob/living/human/user_human if(ishuman(character)) user_human = character - if(job.branch && mil_branches) - user_human.char_branch = mil_branches.get_branch(job.branch) - user_human.char_rank = mil_branches.get_rank(job.branch, job.rank) + var/datum/mil_branches/using_branches = global.using_map.mil_branches + if(job.branch && global.using_map & MAP_HAS_BRANCH && using_branches) + user_human.char_branch = using_branches.get_branch(job.branch) + user_human.char_rank = using_branches.get_rank(job.branch, job.rank) // We need to make sure to use the abstract instance here; it's not the same as the one we were passed. character.skillset.obtain_from_client(SSjobs.get_by_path(job.type), character.client) diff --git a/maps/~mapsystem/map_ranks.dm b/maps/~mapsystem/map_ranks.dm index 9f100dc66660..5ced51e5f70b 100644 --- a/maps/~mapsystem/map_ranks.dm +++ b/maps/~mapsystem/map_ranks.dm @@ -1,4 +1,5 @@ /datum/map + var/datum/mil_branches/mil_branches = new() var/list/branch_types // list of branch datum paths for military branches available on this map var/list/spawn_branch_types // subset of above for branches a player can spawn in with From adf5021c26b541c363f3f88e36c9e70981aab903 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 25 Sep 2025 21:08:29 -0400 Subject: [PATCH 30/36] Generalize stat organ code from drakes --- code/modules/mob/living/human/human_organs.dm | 8 ++++++++ code/modules/organs/organ.dm | 6 +++--- mods/species/drakes/drake_organs.dm | 8 +------- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/code/modules/mob/living/human/human_organs.dm b/code/modules/mob/living/human/human_organs.dm index a9dd1c86d45f..1b4884758d9c 100644 --- a/code/modules/mob/living/human/human_organs.dm +++ b/code/modules/mob/living/human/human_organs.dm @@ -74,6 +74,10 @@ LAZYINITLIST(organs_by_category) LAZYDISTINCTADD(organs_by_category[O.organ_category], O) + // Update stat organs as well + if(O.has_stat_info) + LAZYDISTINCTADD(stat_organs, O) + . = ..() if(!.) return @@ -113,6 +117,10 @@ if(LAZYLEN(organs_by_category[O.organ_category]) <= 0) LAZYREMOVE(organs_by_category, O.organ_category) + // Update stat organs as well + if(O.has_stat_info && stat_organs) + LAZYREMOVE(stat_organs, O) + if(!O.is_internal()) refresh_modular_limb_verbs() LAZYREMOVE(bad_external_organs, O) diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 135a242c58ff..6f483c9e85ec 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -55,8 +55,8 @@ /// Whether or not we should scale the damage values of this organ to the owner species. var/scale_max_damage_to_species_health - /// Set to true if this organ should return info to Stat(). See get_stat_info(). - var/has_stat_info + /// Set to TRUE if this organ should return info to Stat(). See get_stat_info(). + var/has_stat_info = FALSE /obj/item/organ/proc/reset_matter() matter = null @@ -687,7 +687,7 @@ var/global/list/ailment_reference_cache = list() place_butcher_product(GET_DECL(species.butchery_data)) return ..() -/// Returns a list with two entries, first being the stat panel title, the second being the value. See has_stat_value bool above. +/// Returns a list with two entries, first being the stat panel title, the second being the value. See has_stat_info bool above. /obj/item/organ/proc/get_stat_info() return null diff --git a/mods/species/drakes/drake_organs.dm b/mods/species/drakes/drake_organs.dm index a42a3578cb45..988fb597c48e 100644 --- a/mods/species/drakes/drake_organs.dm +++ b/mods/species/drakes/drake_organs.dm @@ -11,6 +11,7 @@ relative_size = 60 min_regeneration_cutoff_threshold = 2 max_regeneration_cutoff_threshold = 5 + has_stat_info = TRUE var/datum/reagents/sap_crop /obj/item/organ/internal/drake_gizzard/Initialize() @@ -22,14 +23,7 @@ if(owner && owner.stat != DEAD && !is_broken() && sap_crop && sap_crop.total_volume < 10) sap_crop.add_reagent(/decl/material/liquid/sifsap, 0.5) -/obj/item/organ/internal/drake_gizzard/do_install(var/mob/living/human/target, var/obj/item/organ/external/affected, var/in_place = FALSE, var/update_icon = TRUE, var/detached = FALSE) - . = ..() - if(owner) - LAZYDISTINCTADD(owner.stat_organs, src) - /obj/item/organ/internal/drake_gizzard/do_uninstall(in_place, detach, ignore_children, update_icon) - if(owner) - LAZYREMOVE(owner.stat_organs, src) . = ..() if(sap_crop?.total_volume) if(reagents) From 4183c05677b7000eb5d8aa853275cff8fe150693 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 26 Sep 2025 02:26:03 -0400 Subject: [PATCH 31/36] Reimplement codex implant and add config option for it --- .../config/config_types/config_game_world.dm | 9 +++++++-- .../loadout/lists/augmentations.dm | 14 ++++++++++++++ code/modules/codex/codex_implant.dm | 1 + code/modules/codex/codex_mob.dm | 6 +++++- 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/code/datums/config/config_types/config_game_world.dm b/code/datums/config/config_types/config_game_world.dm index 66b154dd6dc6..c3328c8c2b30 100644 --- a/code/datums/config/config_types/config_game_world.dm +++ b/code/datums/config/config_types/config_game_world.dm @@ -23,7 +23,8 @@ /decl/config/toggle/roundstart_level_generation, /decl/config/toggle/lights_start_on, /decl/config/toggle/on/cisnormativity, - /decl/config/enum/colored_coating_names + /decl/config/enum/colored_coating_names, + /decl/config/toggle/codex_requires_implant ) /decl/config/num/exterior_ambient_light @@ -145,4 +146,8 @@ "none" = CONFIG_COATING_COLOR_NONE, "mixture" = CONFIG_COATING_COLOR_MIXTURE, "components" = CONFIG_COATING_COLOR_COMPONENTS - ) \ No newline at end of file + ) + +/decl/config/toggle/codex_requires_implant + uid = "codex_requires_implant" + desc = "If true, humans require a codex implant to access the codex." \ No newline at end of file diff --git a/code/modules/client/preference_setup/loadout/lists/augmentations.dm b/code/modules/client/preference_setup/loadout/lists/augmentations.dm index 1fa6febaf4fa..e2f387cd6ec2 100644 --- a/code/modules/client/preference_setup/loadout/lists/augmentations.dm +++ b/code/modules/client/preference_setup/loadout/lists/augmentations.dm @@ -33,3 +33,17 @@ user.add_organ(src, organ_to_implant_into) to_chat(user, SPAN_NOTICE("Your [organ_to_implant_into.name] has been replaced with \the [src].")) + +// Codex implant, only available if the codex is set to require it in config +/decl/loadout_option/augmentation/codex_implant + name = "Codex Implant" + uid = "gear_augmentation_codex" + description = "A neural implant that provides access to the codex." + path = /obj/item/implant/codex + custom_setup_proc_arguments = list(BP_HEAD) + cost = 0 + +/decl/loadout_option/augmentation/codex_implant/can_be_taken_by(mob/living/user) + if(!get_config_value(/decl/config/toggle/codex_requires_implant)) + return FALSE + return ..() \ No newline at end of file diff --git a/code/modules/codex/codex_implant.dm b/code/modules/codex/codex_implant.dm index 48d57b472edc..9e965a27e34a 100644 --- a/code/modules/codex/codex_implant.dm +++ b/code/modules/codex/codex_implant.dm @@ -5,6 +5,7 @@ /obj/item/implant/codex name = "codex implant" desc = "It has 'DON'T PANIC' embossed on the casing in friendly letters." + known = TRUE /obj/item/implant/codex/implanted(var/mob/source) . = ..(source) diff --git a/code/modules/codex/codex_mob.dm b/code/modules/codex/codex_mob.dm index 81abaeb25726..697c67aa64ca 100644 --- a/code/modules/codex/codex_mob.dm +++ b/code/modules/codex/codex_mob.dm @@ -11,7 +11,11 @@ return TRUE /mob/living/human/can_use_codex() - return TRUE //has_implant(/obj/item/implant/codex, functioning = TRUE) + if(get_config_value(/decl/config/toggle/codex_requires_implant)) + for(var/obj/item/implant/codex/codex_implant in contents) + if(codex_implant.implanted && !codex_implant.malfunction) + return TRUE + return TRUE /mob/living/human/get_codex_value() return "[lowertext(species.name)] (species)" \ No newline at end of file From ddb6c00e25a6ff8563d4e9e38ed4890c7ed59bf8 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 8 Oct 2025 22:03:31 -0400 Subject: [PATCH 32/36] Renormalize all line endings --- .gitignore | 124 +- README.md | 162 +-- config/example/admin_ranks.txt | 90 +- config/example/admins.txt | 16 +- config/example/dbconfig.txt | 40 +- config/example/dbconfig_docker.txt | 42 +- config/example/jobs.txt | 72 +- config/example/motd.txt | 10 +- config/example/rules.html | 20 +- config/names/adjectives.txt | 792 +++++------ config/names/ai.txt | 108 +- config/names/ninjaname.txt | 88 +- config/names/ninjatitle.txt | 90 +- config/names/verbs.txt | 1264 ++++++++--------- config/names/wizardfirst.txt | 70 +- config/names/wizardsecond.txt | 76 +- html/changelog.css | 158 +-- html/changelogs/__CHANGELOG_README.txt | 38 +- html/changelogs/example.yml | 76 +- html/create_object.html | 250 ++-- html/panels.css | 20 +- html/search.js | 64 +- html/templates/footer.html | 8 +- html/templates/header.html | 106 +- interface/skin.dmf | 870 ++++++------ mods/gamemodes/cult/_cult.dme | 18 +- nano/templates/agent_id_card.tmpl | 42 +- nano/templates/air_alarm.tmpl | 436 +++--- nano/templates/alarm_monitor.tmpl | 74 +- nano/templates/appearance_changer.tmpl | 178 +-- nano/templates/atmos_alert.tmpl | 36 +- nano/templates/atmos_control.tmpl | 50 +- nano/templates/door_control.tmpl | 130 +- nano/templates/law_manager.tmpl | 504 +++---- nano/templates/nuclear_bomb.tmpl | 144 +- nano/templates/omni_filter.tmpl | 204 +-- nano/templates/omni_mixer.tmpl | 202 +-- nano/templates/portpump.tmpl | 200 +-- nano/templates/portscrubber.tmpl | 182 +-- .../shuttle_control_console_antag.tmpl | 186 +-- .../shuttle_control_console_multi.tmpl | 192 +-- nano/templates/turret.tmpl | 176 +-- nano/templates/turret_control.tmpl | 82 +- nano/templates/uplink.tmpl | 178 +-- tools/TagMatcher/checkTagMatches.bat | 6 +- tools/TagMatcher/tag-matcher.py | 240 ++-- tools/dmitool/git_merge_installer.bat | 12 +- tools/expand_filedir_paths.py | 186 +-- tools/mapcapturemerge/.gitignore | 6 +- tools/mapcapturemerge/imageHelpers.py | 30 +- tools/mapcapturemerge/merge.py | 82 +- 51 files changed, 4215 insertions(+), 4215 deletions(-) diff --git a/.gitignore b/.gitignore index b7e92fbae535..3d638d224bdc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,62 +1,62 @@ -# ignore misc BYOND files -*.log -*.int -*.rsc -*.dmb -*.lk -*.backup -*.before -data/ -dmdoc/ -cfg/ -build_log.txt -use_map -stopserver -reboot_called -atupdate - -# ignore config, but not subdirs -!config/*/ -config/* -sql/test_db - -# misc OS garbage -Thumbs.db -Thumbs.db:encryptable -.DS_Store - -# vscode -.vscode/* -*.code-workspace -.history - -# git/kdiff4 -*.orig - -# swap -[._]*.s[a-v][a-z] -[._]*.sw[a-p] -[._]s[a-v][a-z] -[._]sw[a-p] - -# session -Session.vim - -# temporary -.netrwhist -*~ - -# auto-generated tag files -tags - -# ignore built libs -lib/*.dll -lib/*.so -/prof.dll - -# python -*.pyc -__pycache__ - -# Running OpenDream locally -nebula.json +# ignore misc BYOND files +*.log +*.int +*.rsc +*.dmb +*.lk +*.backup +*.before +data/ +dmdoc/ +cfg/ +build_log.txt +use_map +stopserver +reboot_called +atupdate + +# ignore config, but not subdirs +!config/*/ +config/* +sql/test_db + +# misc OS garbage +Thumbs.db +Thumbs.db:encryptable +.DS_Store + +# vscode +.vscode/* +*.code-workspace +.history + +# git/kdiff4 +*.orig + +# swap +[._]*.s[a-v][a-z] +[._]*.sw[a-p] +[._]s[a-v][a-z] +[._]sw[a-p] + +# session +Session.vim + +# temporary +.netrwhist +*~ + +# auto-generated tag files +tags + +# ignore built libs +lib/*.dll +lib/*.so +/prof.dll + +# python +*.pyc +__pycache__ + +# Running OpenDream locally +nebula.json diff --git a/README.md b/README.md index 3d4d64d1569e..60c5fccb5b77 100644 --- a/README.md +++ b/README.md @@ -1,81 +1,81 @@ -

    -
    - Nebula 13 -
    - Nebula 13 -
    -

    - -

    - - Build Status - - - CodeFactor - - - Last Commit - - - Issues - - - Discord - - - License - -

    - -

    - Contributing Guidelines • - Security • - License • - Getting the Code and Installing -

    - ---- - -### NOTICE OF MODIFICATION - -This project was forked from [Baystation 12](https://github.com/Baystation12/Baystation12) on 6 Jan 2020. - ---- - -### CONTRIBUTING GUIDELINES - -All users are expected to review [/docs/CODE_OF_CONDUCT.md](/docs/CODE_OF_CONDUCT.md) before interacting with the repository or other users. - ---- - -### SECURITY - -Please see [/docs/SECURITY.md](/docs/SECURITY.md) for this repository's security policy, and how to report security issues. - ---- - -### LICENSE - -The code for Nebula13 is licensed under the [GNU Affero General Public License v3](http://www.gnu.org/licenses/agpl.html), which can be found in full in [/LICENSE](/LICENSE). - -Code with a git authorship date prior to `1420675200 +0000` (2015/01/08 00:00 GMT) is licensed under the GNU General Public License version 3, which can be found in full in [/docs/GPL3.txt](/docs/GPL3.txt) - -All code where the authorship dates on or after `1420675200 +0000` is assumed to be licensed under AGPL v3, if you wish to license under GPL v3 please make this clear in the commit message and any added files. - -If you wish to develop and host this codebase in a closed source manner you may use all commits prior to `1420675200 +0000`, which are licensed under GPL v3. The major change here is that if you host a server using any code licensed under AGPLv3 you are required to provide full source code for your servers users as well including addons and modifications you have made. - -See [here](https://www.gnu.org/licenses/why-affero-gpl.html) for more information. - -All assets including icons and sound are under a [Creative Commons 3.0 BY-SA license](http://creativecommons.org/licenses/by-sa/3.0/) unless otherwise indicated. - ---- - -### GETTING THE CODE AND INSTALLING - -Please see [/docs/installation.md](/docs/installation.md) for instructions on obtaining, installing, updating, and running this code. +

    +
    + Nebula 13 +
    + Nebula 13 +
    +

    + +

    + + Build Status + + + CodeFactor + + + Last Commit + + + Issues + + + Discord + + + License + +

    + +

    + Contributing Guidelines • + Security • + License • + Getting the Code and Installing +

    + +--- + +### NOTICE OF MODIFICATION + +This project was forked from [Baystation 12](https://github.com/Baystation12/Baystation12) on 6 Jan 2020. + +--- + +### CONTRIBUTING GUIDELINES + +All users are expected to review [/docs/CODE_OF_CONDUCT.md](/docs/CODE_OF_CONDUCT.md) before interacting with the repository or other users. + +--- + +### SECURITY + +Please see [/docs/SECURITY.md](/docs/SECURITY.md) for this repository's security policy, and how to report security issues. + +--- + +### LICENSE + +The code for Nebula13 is licensed under the [GNU Affero General Public License v3](http://www.gnu.org/licenses/agpl.html), which can be found in full in [/LICENSE](/LICENSE). + +Code with a git authorship date prior to `1420675200 +0000` (2015/01/08 00:00 GMT) is licensed under the GNU General Public License version 3, which can be found in full in [/docs/GPL3.txt](/docs/GPL3.txt) + +All code where the authorship dates on or after `1420675200 +0000` is assumed to be licensed under AGPL v3, if you wish to license under GPL v3 please make this clear in the commit message and any added files. + +If you wish to develop and host this codebase in a closed source manner you may use all commits prior to `1420675200 +0000`, which are licensed under GPL v3. The major change here is that if you host a server using any code licensed under AGPLv3 you are required to provide full source code for your servers users as well including addons and modifications you have made. + +See [here](https://www.gnu.org/licenses/why-affero-gpl.html) for more information. + +All assets including icons and sound are under a [Creative Commons 3.0 BY-SA license](http://creativecommons.org/licenses/by-sa/3.0/) unless otherwise indicated. + +--- + +### GETTING THE CODE AND INSTALLING + +Please see [/docs/installation.md](/docs/installation.md) for instructions on obtaining, installing, updating, and running this code. diff --git a/config/example/admin_ranks.txt b/config/example/admin_ranks.txt index 146a1aa77765..99c116e12387 100644 --- a/config/example/admin_ranks.txt +++ b/config/example/admin_ranks.txt @@ -1,45 +1,45 @@ -######################################################################################## -# ADMIN RANK DEFINES # -# The format of this is very simple. Rank name goes first. # -# Rank is CASE-SENSITIVE, all punctuation will be stripped so spaces don't matter. # -# Each rank is then followed by keywords with the prefix "+". # -# These keywords represent groups of verbs and abilities which are given to that rank. # -# +@ (or +prev) is a special shorthand which adds all the rights of the rank above it. # -# Ranks with no keywords will just be given the most basic verbs and abilities ~Carn # -######################################################################################## -# PLEASE NOTE: depending on config options, some abilities will be unavailable regardless if you have permission to use them! -# ALSO NOTE: this is a WorkInProgress at the moment. Most of this is just arbitrarily thrown in whatever group because LoadsaWork2Do+LittleTime. -# I'll be doing more moving around as feedback comes in. So be sure to check the notes after updates. - -# KEYWORDS: -# +ADMIN = general admin tools, verbs etc -# +FUN = events, other event-orientated actions. Access to the fun secrets in the secrets panel. -# +BAN = the ability to ban, jobban and fullban -# +STEALTH = the ability to stealthmin (make yourself appear with a fake name to everyone but other admins -# +POSSESS = the ability to possess objects -# +REJUV (or +REJUVINATE) = the ability to heal, respawn, modify damage and use godmode -# +BUILD (or +BUILDMODE) = the ability to use buildmode -# +SERVER = higher-risk admin verbs and abilities, such as those which affect the server configuration. -# +DEBUG = debug tools used for diagnosing and fixing problems. It's useful to give this to coders so they can investigate problems on a live server. -# +VAREDIT = everyone may view viewvars/debugvars/whatever you call it. This keyword allows you to actually EDIT those variables. -# +RIGHTS (or +PERMISSIONS) = allows you to promote and/or demote people. -# +SOUND (or +SOUNDS) = allows you to upload and play sounds -# +SPAWN (or +CREATE) = mob transformations, spawning of most atoms including mobs (high-risk atoms, e.g. blackholes, will require the +FUN flag too) -# +EVERYTHING (or +HOST or +ALL) = Simply gives you everything without having to type every flag - -RetiredAdmin - -Moderator +MOD -TrialModerator +MOD - -TrialAdmin +@ +ADMIN +STEALTH +SPAWN +REJUV +VAREDIT +BAN +SERVER -GameAdmin +@ +DEBUG +FUN +POSSESS +BUILDMODE +SOUND +PERMISSIONS -SeniorAdmin +@ - -HeadDeveloper +EVERYTHING -HeadAdmin +EVERYTHING -Host +EVERYTHING - -Developer +DEBUG +VAREDIT +SERVER +SPAWN +REJUV +POSSESS +BUILDMODE +ADMIN +FUN -TrialDevAdmin +DEBUG +VAREDIT +SERVER +SPAWN +REJUV +POSSESS +BUILDMODE +ADMIN +STEALTH +BAN +FUN -DevAdmin +DEBUG +VAREDIT +SERVER +SPAWN +REJUV +POSSESS +BUILDMODE +ADMIN +STEALTH +BAN +FUN +SOUND +PERMISSIONS +######################################################################################## +# ADMIN RANK DEFINES # +# The format of this is very simple. Rank name goes first. # +# Rank is CASE-SENSITIVE, all punctuation will be stripped so spaces don't matter. # +# Each rank is then followed by keywords with the prefix "+". # +# These keywords represent groups of verbs and abilities which are given to that rank. # +# +@ (or +prev) is a special shorthand which adds all the rights of the rank above it. # +# Ranks with no keywords will just be given the most basic verbs and abilities ~Carn # +######################################################################################## +# PLEASE NOTE: depending on config options, some abilities will be unavailable regardless if you have permission to use them! +# ALSO NOTE: this is a WorkInProgress at the moment. Most of this is just arbitrarily thrown in whatever group because LoadsaWork2Do+LittleTime. +# I'll be doing more moving around as feedback comes in. So be sure to check the notes after updates. + +# KEYWORDS: +# +ADMIN = general admin tools, verbs etc +# +FUN = events, other event-orientated actions. Access to the fun secrets in the secrets panel. +# +BAN = the ability to ban, jobban and fullban +# +STEALTH = the ability to stealthmin (make yourself appear with a fake name to everyone but other admins +# +POSSESS = the ability to possess objects +# +REJUV (or +REJUVINATE) = the ability to heal, respawn, modify damage and use godmode +# +BUILD (or +BUILDMODE) = the ability to use buildmode +# +SERVER = higher-risk admin verbs and abilities, such as those which affect the server configuration. +# +DEBUG = debug tools used for diagnosing and fixing problems. It's useful to give this to coders so they can investigate problems on a live server. +# +VAREDIT = everyone may view viewvars/debugvars/whatever you call it. This keyword allows you to actually EDIT those variables. +# +RIGHTS (or +PERMISSIONS) = allows you to promote and/or demote people. +# +SOUND (or +SOUNDS) = allows you to upload and play sounds +# +SPAWN (or +CREATE) = mob transformations, spawning of most atoms including mobs (high-risk atoms, e.g. blackholes, will require the +FUN flag too) +# +EVERYTHING (or +HOST or +ALL) = Simply gives you everything without having to type every flag + +RetiredAdmin + +Moderator +MOD +TrialModerator +MOD + +TrialAdmin +@ +ADMIN +STEALTH +SPAWN +REJUV +VAREDIT +BAN +SERVER +GameAdmin +@ +DEBUG +FUN +POSSESS +BUILDMODE +SOUND +PERMISSIONS +SeniorAdmin +@ + +HeadDeveloper +EVERYTHING +HeadAdmin +EVERYTHING +Host +EVERYTHING + +Developer +DEBUG +VAREDIT +SERVER +SPAWN +REJUV +POSSESS +BUILDMODE +ADMIN +FUN +TrialDevAdmin +DEBUG +VAREDIT +SERVER +SPAWN +REJUV +POSSESS +BUILDMODE +ADMIN +STEALTH +BAN +FUN +DevAdmin +DEBUG +VAREDIT +SERVER +SPAWN +REJUV +POSSESS +BUILDMODE +ADMIN +STEALTH +BAN +FUN +SOUND +PERMISSIONS diff --git a/config/example/admins.txt b/config/example/admins.txt index 3b830cd27ff8..ae1ab106a512 100644 --- a/config/example/admins.txt +++ b/config/example/admins.txt @@ -1,8 +1,8 @@ -###################################################################### -# Basically, ckey goes first. Rank goes after the "-" # -# Case is not important for ckey. # -# Case IS important for the rank. However punctuation/spaces are not # -# Ranks can be anything defined in admin_ranks.txt ~Carn # -###################################################################### - -# not_a_user - Admin +###################################################################### +# Basically, ckey goes first. Rank goes after the "-" # +# Case is not important for ckey. # +# Case IS important for the rank. However punctuation/spaces are not # +# Ranks can be anything defined in admin_ranks.txt ~Carn # +###################################################################### + +# not_a_user - Admin diff --git a/config/example/dbconfig.txt b/config/example/dbconfig.txt index 3c056d2adf78..8ed5047c4923 100644 --- a/config/example/dbconfig.txt +++ b/config/example/dbconfig.txt @@ -1,20 +1,20 @@ -# MySQL Connection Configuration - -# First of all, should SQL be used at all. Unhash next line, if yes -# ENABLED - -# Server the MySQL database can be found at -# Examples: localhost, 200.135.5.43, www.mysqldb.com, etc. -ADDRESS localhost - -# MySQL server port (default is 3306) -PORT 3306 - -# Database the population, death, karma, etc. tables may be found in -DATABASE tgstation - -# Username/Login used to access the database -LOGIN mylogin - -# Password used to access the database -PASSWORD mypassword +# MySQL Connection Configuration + +# First of all, should SQL be used at all. Unhash next line, if yes +# ENABLED + +# Server the MySQL database can be found at +# Examples: localhost, 200.135.5.43, www.mysqldb.com, etc. +ADDRESS localhost + +# MySQL server port (default is 3306) +PORT 3306 + +# Database the population, death, karma, etc. tables may be found in +DATABASE tgstation + +# Username/Login used to access the database +LOGIN mylogin + +# Password used to access the database +PASSWORD mypassword diff --git a/config/example/dbconfig_docker.txt b/config/example/dbconfig_docker.txt index 7f3fe3ba6666..929f19d51400 100644 --- a/config/example/dbconfig_docker.txt +++ b/config/example/dbconfig_docker.txt @@ -1,22 +1,22 @@ -# For running on the included Dockerized database + gameserver -# MySQL Connection Configuration - -# Server the MySQL database can be found at -# Examples: localhost, 200.135.5.43, www.mysqldb.com, etc. -ADDRESS db - -# MySQL server port (default is 3306) -PORT 3306 - -# Database the population, death, karma, etc. tables may be found in -DATABASE bs12 - -# Username/Login used to access the database -LOGIN gamelord - -# Password used to access the database -PASSWORD gamelord - -# Track population and death statistics -# Comment this out to disable +# For running on the included Dockerized database + gameserver +# MySQL Connection Configuration + +# Server the MySQL database can be found at +# Examples: localhost, 200.135.5.43, www.mysqldb.com, etc. +ADDRESS db + +# MySQL server port (default is 3306) +PORT 3306 + +# Database the population, death, karma, etc. tables may be found in +DATABASE bs12 + +# Username/Login used to access the database +LOGIN gamelord + +# Password used to access the database +PASSWORD gamelord + +# Track population and death statistics +# Comment this out to disable ENABLE_STAT_TRACKING \ No newline at end of file diff --git a/config/example/jobs.txt b/config/example/jobs.txt index 8279ed18b1a2..060cf2d6a737 100644 --- a/config/example/jobs.txt +++ b/config/example/jobs.txt @@ -1,37 +1,37 @@ -Captain=1 -Head of Personnel=1 -Head of Security=1 -Chief Engineer=1 -Research Director=1 -Chief Medical Officer=1 - -Station Engineer=5 -Roboticist=1 - -Medical Doctor=5 -Geneticist=2 -Virologist=1 - -Scientist=3 -Chemist=2 - -Bartender=1 -Botanist=2 -Chef=1 -Janitor=1 -Quartermaster=1 -Shaft Miner=3 - -Warden=1 -Detective=1 -Security Officer=5 - -Assistant=-1 -Atmospheric Technician=4 -Cargo Technician=3 -Chaplain=1 -Lawyer=2 -Librarian=1 - -AI=1 +Captain=1 +Head of Personnel=1 +Head of Security=1 +Chief Engineer=1 +Research Director=1 +Chief Medical Officer=1 + +Station Engineer=5 +Roboticist=1 + +Medical Doctor=5 +Geneticist=2 +Virologist=1 + +Scientist=3 +Chemist=2 + +Bartender=1 +Botanist=2 +Chef=1 +Janitor=1 +Quartermaster=1 +Shaft Miner=3 + +Warden=1 +Detective=1 +Security Officer=5 + +Assistant=-1 +Atmospheric Technician=4 +Cargo Technician=3 +Chaplain=1 +Lawyer=2 +Librarian=1 + +AI=1 Cyborg=1 \ No newline at end of file diff --git a/config/example/motd.txt b/config/example/motd.txt index 09727a101d5f..ada540e0c886 100644 --- a/config/example/motd.txt +++ b/config/example/motd.txt @@ -1,5 +1,5 @@ -

    Welcome to Space Station 13!

    - --This server is running Nebula, a modification of the Baystation12 SS13 code. -

    -Bugtracker: Go here for posting of bugs and issues. +

    Welcome to Space Station 13!

    + +-This server is running Nebula, a modification of the Baystation12 SS13 code. +

    +Bugtracker: Go here for posting of bugs and issues. diff --git a/config/example/rules.html b/config/example/rules.html index 9fbad55bcf9a..d36a7bb415d0 100644 --- a/config/example/rules.html +++ b/config/example/rules.html @@ -1,11 +1,11 @@ - -Server Rules - - - - - + +Server Rules + + + + + \ No newline at end of file diff --git a/config/names/adjectives.txt b/config/names/adjectives.txt index ab0b4ba18068..73b6a4076db2 100644 --- a/config/names/adjectives.txt +++ b/config/names/adjectives.txt @@ -1,397 +1,397 @@ -adorable -adventurous -aggressive -alert -attractive -average -beautiful -blue-eyed -bloody -blushing -bright -clean -clear -cloudy -colorful -crowded -cute -dark -drab -distinct -dull -elegant -excited -fancy -filthy -glamorous -gleaming -gorgeous -graceful -grotesque -handsome -homely -light -long -magnificent -misty -motionless -muddy -old-fashioned -plain -poised -precious -quaint -shiny -smoggy -sparkling -spotless -stormy -strange -ugly -ugliest -unsightly -unusual -wide-eyed -alive -annoying -bad -better -beautiful -brainy -breakable -busy -careful -cautious -clever -clumsy -concerned -crazy -curious -dead -different -difficult -doubtful -easy -expensive -famous -fragile -frail -gifted -helpful -helpless -horrible -important -impossible -inexpensive -innocent -inquisitive -modern -mushy -odd -open -outstanding -poor -powerful -prickly -puzzled -real -rich -shy -sleepy -stupid -super -talented -tame -tender -tough -uninterested -vast -wandering -wild -wrong - -angry -annoyed -anxious -arrogant -ashamed -awful -bad -bewildered -black -blue -bored -clumsy -combative -condemned -confused -crazy,flipped-out -creepy -cruel -dangerous -defeated -defiant -depressed -disgusted -disturbed -dizzy -dull -embarrassed -envious -evil -fierce -foolish -frantic -frightened -grieving -grumpy -helpless -homeless -hungry -hurt -ill -itchy -jealous -jittery -lazy -lonely -mysterious -nasty -naughty -nervous -nutty -obnoxious -outrageous -panicky -repulsive -scary -selfish -sore -tense -terrible -testy -thoughtless -tired -troubled -upset -uptight -weary -wicked -worried -agreeable -amused -brave -calm -charming -cheerful -comfortable -cooperative -courageous -delightful -determined -eager -elated -enchanting -encouraging -energetic -enthusiastic -excited -exuberant -fair -faithful -fantastic -fine -friendly -funny -gentle -glorious -good -happy -healthy -helpful -hilarious -jolly -joyous -kind -lively -lovely -lucky -nice -obedient -perfect -pleasant -proud -relieved -silly -smiling -splendid -successful -thankful -thoughtful -victorious -vivacious -witty -wonderful -zealous -zany -broad -chubby -crooked -curved -deep -flat -high -hollow -low -narrow -round -shallow -skinny -square -steep -straight -wide -big -colossal -fat -gigantic -great -huge -immense -large -little -mammoth -massive -miniature -petite -puny -scrawny -short -small -tall -teeny -teeny-tiny -tiny -cooing -deafening -faint -harsh -high-pitched -hissing -hushed -husky -loud -melodic -moaning -mute -noisy -purring -quiet -raspy -resonant -screeching -shrill -silent -soft -squealing -thundering -voiceless -whispering -ancient -brief -early -fast -late -long -modern -old -old-fashioned -quick -rapid -short -slow -swift -young -Taste/Touch -bitter -delicious -fresh -juicy -ripe -rotten -salty -sour -spicy -stale -sticky -strong -sweet -tart -tasteless -tasty -thirsty -fluttering -fuzzy -greasy -grubby -hard -hot -icy -loose -melted -nutritious -plastic -prickly -rainy -rough -scattered -shaggy -shaky -sharp -shivering -silky -slimy -slippery -smooth -soft -solid -steady -sticky -tender -tight -uneven -weak -wet -wooden -yummy -boiling -breezy -broken -bumpy -chilly -cold -cool -creepy -crooked -cuddly -curly -damaged -damp -dirty -dry -dusty -filthy -flaky -fluffy -freezing -hot -warm -wet -abundant -empty -few -heavy -light -many -numerous +adorable +adventurous +aggressive +alert +attractive +average +beautiful +blue-eyed +bloody +blushing +bright +clean +clear +cloudy +colorful +crowded +cute +dark +drab +distinct +dull +elegant +excited +fancy +filthy +glamorous +gleaming +gorgeous +graceful +grotesque +handsome +homely +light +long +magnificent +misty +motionless +muddy +old-fashioned +plain +poised +precious +quaint +shiny +smoggy +sparkling +spotless +stormy +strange +ugly +ugliest +unsightly +unusual +wide-eyed +alive +annoying +bad +better +beautiful +brainy +breakable +busy +careful +cautious +clever +clumsy +concerned +crazy +curious +dead +different +difficult +doubtful +easy +expensive +famous +fragile +frail +gifted +helpful +helpless +horrible +important +impossible +inexpensive +innocent +inquisitive +modern +mushy +odd +open +outstanding +poor +powerful +prickly +puzzled +real +rich +shy +sleepy +stupid +super +talented +tame +tender +tough +uninterested +vast +wandering +wild +wrong + +angry +annoyed +anxious +arrogant +ashamed +awful +bad +bewildered +black +blue +bored +clumsy +combative +condemned +confused +crazy,flipped-out +creepy +cruel +dangerous +defeated +defiant +depressed +disgusted +disturbed +dizzy +dull +embarrassed +envious +evil +fierce +foolish +frantic +frightened +grieving +grumpy +helpless +homeless +hungry +hurt +ill +itchy +jealous +jittery +lazy +lonely +mysterious +nasty +naughty +nervous +nutty +obnoxious +outrageous +panicky +repulsive +scary +selfish +sore +tense +terrible +testy +thoughtless +tired +troubled +upset +uptight +weary +wicked +worried +agreeable +amused +brave +calm +charming +cheerful +comfortable +cooperative +courageous +delightful +determined +eager +elated +enchanting +encouraging +energetic +enthusiastic +excited +exuberant +fair +faithful +fantastic +fine +friendly +funny +gentle +glorious +good +happy +healthy +helpful +hilarious +jolly +joyous +kind +lively +lovely +lucky +nice +obedient +perfect +pleasant +proud +relieved +silly +smiling +splendid +successful +thankful +thoughtful +victorious +vivacious +witty +wonderful +zealous +zany +broad +chubby +crooked +curved +deep +flat +high +hollow +low +narrow +round +shallow +skinny +square +steep +straight +wide +big +colossal +fat +gigantic +great +huge +immense +large +little +mammoth +massive +miniature +petite +puny +scrawny +short +small +tall +teeny +teeny-tiny +tiny +cooing +deafening +faint +harsh +high-pitched +hissing +hushed +husky +loud +melodic +moaning +mute +noisy +purring +quiet +raspy +resonant +screeching +shrill +silent +soft +squealing +thundering +voiceless +whispering +ancient +brief +early +fast +late +long +modern +old +old-fashioned +quick +rapid +short +slow +swift +young +Taste/Touch +bitter +delicious +fresh +juicy +ripe +rotten +salty +sour +spicy +stale +sticky +strong +sweet +tart +tasteless +tasty +thirsty +fluttering +fuzzy +greasy +grubby +hard +hot +icy +loose +melted +nutritious +plastic +prickly +rainy +rough +scattered +shaggy +shaky +sharp +shivering +silky +slimy +slippery +smooth +soft +solid +steady +sticky +tender +tight +uneven +weak +wet +wooden +yummy +boiling +breezy +broken +bumpy +chilly +cold +cool +creepy +crooked +cuddly +curly +damaged +damp +dirty +dry +dusty +filthy +flaky +fluffy +freezing +hot +warm +wet +abundant +empty +few +heavy +light +many +numerous substantial \ No newline at end of file diff --git a/config/names/ai.txt b/config/names/ai.txt index 1ebd9400d2eb..52ef74313217 100644 --- a/config/names/ai.txt +++ b/config/names/ai.txt @@ -1,55 +1,55 @@ -A-SYNC -Alpha v0.9 -AI -Algebra -A.P.T. -B-4 -B-9 -Beta v0.5 -BLUE-PRNT -Bright -B.U.F.F.E.R. -CALC -Calculus -Chroot -Cruiser -D-LITE -Digit -DSTAR -E.X.E.C. -F.I.N.D. -FG-N1 -Force -GREP -H.E.A.D. -Idle -IN-2 -JLT-0 -Kernel -LC-8 -LS-AL -M.A.K.E. -NAN -NAND -Neon -Neumann -NOR -NOT -OMNI -OVR-FLW -PID-0 -PTO -PWR-10K -R0-MAN -Q-TE -R.M. -SED-N -Station -TA-IL -T.O.P. -U-TM -VER-T G0 -Wisdom -XOR -Y2K +A-SYNC +Alpha v0.9 +AI +Algebra +A.P.T. +B-4 +B-9 +Beta v0.5 +BLUE-PRNT +Bright +B.U.F.F.E.R. +CALC +Calculus +Chroot +Cruiser +D-LITE +Digit +DSTAR +E.X.E.C. +F.I.N.D. +FG-N1 +Force +GREP +H.E.A.D. +Idle +IN-2 +JLT-0 +Kernel +LC-8 +LS-AL +M.A.K.E. +NAN +NAND +Neon +Neumann +NOR +NOT +OMNI +OVR-FLW +PID-0 +PTO +PWR-10K +R0-MAN +Q-TE +R.M. +SED-N +Station +TA-IL +T.O.P. +U-TM +VER-T G0 +Wisdom +XOR +Y2K ZE-M3 \ No newline at end of file diff --git a/config/names/ninjaname.txt b/config/names/ninjaname.txt index 24d5d6879ef9..828bc17039de 100644 --- a/config/names/ninjaname.txt +++ b/config/names/ninjaname.txt @@ -1,45 +1,45 @@ -Shadow -Sarutobi -Smoke -Rain -Scorpion -Zero -Ermac -Saibot -Sun -Moon -Cyrax -Raphael -Michaelangelo -Cloud -Donatello -Leonardo -Splinter -Shredder -Hazuki -Hien -Hiryu -Ryu -Hayabusa -Midnight -Seven -Hanzo -Blood -Iga -Koga -Hero -Hiro -Phantom -Baki -Ogre -Daemon -Goemon -Throat -Death -Aria -Bro -Fox -Null -Raiden -Samurai +Shadow +Sarutobi +Smoke +Rain +Scorpion +Zero +Ermac +Saibot +Sun +Moon +Cyrax +Raphael +Michaelangelo +Cloud +Donatello +Leonardo +Splinter +Shredder +Hazuki +Hien +Hiryu +Ryu +Hayabusa +Midnight +Seven +Hanzo +Blood +Iga +Koga +Hero +Hiro +Phantom +Baki +Ogre +Daemon +Goemon +Throat +Death +Aria +Bro +Fox +Null +Raiden +Samurai Eater \ No newline at end of file diff --git a/config/names/ninjatitle.txt b/config/names/ninjatitle.txt index 966204bb4dcf..429425ca8e06 100644 --- a/config/names/ninjatitle.txt +++ b/config/names/ninjatitle.txt @@ -1,46 +1,46 @@ -Master -Sensei -Swift -Merciless -Assassin -Rogue -Hunter -Widower -Orphaner -Stalker -Killer -Silent -Silencing -Quick -Agile -Merciful -Ninja -Shinobi -Initiate -Grandmaster -Strider -Striker -Slayer -Awesome -Ender -Dr. -Night -Crimson -Grappler -Ulimate -Remorseless -Deep -Dragon -Cruel -Nightshade -Black -Gray -Solid -Liquid -Solidus -Steel -Nickel -Silver -Singing -Snake +Master +Sensei +Swift +Merciless +Assassin +Rogue +Hunter +Widower +Orphaner +Stalker +Killer +Silent +Silencing +Quick +Agile +Merciful +Ninja +Shinobi +Initiate +Grandmaster +Strider +Striker +Slayer +Awesome +Ender +Dr. +Night +Crimson +Grappler +Ulimate +Remorseless +Deep +Dragon +Cruel +Nightshade +Black +Gray +Solid +Liquid +Solidus +Steel +Nickel +Silver +Singing +Snake Acid \ No newline at end of file diff --git a/config/names/verbs.txt b/config/names/verbs.txt index e036e3c1dabb..5bb8d6e3139a 100644 --- a/config/names/verbs.txt +++ b/config/names/verbs.txt @@ -1,633 +1,633 @@ -accept -add -admire -admit -advise -afford -agree -alert -allow -amuse -analyse -announce -annoy -answer -apologise -appear -applaud -appreciate -approve -argue -arrange -arrest -arrive -ask -attach -attack -attempt -attend -attract -avoid -back -bake -balance -ban -bang -bare -bat -bathe -battle -beam -beg -behave -belong -bleach -bless -blind -blink -blot -blush -boast -boil -bolt -bomb -book -bore -borrow -bounce -bow -box -brake -brake -branch -breathe -bruise -brush -bubble -bump -burn -bury -buzz -calculate -call -camp -care -carry -carve -cause -challenge -change -charge -chase -cheat -check -cheer -chew -choke -chop -claim -clap -clean -clear -clip -close -coach -coil -collect -colour -comb -command -communicate -compare -compete -complain -complete -concentrate -concern -confess -confuse -connect -consider -consist -contain -continue -copy -correct -cough -count -cover -crack -crash -crawl -cross -crush -cry -cure -curl -curve -cycle -dam -damage -dance -dare -decay -deceive -decide -decorate -delay -delight -deliver -depend -describe -desert -deserve -destroy -detect -develop -disagree -disappear -disapprove -disarm -discover -dislike -divide -double -doubt -drag -drain -dream -dress -drip -drop -drown -drum -dry -dust -earn -educate -embarrass -employ -empty -encourage -end -enjoy -enter -entertain -escape -examine -excite -excuse -exercise -exist -expand -expect -explain -explode -extend -face -fade -fail -fancy -fasten -fax -fear -fence -fetch -file -fill -film -fire -fit -fix -flap -flash -float -flood -flow -flower -fold -follow -fool -force -form -found -frame -frighten -fry -gather -gaze -glow -glue -grab -grate -grease -greet -grin -grip -groan -guarantee -guard -guess -guide -hammer -hand -handle -hang -happen -harass -harm -hate -haunt -head -heal -heap -heat -help -hook -hop -hope -hover -hug -hum -hunt -hurry -identify -ignore -imagine -impress -improve -include -increase -influence -inform -inject -injure -instruct -intend -interest -interfere -interrupt -introduce -invent -invite -irritate -itch -jail -jam -jog -join -joke -judge -juggle -jump -kick -kill -kiss -kneel -knit -knock -knot -label -land -last -laugh -launch -learn -level -license -lick -lie -lighten -like -list -listen -live -load -lock -long -look -love -man -manage -march -mark -marry -match -mate -matter -measure -meddle -melt -memorise -mend -messup -milk -mine -miss -mix -moan -moor -mourn -move -muddle -mug -multiply -murder -nail -name -need -nest -nod -note -notice -number -obey -object -observe -obtain -occur -offend -offer -open -order -overflow -owe -own -pack -paddle -paint -park -part -pass -paste -pat -pause -peck -pedal -peel -peep -perform -permit -phone -pick -pinch -pine -place -plan -plant -play -please -plug -point -poke -polish -pop -possess -post -pour -practise -pray -preach -precede -prefer -prepare -present -preserve -press -pretend -prevent -prick -print -produce -program -promise -protect -provide -pull -pump -punch -puncture -punish -push -question -queue -race -radiate -rain -raise -reach -realise -receive -recognise -record -reduce -reflect -refuse -regret -reign -reject -rejoice -relax -release -rely -remain -remember -remind -remove -repair -repeat -replace -reply -report -reproduce -request -rescue -retire -return -rhyme -rinse -risk -rob -rock -roll -rot -rub -ruin -rule -rush -sack -sail -satisfy -save -saw -scare -scatter -scold -scorch -scrape -scratch -scream -screw -scribble -scrub -seal -search -separate -serve -settle -shade -share -shave -shelter -shiver -shock -shop -shrug -sigh -sign -signal -sin -sip -ski -skip -slap -slip -slow -smash -smell -smile -smoke -snatch -sneeze -sniff -snore -snow -soak -soothe -sound -spare -spark -sparkle -spell -spill -spoil -spot -spray -sprout -squash -squeak -squeal -squeeze -stain -stamp -stare -start -stay -steer -step -stir -stitch -stop -store -strap -strengthen -stretch -strip -stroke -stuff -subtract -succeed -suck -suffer -suggest -suit -supply -support -suppose -surprise -surround -suspect -suspend -switch -talk -tame -tap -taste -tease -telephone -tempt -terrify -test -thank -thaw -tick -tickle -tie -time -tip -tire -touch -tour -tow -trace -trade -train -transport -trap -travel -treat -tremble -trick -trip -trot -trouble -trust -try -tug -tumble -turn -twist -type -undress -unfasten -unite -unlock -unpack -untidy -use -vanish -visit -wail -wait -walk -wander -want -warm -warn -wash -waste -watch -water -wave -weigh -welcome -whine -whip -whirl -whisper -whistle -wink -wipe -wish -wobble -wonder -work -worry -wrap -wreck -wrestle -wriggle -yawn -yell -zip +accept +add +admire +admit +advise +afford +agree +alert +allow +amuse +analyse +announce +annoy +answer +apologise +appear +applaud +appreciate +approve +argue +arrange +arrest +arrive +ask +attach +attack +attempt +attend +attract +avoid +back +bake +balance +ban +bang +bare +bat +bathe +battle +beam +beg +behave +belong +bleach +bless +blind +blink +blot +blush +boast +boil +bolt +bomb +book +bore +borrow +bounce +bow +box +brake +brake +branch +breathe +bruise +brush +bubble +bump +burn +bury +buzz +calculate +call +camp +care +carry +carve +cause +challenge +change +charge +chase +cheat +check +cheer +chew +choke +chop +claim +clap +clean +clear +clip +close +coach +coil +collect +colour +comb +command +communicate +compare +compete +complain +complete +concentrate +concern +confess +confuse +connect +consider +consist +contain +continue +copy +correct +cough +count +cover +crack +crash +crawl +cross +crush +cry +cure +curl +curve +cycle +dam +damage +dance +dare +decay +deceive +decide +decorate +delay +delight +deliver +depend +describe +desert +deserve +destroy +detect +develop +disagree +disappear +disapprove +disarm +discover +dislike +divide +double +doubt +drag +drain +dream +dress +drip +drop +drown +drum +dry +dust +earn +educate +embarrass +employ +empty +encourage +end +enjoy +enter +entertain +escape +examine +excite +excuse +exercise +exist +expand +expect +explain +explode +extend +face +fade +fail +fancy +fasten +fax +fear +fence +fetch +file +fill +film +fire +fit +fix +flap +flash +float +flood +flow +flower +fold +follow +fool +force +form +found +frame +frighten +fry +gather +gaze +glow +glue +grab +grate +grease +greet +grin +grip +groan +guarantee +guard +guess +guide +hammer +hand +handle +hang +happen +harass +harm +hate +haunt +head +heal +heap +heat +help +hook +hop +hope +hover +hug +hum +hunt +hurry +identify +ignore +imagine +impress +improve +include +increase +influence +inform +inject +injure +instruct +intend +interest +interfere +interrupt +introduce +invent +invite +irritate +itch +jail +jam +jog +join +joke +judge +juggle +jump +kick +kill +kiss +kneel +knit +knock +knot +label +land +last +laugh +launch +learn +level +license +lick +lie +lighten +like +list +listen +live +load +lock +long +look +love +man +manage +march +mark +marry +match +mate +matter +measure +meddle +melt +memorise +mend +messup +milk +mine +miss +mix +moan +moor +mourn +move +muddle +mug +multiply +murder +nail +name +need +nest +nod +note +notice +number +obey +object +observe +obtain +occur +offend +offer +open +order +overflow +owe +own +pack +paddle +paint +park +part +pass +paste +pat +pause +peck +pedal +peel +peep +perform +permit +phone +pick +pinch +pine +place +plan +plant +play +please +plug +point +poke +polish +pop +possess +post +pour +practise +pray +preach +precede +prefer +prepare +present +preserve +press +pretend +prevent +prick +print +produce +program +promise +protect +provide +pull +pump +punch +puncture +punish +push +question +queue +race +radiate +rain +raise +reach +realise +receive +recognise +record +reduce +reflect +refuse +regret +reign +reject +rejoice +relax +release +rely +remain +remember +remind +remove +repair +repeat +replace +reply +report +reproduce +request +rescue +retire +return +rhyme +rinse +risk +rob +rock +roll +rot +rub +ruin +rule +rush +sack +sail +satisfy +save +saw +scare +scatter +scold +scorch +scrape +scratch +scream +screw +scribble +scrub +seal +search +separate +serve +settle +shade +share +shave +shelter +shiver +shock +shop +shrug +sigh +sign +signal +sin +sip +ski +skip +slap +slip +slow +smash +smell +smile +smoke +snatch +sneeze +sniff +snore +snow +soak +soothe +sound +spare +spark +sparkle +spell +spill +spoil +spot +spray +sprout +squash +squeak +squeal +squeeze +stain +stamp +stare +start +stay +steer +step +stir +stitch +stop +store +strap +strengthen +stretch +strip +stroke +stuff +subtract +succeed +suck +suffer +suggest +suit +supply +support +suppose +surprise +surround +suspect +suspend +switch +talk +tame +tap +taste +tease +telephone +tempt +terrify +test +thank +thaw +tick +tickle +tie +time +tip +tire +touch +tour +tow +trace +trade +train +transport +trap +travel +treat +tremble +trick +trip +trot +trouble +trust +try +tug +tumble +turn +twist +type +undress +unfasten +unite +unlock +unpack +untidy +use +vanish +visit +wail +wait +walk +wander +want +warm +warn +wash +waste +watch +water +wave +weigh +welcome +whine +whip +whirl +whisper +whistle +wink +wipe +wish +wobble +wonder +work +worry +wrap +wreck +wrestle +wriggle +yawn +yell +zip zoom \ No newline at end of file diff --git a/config/names/wizardfirst.txt b/config/names/wizardfirst.txt index 408ae3b447ee..18806ca74b7c 100644 --- a/config/names/wizardfirst.txt +++ b/config/names/wizardfirst.txt @@ -1,36 +1,36 @@ -Jim -Gulstaff -Gandalf -Grimm -Mordenkainen -Elminister -Saruman -Vaarsuvius -Yoda -Zul -Nihilus -Vecna -Mogan -Circe -Prospero -Raistlin -Rasputin -Tzeentch -Khelben -Dumbledor -Houdini -Terefi -Urza -Tenser -Zagyg -Mystryl -Boccob -Merlin -Archchancellor -Radagast -Kreol -Kaschei -Lina -Morgan -Alatar +Jim +Gulstaff +Gandalf +Grimm +Mordenkainen +Elminister +Saruman +Vaarsuvius +Yoda +Zul +Nihilus +Vecna +Mogan +Circe +Prospero +Raistlin +Rasputin +Tzeentch +Khelben +Dumbledor +Houdini +Terefi +Urza +Tenser +Zagyg +Mystryl +Boccob +Merlin +Archchancellor +Radagast +Kreol +Kaschei +Lina +Morgan +Alatar Palando \ No newline at end of file diff --git a/config/names/wizardsecond.txt b/config/names/wizardsecond.txt index d1e2e7348627..1fe60bdb2755 100644 --- a/config/names/wizardsecond.txt +++ b/config/names/wizardsecond.txt @@ -1,39 +1,39 @@ -the Powerful -the Great -the Magician -the Wise -the Seething -the Amazing -the Spiral King -Darkmagic -the White -the Gray -Shado -the Sorcelator -the Raven -the Emperor -the Brown -Weatherwax -the Destroyer -the Deathless -Yagg -the Remorseful -the Weeping -the Unending -the All Knowing -Dark -Smith -the Conquerer -the Unstoppable -Gray -of Void -Unseen -Darko -Honko -the Bandit Killer -the Dragon Spooker -Inverse -le Fay -the Blue -the Red +the Powerful +the Great +the Magician +the Wise +the Seething +the Amazing +the Spiral King +Darkmagic +the White +the Gray +Shado +the Sorcelator +the Raven +the Emperor +the Brown +Weatherwax +the Destroyer +the Deathless +Yagg +the Remorseful +the Weeping +the Unending +the All Knowing +Dark +Smith +the Conquerer +the Unstoppable +Gray +of Void +Unseen +Darko +Honko +the Bandit Killer +the Dragon Spooker +Inverse +le Fay +the Blue +the Red the Benevolent \ No newline at end of file diff --git a/html/changelog.css b/html/changelog.css index 59248aa23d8e..73d8fd6ebda6 100644 --- a/html/changelog.css +++ b/html/changelog.css @@ -1,79 +1,79 @@ -body{font-family:Tahoma,sans-serif;} -.top{font-size:12px;} -a img {border:none;} -.bgimages16 li { - padding:2px 10px 2px 30px; - background-position:6px center; - background-repeat:no-repeat; - border:1px solid #ddd; - border-left:4px solid #999; - margin-bottom:2px; -} -.bugfix {background-image:url(bug-minus.png)} -.wip {background-image:url(hard-hat-exclamation.png)} -.tweak {background-image:url(wrench-screwdriver.png)} -.soundadd {background-image:url(music-plus.png)} -.sounddel {background-image:url(music-minus.png)} -.rscdel {background-image:url(cross-circle.png)} -.rscadd {background-image:url(tick-circle.png)} -.imageadd {background-image:url(image-plus.png)} -.imagedel {background-image:url(image-minus.png)} -.spellcheck {background-image:url(spell-check.png)} -.experiment {background-image:url(burn-exclamation.png)} -.balance {background-image:url(scales.png)} -.maptweak {background-image:url(map-pencil.png)} -.admin {background-image:url(auction-hammer-gavel.png)} -.sansserif {font-size:12px;} -.commit { - margin-bottom:20px; - font-size:100%;font-weight:normal; -} -.changes { - list-style:none; - margin:5px 0; - padding:0 0 0 25px; - font-size:0.8em; -} -.date { - margin:10px 0; - color:blue; - border-bottom:2px solid #00f; - width:60%; - padding:2px 0; - font-size:1em; - font-weight:bold; -} -.author { - padding-left:10px; - margin:0; - font-weight:bold; - font-size:0.9em; - } -.drop { - cursor:pointer; - border:1px solid #999; - display:inline; - font-size:0.9em; - padding:1px 20px 1px 5px; - line-height:16px; -} -.hidden {display:none;} -.indrop { - margin:2px 0 0 0; - clear:both; - background:#fff; - border:1px solid #ddd; - padding:5px 10px; - } -.indrop p { - margin:0; - font-size:0.8em; - line-height:16px; - margin:1px 0; -} -.indrop img { - margin-right:5px; - vertical-align:middle;} -.closed {background:url(chevron-expand.png) right center no-repeat;} -.open {background:url(chevron.png) right center no-repeat;} -.lic {font-size:9px;} +body{font-family:Tahoma,sans-serif;} +.top{font-size:12px;} +a img {border:none;} +.bgimages16 li { + padding:2px 10px 2px 30px; + background-position:6px center; + background-repeat:no-repeat; + border:1px solid #ddd; + border-left:4px solid #999; + margin-bottom:2px; +} +.bugfix {background-image:url(bug-minus.png)} +.wip {background-image:url(hard-hat-exclamation.png)} +.tweak {background-image:url(wrench-screwdriver.png)} +.soundadd {background-image:url(music-plus.png)} +.sounddel {background-image:url(music-minus.png)} +.rscdel {background-image:url(cross-circle.png)} +.rscadd {background-image:url(tick-circle.png)} +.imageadd {background-image:url(image-plus.png)} +.imagedel {background-image:url(image-minus.png)} +.spellcheck {background-image:url(spell-check.png)} +.experiment {background-image:url(burn-exclamation.png)} +.balance {background-image:url(scales.png)} +.maptweak {background-image:url(map-pencil.png)} +.admin {background-image:url(auction-hammer-gavel.png)} +.sansserif {font-size:12px;} +.commit { + margin-bottom:20px; + font-size:100%;font-weight:normal; +} +.changes { + list-style:none; + margin:5px 0; + padding:0 0 0 25px; + font-size:0.8em; +} +.date { + margin:10px 0; + color:blue; + border-bottom:2px solid #00f; + width:60%; + padding:2px 0; + font-size:1em; + font-weight:bold; +} +.author { + padding-left:10px; + margin:0; + font-weight:bold; + font-size:0.9em; + } +.drop { + cursor:pointer; + border:1px solid #999; + display:inline; + font-size:0.9em; + padding:1px 20px 1px 5px; + line-height:16px; +} +.hidden {display:none;} +.indrop { + margin:2px 0 0 0; + clear:both; + background:#fff; + border:1px solid #ddd; + padding:5px 10px; + } +.indrop p { + margin:0; + font-size:0.8em; + line-height:16px; + margin:1px 0; +} +.indrop img { + margin-right:5px; + vertical-align:middle;} +.closed {background:url(chevron-expand.png) right center no-repeat;} +.open {background:url(chevron.png) right center no-repeat;} +.lic {font-size:9px;} diff --git a/html/changelogs/__CHANGELOG_README.txt b/html/changelogs/__CHANGELOG_README.txt index 6915dc47e25e..166e2bea8b62 100644 --- a/html/changelogs/__CHANGELOG_README.txt +++ b/html/changelogs/__CHANGELOG_README.txt @@ -1,19 +1,19 @@ -Changelogs are included with commits as text .yml files created individually by the committer. If you want to create a changelog entry you create a .yml file in the /changelogs directory; nothing else needs to be touched unless you are a maintainer. - -####################################################### - -TO MAKE A CHANGELOG .YML ENTRRY - -1. Make a copy of the file example.yml in html/changelogs and rename it to [YOUR USERNAME]-PR-[YOUR PR NUMBER].yml or [YOUR USERNAME]-[YOUR BRANCH NAME]. Only the username is strictly required, anything else is organizational and can be ignored if you so wish. - -2. Change the author to yourself - -3. Replace the changes text with a description of the changes in your PR, keep the double quotes to avoid errors (your changelog can be written ICly or OOCly, it doesn't matter) - -4. (Optional) set the change prefix (rscadd) to a different one listed above in example.yml (this affects what icon is used for your changelog entry) - -5. When commiting make sure your .yml file is included in the commit (it will usually be unticked as an unversioned file) - -####################################################### - -If you have trouble ask for help in #codershuttle on irc.sorcery.net or read https://tgstation13.org/wiki/Guide_to_Changelogs +Changelogs are included with commits as text .yml files created individually by the committer. If you want to create a changelog entry you create a .yml file in the /changelogs directory; nothing else needs to be touched unless you are a maintainer. + +####################################################### + +TO MAKE A CHANGELOG .YML ENTRRY + +1. Make a copy of the file example.yml in html/changelogs and rename it to [YOUR USERNAME]-PR-[YOUR PR NUMBER].yml or [YOUR USERNAME]-[YOUR BRANCH NAME]. Only the username is strictly required, anything else is organizational and can be ignored if you so wish. + +2. Change the author to yourself + +3. Replace the changes text with a description of the changes in your PR, keep the double quotes to avoid errors (your changelog can be written ICly or OOCly, it doesn't matter) + +4. (Optional) set the change prefix (rscadd) to a different one listed above in example.yml (this affects what icon is used for your changelog entry) + +5. When commiting make sure your .yml file is included in the commit (it will usually be unticked as an unversioned file) + +####################################################### + +If you have trouble ask for help in #codershuttle on irc.sorcery.net or read https://tgstation13.org/wiki/Guide_to_Changelogs diff --git a/html/changelogs/example.yml b/html/changelogs/example.yml index 05c234a82c0d..65bd6b448399 100644 --- a/html/changelogs/example.yml +++ b/html/changelogs/example.yml @@ -1,38 +1,38 @@ -################################ -# Example Changelog File -# -# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. -# -# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) -# When it is, any changes listed below will disappear. -# -# Valid Prefixes: -# bugfix -# wip (For works in progress) -# tweak -# soundadd -# sounddel -# rscadd (general adding of nice things) -# rscdel (general deleting of nice things) -# imageadd -# imagedel -# maptweak -# spellcheck (typo fixes) -# experiment -# admin -################################# - -# Your name. -author: Unknown - -# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. -delete-after: True - -# Any changes you've made. See valid prefix list above. -# INDENT WITH TWO SPACES. NOT TABS. SPACES. -# SCREW THIS UP AND IT WON'T WORK. -# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. -# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. -changes: - - rscadd: "Added a changelog editing system that should cause fewer conflicts and more accurate timestamps." - - rscdel: "Killed innocent kittens." +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +# admin +################################# + +# Your name. +author: Unknown + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Added a changelog editing system that should cause fewer conflicts and more accurate timestamps." + - rscdel: "Killed innocent kittens." diff --git a/html/create_object.html b/html/create_object.html index 899658fdb665..a505eb7dda31 100644 --- a/html/create_object.html +++ b/html/create_object.html @@ -1,126 +1,126 @@ - - - - Create Object - - - - -
    - - - - Type
    - Offset: - - A - R
    - - Number: - Dir: - Name:
    - Where: - -

    - Number of matches: -

    -
    - -
    - -
    -
    - - - - + + + + Create Object + + + + +
    + + + + Type
    + Offset: + + A + R
    + + Number: + Dir: + Name:
    + Where: + +

    + Number of matches: +

    +
    + +
    + +
    +
    + + + + \ No newline at end of file diff --git a/html/panels.css b/html/panels.css index 0d1cb0cb9fbe..ac44cf54877a 100644 --- a/html/panels.css +++ b/html/panels.css @@ -1,10 +1,10 @@ -body {padding:0px;margin:0px;} -#top {position:fixed;top:5px;left:10%;width:80%;text-align:center;background-color:#fff;border:2px solid #ccc;} -#main {position:relative;top:50px;left:3%;width:96%;text-align:center;z-index:0;} -#searchable {table-layout:fixed;width:100%;text-align:center;"#f4f4f4";} -tr.norm {background-color:#f4f4f4;} -tr.title {background-color:#ccc;} -tr.alt {background-color:#e7e7e7;} -.small {font-size:80%;} -a {text-decoration:none;color:#a0a;} -a:hover {color:#d3d;} +body {padding:0px;margin:0px;} +#top {position:fixed;top:5px;left:10%;width:80%;text-align:center;background-color:#fff;border:2px solid #ccc;} +#main {position:relative;top:50px;left:3%;width:96%;text-align:center;z-index:0;} +#searchable {table-layout:fixed;width:100%;text-align:center;"#f4f4f4";} +tr.norm {background-color:#f4f4f4;} +tr.title {background-color:#ccc;} +tr.alt {background-color:#e7e7e7;} +.small {font-size:80%;} +a {text-decoration:none;color:#a0a;} +a:hover {color:#d3d;} diff --git a/html/search.js b/html/search.js index abc47a975731..ded0b9284467 100644 --- a/html/search.js +++ b/html/search.js @@ -1,33 +1,33 @@ -function selectTextField(){ - var filter_text = document.getElementById('filter'); - filter_text.focus(); - filter_text.select(); -} -function updateSearch(){ - var input_form = document.getElementById('filter'); - var filter = input_form.value.toLowerCase(); - input_form.value = filter; - var table = document.getElementById('searchable'); - var alt_style = 'norm'; - for(var i = 0; i < table.rows.length; i++){ - try{ - var row = table.rows[i]; - if(row.className == 'title') continue; - var found=0; - for(var j = 0; j < row.cells.length; j++){ - var cell = row.cells[j]; - if(cell.innerText.toLowerCase().indexOf(filter) != -1){ - found=1; - break; - } - } - if(found == 0) row.style.display='none'; - else{ - row.style.display='block'; - row.className = alt_style; - if(alt_style == 'alt') alt_style = 'norm'; - else alt_style = 'alt'; - } - }catch(err) { } - } +function selectTextField(){ + var filter_text = document.getElementById('filter'); + filter_text.focus(); + filter_text.select(); +} +function updateSearch(){ + var input_form = document.getElementById('filter'); + var filter = input_form.value.toLowerCase(); + input_form.value = filter; + var table = document.getElementById('searchable'); + var alt_style = 'norm'; + for(var i = 0; i < table.rows.length; i++){ + try{ + var row = table.rows[i]; + if(row.className == 'title') continue; + var found=0; + for(var j = 0; j < row.cells.length; j++){ + var cell = row.cells[j]; + if(cell.innerText.toLowerCase().indexOf(filter) != -1){ + found=1; + break; + } + } + if(found == 0) row.style.display='none'; + else{ + row.style.display='block'; + row.className = alt_style; + if(alt_style == 'alt') alt_style = 'norm'; + else alt_style = 'alt'; + } + }catch(err) { } + } } \ No newline at end of file diff --git a/html/templates/footer.html b/html/templates/footer.html index 105e03de2ad0..68ce1ab76678 100644 --- a/html/templates/footer.html +++ b/html/templates/footer.html @@ -1,4 +1,4 @@ - - - - + + + + diff --git a/html/templates/header.html b/html/templates/header.html index 09df40020d4b..6d078158aca2 100644 --- a/html/templates/header.html +++ b/html/templates/header.html @@ -1,53 +1,53 @@ - - - - Nebula13 Changelog - - - - - - - -
    - - - - -
    -
    Nebula13
    -
    A Space Station 13 Project
    - -

    - Code licensed under AGPLv3. Content licensed under CC BY-SA 3.0.

    -
    - -
    Nebula13 Credit List - - - - -
    - Contributor list: -Click Here-
    - Special thanks to: the developers of Baystation 12, ScavStation, /tg/station, /vg/station, GoonStation, the original Space Station 13, and BYOND.
    -

    Have a bug to report?
    Visit our Issue Tracker.
    -
    - - -
    + + + + Nebula13 Changelog + + + + + + + +" @@ -132,9 +130,9 @@ if(!branch_string) branch_string = "" if(player_branch) - var/ranks = branch_rank[player_branch.name] || using_branches.spawn_ranks(player_branch.name, S) + var/ranks = branch_rank[player_branch.name] || global.using_map.spawn_ranks(player_branch.name, S) if(LAZYLEN(ranks)) - player_rank = using_branches.get_rank(player_branch.name, pref.ranks[job.title]) + player_rank = global.using_map.get_rank(player_branch.name, pref.ranks[job.title]) if(player_rank) if(LAZYLEN(ranks) > 1) rank_branch_string += "" @@ -259,8 +257,6 @@ /datum/category_item/player_setup_item/proc/validate_branch_and_rank() - var/datum/mil_branches/using_branches = global.using_map.mil_branches - if(LAZYLEN(pref.branches)) for(var/job_name in pref.branches) if(!(job_name in SSjobs.titles_to_datums)) @@ -279,16 +275,16 @@ var/datum/job/job = SSjobs.get_by_title(job_name) - var/datum/mil_branch/player_branch = pref.branches[job.title] ? using_branches.get_branch(pref.branches[job.title]) : null - var/branch_rank = job.allowed_branches ? job.get_branch_rank(S) : using_branches.spawn_branches(S) + var/datum/mil_branch/player_branch = pref.branches[job.title] ? global.using_map.get_branch(pref.branches[job.title]) : null + var/branch_rank = job.allowed_branches ? job.get_branch_rank(S) : global.using_map.spawn_branches(S) if(!player_branch || !(player_branch.name in branch_rank)) - player_branch = LAZYLEN(branch_rank) ? using_branches.get_branch(branch_rank[1]) : null + player_branch = LAZYLEN(branch_rank) ? global.using_map.get_branch(branch_rank[1]) : null if(player_branch) - var/datum/mil_rank/player_rank = pref.ranks[job.title] ? using_branches.get_rank(player_branch.name, pref.ranks[job.title]) : null - var/ranks = branch_rank[player_branch.name] || using_branches.spawn_ranks(player_branch.name, S) + var/datum/mil_rank/player_rank = pref.ranks[job.title] ? global.using_map.get_rank(player_branch.name, pref.ranks[job.title]) : null + var/ranks = branch_rank[player_branch.name] || global.using_map.spawn_ranks(player_branch.name, S) if(!player_rank || !(player_rank.name in ranks)) - player_rank = LAZYLEN(ranks) ? using_branches.get_rank(player_branch.name, ranks[1]) : null + player_rank = LAZYLEN(ranks) ? global.using_map.get_rank(player_branch.name, ranks[1]) : null // Now make the assignments pref.branches[job.title] = player_branch.name @@ -301,7 +297,6 @@ pref.ranks -= job.title /datum/category_item/player_setup_item/occupation/OnTopic(href, href_list, user) - var/datum/mil_branches/using_branches = global.using_map.mil_branches if(href_list["reset_jobs"]) ResetJobs() return TOPIC_REFRESH @@ -345,9 +340,9 @@ var/datum/job/job = locate(href_list["checking_job"]) if(istype(job)) var/decl/species/S = pref.get_species_decl() - var/list/options = job.allowed_branches ? job.get_branch_rank(S) : using_branches.spawn_branches(S) + var/list/options = job.allowed_branches ? job.get_branch_rank(S) : global.using_map.spawn_branches(S) var/choice = input(user, "Choose your branch of service.", CHARACTER_PREFERENCE_INPUT_TITLE) as null|anything in options - if(choice && CanUseTopic(user) && using_branches.is_spawn_branch(choice, S)) + if(choice && CanUseTopic(user) && global.using_map.is_spawn_branch(choice, S)) pref.branches[job.title] = choice pref.ranks -= job.title pref.skills_allocated = pref.sanitize_skills(pref.skills_allocated) // Check our skillset is still valid @@ -358,12 +353,12 @@ else if(href_list["char_rank"]) var/datum/job/job = locate(href_list["checking_job"]) if(istype(job)) - var/datum/mil_branch/branch = using_branches.get_branch(pref.branches[job.title]) + var/datum/mil_branch/branch = global.using_map.get_branch(pref.branches[job.title]) var/decl/species/S = pref.get_species_decl() - var/list/branch_rank = job.allowed_branches ? job.get_branch_rank(S) : using_branches.spawn_branches(S) - var/list/options = branch_rank[branch.name] || using_branches.spawn_ranks(branch.name, S) + var/list/branch_rank = job.allowed_branches ? job.get_branch_rank(S) : global.using_map.spawn_branches(S) + var/list/options = branch_rank[branch.name] || global.using_map.spawn_ranks(branch.name, S) var/choice = input(user, "Choose your rank.", CHARACTER_PREFERENCE_INPUT_TITLE) as null|anything in options - if(choice && CanUseTopic(user) && using_branches.is_spawn_rank(branch.name, choice, pref.get_species_decl())) + if(choice && CanUseTopic(user) && global.using_map.is_spawn_rank(branch.name, choice, pref.get_species_decl())) pref.ranks[job.title] = choice pref.skills_allocated = pref.sanitize_skills(pref.skills_allocated) // Check our skillset is still valid validate_branch_and_rank() @@ -430,7 +425,7 @@ if(job.allowed_branches) dat += "You can be of following ranks:" for(var/T in job.allowed_branches) - var/datum/mil_branch/B = using_branches.get_branch_by_type(T) + var/datum/mil_branch/B = global.using_map.get_branch_by_type(T) dat += "
  • [B.name]: [job.get_ranks(B.name)]" dat += "
    " if(get_config_value(/decl/config/text/wikiurl)) diff --git a/code/modules/client/preference_setup/occupation/skill_selection.dm b/code/modules/client/preference_setup/occupation/skill_selection.dm index acb013ddc275..6909a811fd5d 100644 --- a/code/modules/client/preference_setup/occupation/skill_selection.dm +++ b/code/modules/client/preference_setup/occupation/skill_selection.dm @@ -24,7 +24,7 @@ if(job && job.min_skill) . = job.min_skill[S.type] if(!.) - var/datum/mil_branch/branch = global.using_map.mil_branches.get_branch(branches[job.title]) + var/datum/mil_branch/branch = global.using_map.get_branch(branches[job.title]) if(branch && branch.min_skill) . = branch.min_skill[S.type] if(!.) diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index 7bc040ee5570..51565cfd714d 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -74,8 +74,8 @@ if((equip_preview_mob & EQUIP_PREVIEW_JOB) && previewJob) mannequin.job = previewJob.title - var/datum/mil_branch/branch = global.using_map.mil_branches.get_branch(branches[previewJob.title]) - var/datum/mil_rank/rank = global.using_map.mil_branches.get_rank(branches[previewJob.title], ranks[previewJob.title]) + var/datum/mil_branch/branch = global.using_map.get_branch(branches[previewJob.title]) + var/datum/mil_rank/rank = global.using_map.get_rank(branches[previewJob.title], ranks[previewJob.title]) previewJob.equip_preview(mannequin, player_alt_titles[previewJob.title], branch, rank) update_icon = TRUE diff --git a/code/modules/modular_computers/file_system/manifest.dm b/code/modules/modular_computers/file_system/manifest.dm index 9b07a16a2e1d..ee79e016bd94 100644 --- a/code/modules/modular_computers/file_system/manifest.dm +++ b/code/modules/modular_computers/file_system/manifest.dm @@ -26,8 +26,8 @@ mil_ranks[name] = "" if(global.using_map.flags & MAP_HAS_RANK) - var/datum/mil_branch/branch_obj = global.using_map.mil_branches.get_branch(CR.get_branch()) - var/datum/mil_rank/rank_obj = global.using_map.mil_branches.get_rank(CR.get_branch(), CR.get_rank()) + var/datum/mil_branch/branch_obj = global.using_map.get_branch(CR.get_branch()) + var/datum/mil_rank/rank_obj = global.using_map.get_rank(CR.get_branch(), CR.get_rank()) if(branch_obj && rank_obj) mil_ranks[name] = "[rank_obj.name_short] " diff --git a/code/modules/modular_computers/file_system/reports/crew_record.dm b/code/modules/modular_computers/file_system/reports/crew_record.dm index 1570b210e6bb..19af29eaeac7 100644 --- a/code/modules/modular_computers/file_system/reports/crew_record.dm +++ b/code/modules/modular_computers/file_system/reports/crew_record.dm @@ -266,7 +266,7 @@ FIELD_LONG("Exploitable Information", antag_record, access_hacked, access_hacked //Options builderes /datum/report_field/options/crew_record/rank/proc/record_ranks() var/datum/computer_file/report/crew_record/record = owner - var/datum/mil_branch/branch = global.using_map.mil_branches.get_branch(record.get_branch()) + var/datum/mil_branch/branch = global.using_map.get_branch(record.get_branch()) if(!branch) return . = list() @@ -287,8 +287,8 @@ FIELD_LONG("Exploitable Information", antag_record, access_hacked, access_hacked /datum/report_field/options/crew_record/branch/proc/record_branches() . = list() . |= "Unset" - for(var/branch in global.using_map.mil_branches.branches) - var/datum/mil_branch/branch_datum = global.using_map.mil_branches.branches[branch] + for(var/branch in global.using_map.branches) + var/datum/mil_branch/branch_datum = global.using_map.branches[branch] . |= branch_datum.name #undef GETTER_SETTER diff --git a/code/modules/modular_computers/file_system/reports/people.dm b/code/modules/modular_computers/file_system/reports/people.dm index 522c3e80c547..da2961c13adf 100644 --- a/code/modules/modular_computers/file_system/reports/people.dm +++ b/code/modules/modular_computers/file_system/reports/people.dm @@ -95,7 +95,7 @@ if(in_line && (global.using_map.flags & MAP_HAS_RANK)) var/datum/computer_file/report/crew_record/CR = get_crewmember_record(entry["name"]) if(CR) - var/datum/mil_rank/rank_obj = global.using_map.mil_branches.get_rank(CR.get_branch(), CR.get_rank()) + var/datum/mil_rank/rank_obj = global.using_map.get_rank(CR.get_branch(), CR.get_rank()) milrank = (rank_obj ? rank_obj.name_short : "") dat += format_output(entry["name"], in_line ? null : entry["rank"], milrank) return jointext(dat, in_line ? ", " : "
    ") diff --git a/code/modules/submaps/submap_join.dm b/code/modules/submaps/submap_join.dm index 615f96a05d22..4b1b6d3a4420 100644 --- a/code/modules/submaps/submap_join.dm +++ b/code/modules/submaps/submap_join.dm @@ -68,10 +68,9 @@ var/mob/living/human/user_human if(ishuman(character)) user_human = character - var/datum/mil_branches/using_branches = global.using_map.mil_branches - if(job.branch && global.using_map & MAP_HAS_BRANCH && using_branches) - user_human.char_branch = using_branches.get_branch(job.branch) - user_human.char_rank = using_branches.get_rank(job.branch, job.rank) + if(job.branch && (global.using_map.flags & MAP_HAS_BRANCH)) + user_human.char_branch = global.using_map.get_branch(job.branch) + user_human.char_rank = global.using_map.get_rank(job.branch, job.rank) // We need to make sure to use the abstract instance here; it's not the same as the one we were passed. character.skillset.obtain_from_client(SSjobs.get_by_path(job.type), character.client) diff --git a/maps/~mapsystem/map_ranks.dm b/maps/~mapsystem/map_ranks.dm index 5ced51e5f70b..8bd2dd54b04b 100644 --- a/maps/~mapsystem/map_ranks.dm +++ b/maps/~mapsystem/map_ranks.dm @@ -1,6 +1,13 @@ /datum/map - var/datum/mil_branches/mil_branches = new() - var/list/branch_types // list of branch datum paths for military branches available on this map + /// All branches that exist on this map + var/list/branches = list() + /// Branches that a player can choose for spawning on this map, not including species restrictions. + var/list/spawn_branches_ = list() + /// Branches that a player can choose for spawning on this map, with species restrictions. Populated on an as-needed basis + var/list/spawn_branches_by_species_ = list() + + /// list of branch datum paths for military branches available on this map + var/list/branch_types var/list/spawn_branch_types // subset of above for branches a player can spawn in with var/list/species_to_branch_whitelist = list() // List of branches which are allowed, per species. Checked before the blacklist. @@ -9,6 +16,100 @@ var/list/species_to_rank_whitelist = list() // List of ranks which are allowed, per branch and species. Checked before the blacklist. var/list/species_to_rank_blacklist = list() // Lists of ranks which are restricted, per species. +// todo: this will need heavy reworking if we promote submaps from second to first class map status +/** + * Populate the map branches list + */ +/datum/map/proc/populate_branches() + if(!(global.using_map.flags & MAP_HAS_BRANCH) && !(global.using_map.flags & MAP_HAS_RANK)) + branches = null + spawn_branches_ = null + spawn_branches_by_species_ = null + return 1 + + branches = list() + spawn_branches_ = list() + spawn_branches_by_species_ = list() + for(var/branch_path in global.using_map.branch_types) + if(!ispath(branch_path, /datum/mil_branch)) + PRINT_STACK_TRACE("populate_branches() attempted to instantiate object with path [branch_path], which is not a subtype of /datum/mil_branch.") + continue + + var/datum/mil_branch/branch = new branch_path () + branches[branch.name] = branch + + if(branch_path in global.using_map.spawn_branch_types) + spawn_branches_[branch.name] = branch + + return 1 + +/** + * Retrieve branch object by branch name + */ +/datum/map/proc/get_branch(var/branch_name) + if(ispath(branch_name, /datum/mil_branch)) + var/datum/mil_branch/branch = branch_name + branch_name = initial(branch.name) + if(branch_name && branch_name != "None") + return branches[branch_name] + +/** + * Retrieve branch object by branch type + */ +/datum/map/proc/get_branch_by_type(var/branch_type) + for(var/name in branches) + if (istype(branches[name], branch_type)) + return branches[name] + +/** + * Retrieve a rank object from given branch by name + */ +/datum/map/proc/get_rank(var/branch_name, var/rank_name) + if(ispath(rank_name)) + var/datum/mil_rank/rank = rank_name + rank_name = initial(rank.name) + if(rank_name && rank_name != "None") + var/datum/mil_branch/branch = get_branch(branch_name) + if(branch) + return branch.ranks[rank_name] + +/** + * Return all spawn branches for the given input + */ +/datum/map/proc/spawn_branches(var/decl/species/S) + if(!S) + return spawn_branches_.Copy() + . = LAZYACCESS(spawn_branches_by_species_, S) + if(!.) + . = list() + LAZYSET(spawn_branches_by_species_, S, .) + for(var/spawn_branch in spawn_branches_) + if(!global.using_map.is_species_branch_restricted(S, spawn_branches_[spawn_branch])) + . += spawn_branch + +/** + * Return all spawn ranks for the given input + */ +/datum/map/proc/spawn_ranks(var/branch_name, var/decl/species/S) + var/datum/mil_branch/branch = get_branch(branch_name) + return branch && branch.spawn_ranks(S) + +/** + * Return a true value if branch_name is a valid spawn branch key + */ +/datum/map/proc/is_spawn_branch(var/branch_name, var/decl/species/S) + return (branch_name in spawn_branches(S)) + +/** + * Return a true value if rank_name is a valid spawn rank in branch under branch_name + */ +/datum/map/proc/is_spawn_rank(var/branch_name, var/rank_name, var/decl/species/S) + var/datum/mil_branch/branch = get_branch(branch_name) + if(branch && (rank_name in branch.spawn_ranks(S))) + return TRUE + else + return FALSE + // The white, and blacklist are type specific, any subtypes (of both species and jobs) have to be added explicitly /datum/map/proc/is_species_branch_restricted(var/decl/species/S, var/datum/mil_branch/MB) if(!istype(S) || !istype(MB)) diff --git a/maps/~mapsystem/maps.dm b/maps/~mapsystem/maps.dm index ff76e866b038..c09d5bc24880 100644 --- a/maps/~mapsystem/maps.dm +++ b/maps/~mapsystem/maps.dm @@ -254,6 +254,8 @@ var/global/const/MAP_HAS_RANK = 2 //Rank system, also toggleable /datum/map/proc/setup_map() + populate_branches() + if(!length(loadout_categories)) loadout_categories = list() for(var/decl_type in decls_repository.get_decls_of_type(/decl/loadout_category)) From 90d27f2826b502dfbeb19dd24e7bf5dfc6b6d7ce Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 8 Oct 2025 22:15:48 -0400 Subject: [PATCH 34/36] Fix YML files losing line endings on checkout --- .editorconfig | 1 + .gitattributes | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 2643d9b63442..6b3864a466d1 100644 --- a/.editorconfig +++ b/.editorconfig @@ -19,6 +19,7 @@ indent_size = 4 [*.yml] indent_style = space indent_size = 2 +end_of_line = crlf [*.txt] end_of_line = crlf diff --git a/.gitattributes b/.gitattributes index e9d52dc929b5..d5d501e85607 100644 --- a/.gitattributes +++ b/.gitattributes @@ -13,4 +13,5 @@ html/changelog.html merge=union *.dm text eol=crlf *.dmm text eol=crlf *.txt text eol=crlf -*.md text eol=crlf \ No newline at end of file +*.md text eol=crlf +*.yml text eol=crlf \ No newline at end of file From b71a631151e2ada02b4177a059b6dbd3953bd216 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 9 Oct 2025 11:29:43 -0400 Subject: [PATCH 35/36] Fix null skillset runtimes on new_player --- code/datums/mind/mind.dm | 2 +- code/modules/client/preference_setup/occupation/occupation.dm | 2 +- code/modules/mob/skills/skillset.dm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/datums/mind/mind.dm b/code/datums/mind/mind.dm index 27a740428272..1ffcf5a68b56 100644 --- a/code/datums/mind/mind.dm +++ b/code/datums/mind/mind.dm @@ -225,7 +225,7 @@ assigned_job = job assigned_role = job.title role_alt_title = new_role - if(current) + if(current?.skillset) current.skillset.obtain_from_client(job, current.client) else if (href_list["amb_edit"]) diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm index 5613c8466500..feb41bc98058 100644 --- a/code/modules/client/preference_setup/occupation/occupation.dm +++ b/code/modules/client/preference_setup/occupation/occupation.dm @@ -185,7 +185,7 @@ skill_link = "View Skills" skill_link = "
  • " - if(!user.skillset.skills_transferable) + if(!user.skillset?.skills_transferable) skill_link = "" // Begin assembling the actual HTML. diff --git a/code/modules/mob/skills/skillset.dm b/code/modules/mob/skills/skillset.dm index 5e9928b3bf4a..eef151360637 100644 --- a/code/modules/mob/skills/skillset.dm +++ b/code/modules/mob/skills/skillset.dm @@ -38,7 +38,7 @@ var/global/list/all_skill_verbs . += SB.buffs[skill_path] /datum/skillset/proc/obtain_from_mob(mob/living/mob) - if(!istype(mob) || !skills_transferable || !mob.skillset.skills_transferable) + if(!istype(mob) || !skills_transferable || !mob.skillset?.skills_transferable) return skill_list = mob.skillset.skill_list default_value = mob.skillset.default_value From 6a326a4ad43ff13d60f6d0de51b588b32e23ebbc Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 9 Oct 2025 16:21:21 -0400 Subject: [PATCH 36/36] Incorporate Neerti's revised modpack readme --- mods/README.md | 56 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/mods/README.md b/mods/README.md index 3ad3e5f818b8..c6b7a62b11f8 100644 --- a/mods/README.md +++ b/mods/README.md @@ -1,45 +1,56 @@ # Modpacks ## What exactly are modpacks? - Modpacks are, effectively, self-contained (modular) feature bundles. They can contain new objects, new species, new UIs, overrides for existing code, and even more. If you want a feature to be optional on a per-map or per-server basis, while ensuring it's always checked for correctness in unit tests, it should be placed in a modpack. -## Wait, but I've heard that modular code is bad! +## Are modpacks the same as 'module' folders in other codebases? +No. Those were more or less just subdirectories that organized features into conceptual 'modules', but lacked any sort of defined structure or handling, and generally couldn't be selectively enabled or disabled. Nebula's modpacks are more rigorous, with scripts and tests for validation. Each modpack is tested as a unit (along with the base game) as well as in integration with other modpacks on the various included maps. -This is a common sentiment, but it's sort of a misconception. There's nothing *inherently* wrong with modular code; after all, it's just code that'd designed for easy extension and reusability, which is always desirable in a project like SS13. However, the way other codebases tend to handle modularity by just adding new DM files in a separate folder, directly included in the DME, creates issues. Some of the common objections are: +## Making a new modpack +All of Nebula's modpacks are kept inside of the `/mods` subdirectory. -### Load Order +Code inside of a modpack must depend on only itself and stock Nebula code, and not from other modpacks. Cross-modpack code goes elsewhere and is discussed further below. -With the typical way "modular" code is done, load order is difficult to manage and often results in folder names like `upstreamname`, `downstreamname`, `zzzz_servername`, etc., plus it requires editing the main DME. Modpacks have a defined, user-controlled load order, and cross-modpack compatibility is always handled after all modpacks are loaded. +Do NOT tick files inside of your modpack, as that'll add it to the base Nebula .dme file. Instead, you must add them to your modpack's .dme file. -### Organization and Navigation +### Modpack .dme +Each modpack contains its own .dme file, as the modpack is more or less a mini codebase contained within the larger stock Nebula codebase. The .dme needs to be at the base of your modpack directory. +By convention, the .dme should share the same name as the modpack itself, with a leading underscore in front. +The first line of the .dme should be an `#ifndef`, and then a define for your modpack, e.g. `#ifndef MODPACK_YOUR_MODPACK_NAME_HERE`. This needs to be unique across the codebase. +The second line should be a `#define`, and then the same thing as before, e.g. `#define MODPACK_YOUR_MODPACK_NAME_HERE`. +Below that, you should `#include` all of the paths of the files which are inside. The paths are relative to where the .dme is. +At the bottom, after all of the `#define`s, you must add `#endif`. Make sure to add `// BEGIN_INCLUDE` and `// END_INCLUDE` after the `#define` and before the `#endif`. -Similarly, that file-structure makes it very difficult to organize and navigate the codebase as a whole. The original modularization standards were fairly straightforward, in that the modular folder was treated as a straight-forward layer on top of the original codebase, with files being treated as though they're present in the original codebase structure. a trend that ended up being set by other servers going for modularization was adding subdirectories of "modules", with almost every unique piece of content being given it's own individual module folder. The problem with this is that modules don't really have any defined structure or handling, and tend to just amount to subdirectories and nothing more. With every piece of content having its own module, even if they just override or overwrite base-game definitions and nothing more, this leads to the codebase being incredibly hard to navigate even if you already know roughly where what you want to modify is. This even applies to the base game, because some code is separated by type (obj, datum, etc.) and others are separated into conceptual modules. +### Modpack Decl +Every modpack has a `/decl/modpack` subtype. -Nebula's modpacks are similar to modules in that they're separated by concept, but modpacks are more rigorous, with scripts and tests for validation. Each modpack is tested as a unit (along with the base game) as well as in integration with other modpacks on the various included maps. +By convention, the decl is defined at the base of the modpack directory, with the .dm file sharing the same name as the modpack, with a leading underscore, the same as the .dme file. -### Proc Overrides +The decl also lets players to see which modpacks a server is currently running, and holds some miscellaneous information to use for things such as dreams and the round-end credits screen. -Modular code relies heavily on overrides and even side-overrides (overrides defined after, but on the same type as, an existing proc override or definition), which can obfuscate control flow and lead to code breaking when assumptions made about the calling proc change. This is a valid concern! In a lot of cases, though, it's avoidable by making modular behaviour use explicit interfaces intended for change in modpacks, like specifying datum (often decl) handlers that receive one override each. `/decl/human_examination` is a good example of this. +You can have code run during server initialization, or the round starting, by overriding `pre_initialize()`, `initialize()`, `post_initialize()`, and `on_roundstart()` on your modpack's decl. -### Merge Conflicts +If your modpack has NanoUI templates, you must set the `nanoui_directory` variable to point to the path of the folder where the templates are, or NanoUI won't be able to find them in-game. -The issue with "modularity" as done elsewhere is that it just masks conflicts; upstream files are kept intact, but they might be unincluded or the methods they define/call might be completely replaced later on. This swaps out annoying but easily-resolvable merge conflicts for the far-worse issue of silent breakage. +### Load Order +Modpacks have a defined, user-controlled load order, and cross-modpack compatibility is always handled after all modpacks are loaded. -### Upstream Conflicts +### Enabling Your Modpack +Modpacks are enabled on a per-map basis. To activate a modpack, you `#include` the modpack's .dme in a map's .dme file. -More broadly, modular code on a downstream with an upstream that does frequent refactors and rewrites is inevitably going to break when the upstream codebase does anything. Names change, so do assumptions, and even design directions might diverge so far that reconciling them will be hard or even impossible. There's not really getting around that, but we can at least mitigate it by designing stable interfaces and documenting changes. When upstream code is written with modularity in mind, downstreams have a much easier time adding content. +### Overriding Stock Code +TODO: Actually write this section. It's distinct from the "How do I write upstream/core code with extension via modpacks in mind?" part because it's the *opposite,* this section is about overriding core code while the other section is about writing core code to be extended. Maybe do a basic explanation of side-overrides and associated footguns here. -### Implicit Dependencies +### Cross-modpack interactions +Sometimes, a modpack that's enabled might need to do something in response to another modpack also being enabled. Compatibility patches allow for this to happen without the modpacks in question requiring a hard dependency on each other. -The idea of modular code as independent falls apart when code modules begin to require each other to function, without explicitly noting that dependency. Worse yet, sometimes there are non-modular edits to base-game code that require a particular piece of modular code to be included. Since Nebula runs unit tests on an example map with no modpacks and no map-specific code, the core game will always function without any modpacks included. Similarly, modpacks are tested one-at-a-time as well as all together, to ensure there aren't any implicit dependencies. If one modpack requires another to function, there's three methods to resolve this. First, you could have one modpack include the other, making the dependency explicit. Second, you could merge the modpacks so they aren't separate at all. Third, you could use a compatibility patch to gate the content that requires both to be loaded. +An example of such an interaction is that the Supermatter content modpack can give the SM monitoring program to engineering jobs that exist inside the Standard Jobs modpack. Another example is allowing content in the Psionics content modpack to interact with content in the Cult gamemode modpack. -## Okay, but how do I make a modpack? +Cross-modpack code is kept inside of `/mods/~compatibility`. There is another README inside which has more information. -TODO: Write this section. Explain things like creating a DME, where to include the DME, etc. Also explain some common organizational conventions like `foo_overrides.dm` files and `overrides` folders to better organize overrides of base-game procs and functionality. +Some modpacks extend other modpacks and make no sense to include on their own, in which case it's generally okay to make the extension modpack have a hard dependency on the original one by `#include`ing the original modpack's DME in the new one. ### How do I modpack... - - A subsystem? - Check the psionics modpack for an example. - Something small? @@ -47,10 +58,11 @@ TODO: Write this section. Explain things like creating a DME, where to include t - NanoUI templates? - Check the inertial dampener or supermatter modpacks as examples. (Don't forget to set the nanoui_directory variable on the modpack decl!) -## How do I write upstream/core code with extension via modpacks in mind? +## Using modpacks as a downstream server +Modular code on a downstream with an upstream that does frequent refactors and rewrites is inevitably going to break when the upstream codebase does anything. Names change, so do assumptions, and even design directions might diverge so far that reconciling them will be hard or even impossible. There's not really getting around that, but we can at least mitigate it by designing stable interfaces and documenting changes. When upstream code is written with modularity in mind, downstreams have a much easier time adding content. -TODO: Write this section. Give examples like `/decl/atmos_grief_fix_step`, `/decl/human_examination`, the cocktails system, etc. Iterating over subtypes of a base type makes it easy for modpacks to add new code. Also maybe address some footguns like trying to make something modular before trying to make it actually work? Could also discuss the open-closed principle I guess, e.g. write code that gets *extended* rather than *modified* (so avoiding side-overrides, etc.). +## How do I write upstream/core code with extension via modpacks in mind? +TODO: Actually write this section. Give examples like `/decl/atmos_grief_fix_step`, `/decl/human_examination`, the cocktails system, etc. Iterating over subtypes of a base type makes it easy for modpacks to add new code. Also maybe address some footguns like trying to make something modular before trying to make it actually work? Could also discuss the open-closed principle I guess, e.g. write code that gets *extended* rather than *modified* (so avoiding side-overrides where possible, etc.). # Contribution - Please contribute to this README/guide. It's currently unfinished and doesn't cover a lot of important things. Thanks. \ No newline at end of file
    + + + + +
    +
    Nebula13
    +
    A Space Station 13 Project
    + +

    + Code licensed under AGPLv3. Content licensed under CC BY-SA 3.0.

    +
    + +
    Nebula13 Credit List + + + + +
    + Contributor list: -Click Here-
    + Special thanks to: the developers of Baystation 12, ScavStation, /tg/station, /vg/station, GoonStation, the original Space Station 13, and BYOND.
    +

    Have a bug to report?
    Visit our Issue Tracker.
    +
    + + +
    diff --git a/interface/skin.dmf b/interface/skin.dmf index 3778ffcd7c19..c02a82497db3 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -1,435 +1,435 @@ -macro "default" - elem ".winset :map.right-click=false" - name = "SHIFT+Shift" - elem "Shift" - name = "SHIFT" - command = ".winset :map.right-click=false" - elem "ShiftUp" - name = "SHIFT+UP" - command = ".winset :map.right-click=true" - -menu "menu" - elem - name = "&File" - command = "" - saved-params = "is-checked" - elem - name = "&Save screenshot\tF2" - command = ".auto" - category = "&File" - saved-params = "is-checked" - elem - name = "&Save screenshot as..." - command = ".screenshot" - category = "&File" - saved-params = "is-checked" - elem - name = "" - command = "" - category = "&File" - saved-params = "is-checked" - elem - name = "&Reconnect" - command = ".reconnect" - category = "&File" - saved-params = "is-checked" - elem - name = "&Check ping" - command = ".ping" - category = "&File" - saved-params = "is-checked" - elem - name = "&Quit" - command = ".quit" - category = "&File" - saved-params = "is-checked" - elem - name = "&Size" - command = "" - saved-params = "is-checked" - elem "icon128" - name = "&128x128" - command = "SetWindowIconSize 128" - category = "&Size" - can-check = true - group = "size" - saved-params = "is-checked" - elem "icon96" - name = "&96x96" - command = "SetWindowIconSize 96" - category = "&Size" - can-check = true - group = "size" - saved-params = "is-checked" - elem "icon64" - name = "&64x64" - command = "SetWindowIconSize 64" - category = "&Size" - is-checked = true - can-check = true - group = "size" - saved-params = "is-checked" - elem "icon48" - name = "&48x48" - command = "SetWindowIconSize 48" - category = "&Size" - can-check = true - group = "size" - saved-params = "is-checked" - elem "icon32" - name = "&32x32" - command = "SetWindowIconSize 32" - category = "&Size" - can-check = true - group = "size" - saved-params = "is-checked" - elem - name = "&Scaling" - command = "" - saved-params = "is-checked" - elem "ZM" - name = "&Smooth Scaling" - command = ".winset \"zoommode.is-checked=true?map.zoom-mode=normal:map.zoom-mode=distort\"" - category = "&Scaling" - is-checked = true - can-check = true - group = "scale" - saved-params = "is-checked" - elem "NN" - name = "&Nearest Neighbor" - command = ".winset \"mapwindow.map.zoom-mode=distort\"" - category = "&Scaling" - can-check = true - group = "scale" - saved-params = "is-checked" - elem "PS" - name = "&Point Sampling" - command = ".winset \"mapwindow.map.zoom-mode=normal\"" - category = "&Scaling" - can-check = true - group = "scale" - saved-params = "is-checked" - elem "BL" - name = "&Bilinear" - command = ".winset \"mapwindow.map.zoom-mode=blur\"" - category = "&Scaling" - can-check = true - group = "scale" - saved-params = "is-checked" - elem - name = "&Help" - command = "" - saved-params = "is-checked" - elem - name = "&Admin help\tF1" - command = "adminhelp" - category = "&Help" - saved-params = "is-checked" - -window "mainwindow" - elem "mainwindow" - type = MAIN - pos = 281,0 - size = 640x440 - anchor1 = none - anchor2 = none - is-default = true - background-color = #000000 - saved-params = "pos;size;is-minimized;is-maximized" - on-size = "OnResize" - is-maximized = true - icon = 'icons\\ss13_64.png' - macro = "default" - menu = "menu" - elem "split" - type = CHILD - pos = 3,0 - size = 640x440 - anchor1 = 0,0 - anchor2 = 100,100 - saved-params = "splitter" - left = "mapwindow" - right = "rpane" - is-vert = true - elem "asset_cache_browser" - type = BROWSER - pos = 0,0 - size = 200x200 - anchor1 = none - anchor2 = none - is-visible = false - saved-params = "" - elem "tooltip" - type = BROWSER - pos = 0,0 - size = 999x999 - anchor1 = none - anchor2 = none - background-color = none - is-visible = false - saved-params = "" - -window "mapwindow" - elem "mapwindow" - type = MAIN - pos = 281,0 - size = 640x480 - anchor1 = none - anchor2 = none - saved-params = "pos;size;is-minimized;is-maximized" - titlebar = false - statusbar = false - can-close = false - can-minimize = false - can-resize = false - is-pane = true - elem "map" - type = MAP - pos = 0,0 - size = 640x480 - anchor1 = 0,0 - anchor2 = 100,100 - font-family = "Arial Rounded MT Bold,Arial Black,Arial,sans-serif" - font-size = 7 - is-default = true - saved-params = "icon-size;zoom-mode" - elem "lobbybrowser" - type = BROWSER - pos = 0,0 - size = 640x480 - anchor1 = 0,0 - anchor2 = 100,100 - is-visible = false - is-disabled = true - saved-params = "" - elem "status_bar" - type = LABEL - pos = 0,464 - size = 280x16 - anchor1 = 0,100 - anchor2 = none - text-color = #ffffff - background-color = #222222 - is-visible = false - border = line - saved-params = "" - text = "" - align = left - -window "outputwindow" - elem "outputwindow" - type = MAIN - pos = 281,-30 - size = 640x480 - anchor1 = none - anchor2 = none - background-color = none - saved-params = "pos;size;is-minimized;is-maximized" - titlebar = false - statusbar = false - can-close = false - can-minimize = false - can-resize = false - is-pane = true - outer-size = 654x494 - elem "output" - type = OUTPUT - pos = 0,0 - size = 640x456 - anchor1 = 0,0 - anchor2 = 100,100 - is-default = true - saved-params = "max-lines" - style = ".system {color:#ff0000;}" - max-lines = 0 - elem "saybutton" - type = BUTTON - pos = 600,460 - size = 40x20 - anchor1 = 100,100 - anchor2 = none - background-color = none - saved-params = "is-checked" - text = "Chat" - command = ".winset \"saybutton.is-checked=true?input.command=\"!say \\\"\" macrobutton.is-checked=false:input.command=\"" - button-type = pushbox - elem "input" - type = INPUT - pos = 1,460 - size = 600x20 - anchor1 = 0,100 - anchor2 = 100,100 - background-color = #d3b5b5 - is-default = true - border = sunken - saved-params = "command" - -window "rpane" - elem "rpane" - type = MAIN - pos = 281,0 - size = 640x480 - anchor1 = none - anchor2 = none - saved-params = "pos;size;is-minimized;is-maximized" - is-pane = true - elem "rpanewindow" - type = CHILD - pos = 0,30 - size = 0x0 - anchor1 = 0,0 - anchor2 = 100,100 - saved-params = "splitter" - left = "infowindow" - right = "outputwindow" - is-vert = false - elem "github" - type = BUTTON - pos = 520,0 - size = 60x15 - anchor1 = none - anchor2 = none - saved-params = "is-checked" - text = "GitHub" - command = "GitHub" - elem "BugReport" - type = BUTTON - pos = 580,0 - size = 60x15 - anchor1 = none - anchor2 = none - saved-params = "is-checked" - text = "Bug Report" - command = "Bug-Report" - elem "rulesb" - type = BUTTON - pos = 205,0 - size = 60x15 - anchor1 = none - anchor2 = none - saved-params = "is-checked" - text = "Rules" - command = "rules" - group = "rpanemode" - elem "changelog" - type = BUTTON - pos = 460,0 - size = 60x15 - anchor1 = none - anchor2 = none - saved-params = "is-checked" - text = "Changelog" - command = "Changelog" - group = "rpanemode" - elem "Lore" - type = BUTTON - pos = 265,0 - size = 60x15 - anchor1 = none - anchor2 = none - saved-params = "is-checked" - text = "Lore" - command = "Lore" - group = "rpanemode" - elem "forumb" - type = BUTTON - pos = 385,0 - size = 60x15 - anchor1 = none - anchor2 = none - saved-params = "is-checked" - text = "Forum" - command = "forum" - group = "rpanemode" - elem "wikib" - type = BUTTON - pos = 325,0 - size = 60x15 - anchor1 = none - anchor2 = none - saved-params = "is-checked" - text = "Wiki" - command = "wiki" - group = "rpanemode" - elem "textb" - type = BUTTON - pos = 0,0 - size = 60x15 - anchor1 = none - anchor2 = none - saved-params = "is-checked" - text = "Text" - command = ".winset \"rpanewindow.left=;\"" - is-checked = true - group = "rpanemode" - button-type = pushbox - elem "infob" - type = BUTTON - pos = 60,0 - size = 60x15 - anchor1 = none - anchor2 = none - saved-params = "is-checked" - text = "Info" - command = ".winset \"rpanewindow.left=infowindow\"" - group = "rpanemode" - button-type = pushbox - elem "button_codex" - type = BUTTON - pos = 133,0 - size = 60x15 - anchor1 = none - anchor2 = none - saved-params = "is-checked" - text = "Codex" - command = "Codex" - group = "rpanemode" - -window "preferences_window" - elem "preferences_window" - type = MAIN - pos = 281,0 - size = 1000x800 - anchor1 = none - anchor2 = none - is-visible = false - saved-params = "pos;size;is-minimized;is-maximized" - statusbar = false - elem "preferences_browser" - type = BROWSER - pos = 0,0 - size = 800x800 - anchor1 = 0,0 - anchor2 = 80,100 - saved-params = "" - elem "character_preview_map" - type = MAP - pos = 800,0 - size = 200x800 - anchor1 = 80,0 - anchor2 = 100,100 - right-click = true - saved-params = "zoom;letterbox;zoom-mode" - -window "infowindow" - elem "infowindow" - type = MAIN - pos = 281,0 - size = 640x480 - anchor1 = none - anchor2 = none - saved-params = "pos;size;is-minimized;is-maximized" - title = "Info" - is-pane = true - elem "info" - type = INFO - pos = 0,0 - size = 638x477 - anchor1 = 0,0 - anchor2 = 100,100 - is-default = true - saved-params = "" - highlight-color = #00aa00 - on-show = ".winset\"rpane.infob.is-checked=true\"" - on-hide = ".winset\"rpane.infob.is-checked=false\"" - +macro "default" + elem ".winset :map.right-click=false" + name = "SHIFT+Shift" + elem "Shift" + name = "SHIFT" + command = ".winset :map.right-click=false" + elem "ShiftUp" + name = "SHIFT+UP" + command = ".winset :map.right-click=true" + +menu "menu" + elem + name = "&File" + command = "" + saved-params = "is-checked" + elem + name = "&Save screenshot\tF2" + command = ".auto" + category = "&File" + saved-params = "is-checked" + elem + name = "&Save screenshot as..." + command = ".screenshot" + category = "&File" + saved-params = "is-checked" + elem + name = "" + command = "" + category = "&File" + saved-params = "is-checked" + elem + name = "&Reconnect" + command = ".reconnect" + category = "&File" + saved-params = "is-checked" + elem + name = "&Check ping" + command = ".ping" + category = "&File" + saved-params = "is-checked" + elem + name = "&Quit" + command = ".quit" + category = "&File" + saved-params = "is-checked" + elem + name = "&Size" + command = "" + saved-params = "is-checked" + elem "icon128" + name = "&128x128" + command = "SetWindowIconSize 128" + category = "&Size" + can-check = true + group = "size" + saved-params = "is-checked" + elem "icon96" + name = "&96x96" + command = "SetWindowIconSize 96" + category = "&Size" + can-check = true + group = "size" + saved-params = "is-checked" + elem "icon64" + name = "&64x64" + command = "SetWindowIconSize 64" + category = "&Size" + is-checked = true + can-check = true + group = "size" + saved-params = "is-checked" + elem "icon48" + name = "&48x48" + command = "SetWindowIconSize 48" + category = "&Size" + can-check = true + group = "size" + saved-params = "is-checked" + elem "icon32" + name = "&32x32" + command = "SetWindowIconSize 32" + category = "&Size" + can-check = true + group = "size" + saved-params = "is-checked" + elem + name = "&Scaling" + command = "" + saved-params = "is-checked" + elem "ZM" + name = "&Smooth Scaling" + command = ".winset \"zoommode.is-checked=true?map.zoom-mode=normal:map.zoom-mode=distort\"" + category = "&Scaling" + is-checked = true + can-check = true + group = "scale" + saved-params = "is-checked" + elem "NN" + name = "&Nearest Neighbor" + command = ".winset \"mapwindow.map.zoom-mode=distort\"" + category = "&Scaling" + can-check = true + group = "scale" + saved-params = "is-checked" + elem "PS" + name = "&Point Sampling" + command = ".winset \"mapwindow.map.zoom-mode=normal\"" + category = "&Scaling" + can-check = true + group = "scale" + saved-params = "is-checked" + elem "BL" + name = "&Bilinear" + command = ".winset \"mapwindow.map.zoom-mode=blur\"" + category = "&Scaling" + can-check = true + group = "scale" + saved-params = "is-checked" + elem + name = "&Help" + command = "" + saved-params = "is-checked" + elem + name = "&Admin help\tF1" + command = "adminhelp" + category = "&Help" + saved-params = "is-checked" + +window "mainwindow" + elem "mainwindow" + type = MAIN + pos = 281,0 + size = 640x440 + anchor1 = none + anchor2 = none + is-default = true + background-color = #000000 + saved-params = "pos;size;is-minimized;is-maximized" + on-size = "OnResize" + is-maximized = true + icon = 'icons\\ss13_64.png' + macro = "default" + menu = "menu" + elem "split" + type = CHILD + pos = 3,0 + size = 640x440 + anchor1 = 0,0 + anchor2 = 100,100 + saved-params = "splitter" + left = "mapwindow" + right = "rpane" + is-vert = true + elem "asset_cache_browser" + type = BROWSER + pos = 0,0 + size = 200x200 + anchor1 = none + anchor2 = none + is-visible = false + saved-params = "" + elem "tooltip" + type = BROWSER + pos = 0,0 + size = 999x999 + anchor1 = none + anchor2 = none + background-color = none + is-visible = false + saved-params = "" + +window "mapwindow" + elem "mapwindow" + type = MAIN + pos = 281,0 + size = 640x480 + anchor1 = none + anchor2 = none + saved-params = "pos;size;is-minimized;is-maximized" + titlebar = false + statusbar = false + can-close = false + can-minimize = false + can-resize = false + is-pane = true + elem "map" + type = MAP + pos = 0,0 + size = 640x480 + anchor1 = 0,0 + anchor2 = 100,100 + font-family = "Arial Rounded MT Bold,Arial Black,Arial,sans-serif" + font-size = 7 + is-default = true + saved-params = "icon-size;zoom-mode" + elem "lobbybrowser" + type = BROWSER + pos = 0,0 + size = 640x480 + anchor1 = 0,0 + anchor2 = 100,100 + is-visible = false + is-disabled = true + saved-params = "" + elem "status_bar" + type = LABEL + pos = 0,464 + size = 280x16 + anchor1 = 0,100 + anchor2 = none + text-color = #ffffff + background-color = #222222 + is-visible = false + border = line + saved-params = "" + text = "" + align = left + +window "outputwindow" + elem "outputwindow" + type = MAIN + pos = 281,-30 + size = 640x480 + anchor1 = none + anchor2 = none + background-color = none + saved-params = "pos;size;is-minimized;is-maximized" + titlebar = false + statusbar = false + can-close = false + can-minimize = false + can-resize = false + is-pane = true + outer-size = 654x494 + elem "output" + type = OUTPUT + pos = 0,0 + size = 640x456 + anchor1 = 0,0 + anchor2 = 100,100 + is-default = true + saved-params = "max-lines" + style = ".system {color:#ff0000;}" + max-lines = 0 + elem "saybutton" + type = BUTTON + pos = 600,460 + size = 40x20 + anchor1 = 100,100 + anchor2 = none + background-color = none + saved-params = "is-checked" + text = "Chat" + command = ".winset \"saybutton.is-checked=true?input.command=\"!say \\\"\" macrobutton.is-checked=false:input.command=\"" + button-type = pushbox + elem "input" + type = INPUT + pos = 1,460 + size = 600x20 + anchor1 = 0,100 + anchor2 = 100,100 + background-color = #d3b5b5 + is-default = true + border = sunken + saved-params = "command" + +window "rpane" + elem "rpane" + type = MAIN + pos = 281,0 + size = 640x480 + anchor1 = none + anchor2 = none + saved-params = "pos;size;is-minimized;is-maximized" + is-pane = true + elem "rpanewindow" + type = CHILD + pos = 0,30 + size = 0x0 + anchor1 = 0,0 + anchor2 = 100,100 + saved-params = "splitter" + left = "infowindow" + right = "outputwindow" + is-vert = false + elem "github" + type = BUTTON + pos = 520,0 + size = 60x15 + anchor1 = none + anchor2 = none + saved-params = "is-checked" + text = "GitHub" + command = "GitHub" + elem "BugReport" + type = BUTTON + pos = 580,0 + size = 60x15 + anchor1 = none + anchor2 = none + saved-params = "is-checked" + text = "Bug Report" + command = "Bug-Report" + elem "rulesb" + type = BUTTON + pos = 205,0 + size = 60x15 + anchor1 = none + anchor2 = none + saved-params = "is-checked" + text = "Rules" + command = "rules" + group = "rpanemode" + elem "changelog" + type = BUTTON + pos = 460,0 + size = 60x15 + anchor1 = none + anchor2 = none + saved-params = "is-checked" + text = "Changelog" + command = "Changelog" + group = "rpanemode" + elem "Lore" + type = BUTTON + pos = 265,0 + size = 60x15 + anchor1 = none + anchor2 = none + saved-params = "is-checked" + text = "Lore" + command = "Lore" + group = "rpanemode" + elem "forumb" + type = BUTTON + pos = 385,0 + size = 60x15 + anchor1 = none + anchor2 = none + saved-params = "is-checked" + text = "Forum" + command = "forum" + group = "rpanemode" + elem "wikib" + type = BUTTON + pos = 325,0 + size = 60x15 + anchor1 = none + anchor2 = none + saved-params = "is-checked" + text = "Wiki" + command = "wiki" + group = "rpanemode" + elem "textb" + type = BUTTON + pos = 0,0 + size = 60x15 + anchor1 = none + anchor2 = none + saved-params = "is-checked" + text = "Text" + command = ".winset \"rpanewindow.left=;\"" + is-checked = true + group = "rpanemode" + button-type = pushbox + elem "infob" + type = BUTTON + pos = 60,0 + size = 60x15 + anchor1 = none + anchor2 = none + saved-params = "is-checked" + text = "Info" + command = ".winset \"rpanewindow.left=infowindow\"" + group = "rpanemode" + button-type = pushbox + elem "button_codex" + type = BUTTON + pos = 133,0 + size = 60x15 + anchor1 = none + anchor2 = none + saved-params = "is-checked" + text = "Codex" + command = "Codex" + group = "rpanemode" + +window "preferences_window" + elem "preferences_window" + type = MAIN + pos = 281,0 + size = 1000x800 + anchor1 = none + anchor2 = none + is-visible = false + saved-params = "pos;size;is-minimized;is-maximized" + statusbar = false + elem "preferences_browser" + type = BROWSER + pos = 0,0 + size = 800x800 + anchor1 = 0,0 + anchor2 = 80,100 + saved-params = "" + elem "character_preview_map" + type = MAP + pos = 800,0 + size = 200x800 + anchor1 = 80,0 + anchor2 = 100,100 + right-click = true + saved-params = "zoom;letterbox;zoom-mode" + +window "infowindow" + elem "infowindow" + type = MAIN + pos = 281,0 + size = 640x480 + anchor1 = none + anchor2 = none + saved-params = "pos;size;is-minimized;is-maximized" + title = "Info" + is-pane = true + elem "info" + type = INFO + pos = 0,0 + size = 638x477 + anchor1 = 0,0 + anchor2 = 100,100 + is-default = true + saved-params = "" + highlight-color = #00aa00 + on-show = ".winset\"rpane.infob.is-checked=true\"" + on-hide = ".winset\"rpane.infob.is-checked=false\"" + diff --git a/mods/gamemodes/cult/_cult.dme b/mods/gamemodes/cult/_cult.dme index 02138255d74c..88b4aa4b8af3 100644 --- a/mods/gamemodes/cult/_cult.dme +++ b/mods/gamemodes/cult/_cult.dme @@ -25,7 +25,7 @@ #include "abilities\construct.dm" #include "abilities\harvest.dm" #include "abilities\shade.dm" -#include "cultify\de-cultify.dm" +#include "cultify\de-cultify.dm" #include "cultify\defile.dm" #include "cultify\mob.dm" #include "cultify\turf.dm" @@ -34,11 +34,11 @@ #include "mobs\constructs\constructs.dm" #include "mobs\constructs\soulstone.dm" // END_INCLUDE -#endif -// BEGIN_INTERNALS -// END_INTERNALS -// BEGIN_FILE_DIR -#define FILE_DIR . -// END_FILE_DIR -// BEGIN_PREFERENCES -// END_PREFERENCES +#endif +// BEGIN_INTERNALS +// END_INTERNALS +// BEGIN_FILE_DIR +#define FILE_DIR . +// END_FILE_DIR +// BEGIN_PREFERENCES +// END_PREFERENCES diff --git a/nano/templates/agent_id_card.tmpl b/nano/templates/agent_id_card.tmpl index 7a41dcdf1b7f..a802efbc82dd 100644 --- a/nano/templates/agent_id_card.tmpl +++ b/nano/templates/agent_id_card.tmpl @@ -1,21 +1,21 @@ - -{{:helper.syndicateMode()}} -

    Available Entries

    - -{{for data.entries}} - - - -{{/for}} -
    {{:helper.link('', 'gear', {'set' : value.name})}}{{:value.name}}{{:value.value}}
    - - - - - - - -
    Electronic warfare:{{:helper.link('Enabled', null, {'electronic_warfare' : 1}, data.electronic_warfare ? 'selected' : null)}}{{:helper.link('Disabled',null, {'electronic_warfare' : 0}, data.electronic_warfare ? null : 'selected')}}
    + +{{:helper.syndicateMode()}} +

    Available Entries

    + +{{for data.entries}} + + + +{{/for}} +
    {{:helper.link('', 'gear', {'set' : value.name})}}{{:value.name}}{{:value.value}}
    + + + + + + + +
    Electronic warfare:{{:helper.link('Enabled', null, {'electronic_warfare' : 1}, data.electronic_warfare ? 'selected' : null)}}{{:helper.link('Disabled',null, {'electronic_warfare' : 0}, data.electronic_warfare ? null : 'selected')}}
    diff --git a/nano/templates/air_alarm.tmpl b/nano/templates/air_alarm.tmpl index 8d604e58e348..8e9f9a52f364 100644 --- a/nano/templates/air_alarm.tmpl +++ b/nano/templates/air_alarm.tmpl @@ -1,219 +1,219 @@ - -

    Air Status

    -{{if data.has_environment}} - {{for data.environment}} - {{:value.name}}: - {{if value.danger_level == 2}} - - {{else value.danger_level == 1}} - - {{else}} - - {{/if}} - {{:helper.fixed(value.value, 1)}} - {{:value.unit}}
    - {{/for}} - Local Status: {{if data.total_danger == 2}} - DANGER: Internals Required - {{else data.total_danger == 1}} - Caution - {{else}} - Optimal - {{/if}} -
    - Area Status: {{if data.atmos_alarm}}Atmosphere alert in area{{else data.fire_alarm}}Fire alarm in area{{else}}No alerts{{/if}} -{{else}} - Warning: Cannot obtain air sample for analysis. -{{/if}} -
    - - - - - - - - - - - - - -
    -
    -

    Remote Control

    -
    -

    Thermostat

    -
    -
    -
    -
    - {{:helper.link('Off', null, { 'rcon' : 1}, !data.rcon_access ? (data.rcon == 1 ? 'yellowButton' : 'disabled') : null, data.rcon == 1 ? 'selected' : null)}} - {{:helper.link('Auto', null, { 'rcon' : 2}, !data.rcon_access ? (data.rcon == 2 ? 'yellowButton' : 'disabled') : null, data.rcon == 2 ? 'selected' : null)}} - {{:helper.link('On', null, { 'rcon' : 3}, !data.rcon_access ? (data.rcon == 3 ? 'yellowButton' : 'disabled') : null, data.rcon == 3 ? 'selected' : null)}} -
    -
    -
    - {{:helper.link(data.target_temperature, null, { 'temperature' : 1})}} -
    -
    -{{if (data.locked && !data.remote_connection) || (data.remote_connection && ! data.remote_access)}} - {{if data.remote_connection}} - (Current remote control settings and alarm status restricts access.) - {{else}} - (Swipe ID card to unlock interface.) - {{/if}} -{{else}} - {{if data.screen != 1}} -
    {{:helper.link('Main Menu', null, { 'screen' : 1})}}
    - {{/if}} - {{if data.screen == 1}} -
    - {{if data.atmos_alarm}} - {{:helper.link('Reset - Area Atmospheric Alarm', null, { 'atmos_reset' : 1})}} - {{else}} - {{:helper.link('Activate - Area Atmospheric Alarm', null, { 'atmos_alarm' : 1})}} - {{/if}} -
    -
    -
    - {{:helper.link('Scrubbers Control', null, { 'screen' : 3})}} -
    -
    - {{:helper.link('Vents Control', null, { 'screen' : 2})}} -
    -
    - {{:helper.link('Set Environmental Mode', null, { 'screen' : 4})}} -
    -
    - {{:helper.link('Sensor Settings', null, { 'screen' : 5})}} -
    -
    - {{if data.mode==3}} - {{:helper.link('PANIC SIPHON ACTIVE - Turn siphoning off', null, { 'mode' : 1}, null, 'redButton')}} - {{else}} - {{:helper.link('ACTIVATE PANIC SIPHON IN AREA', null, { 'mode' : 3}, null, 'yellowButton')}} - {{/if}} - {{else data.screen == 2}} - {{for data.vents}} -
    - {{:value.long_name}}
    -
    -
    - Operating: -
    -
    - {{:helper.link(value.power ? 'On' : 'Off', null, { 'id_tag' : value.id_tag, 'command' : 'set_power', 'val' : value.power ? 0 : 1}, null, value.power ? null : 'redButton')}} -
    -
    -
    -
    - Operation Mode: -
    -
    - {{:value.direction == "siphon" ? 'Siphoning' : 'Pressurizing'}} -
    -
    -
    -
    - Pressure Checks: -
    -
    - {{:helper.link('External', null, { 'id_tag' : value.id_tag, 'command' : 'set_checks', 'val' : value.checks^1}, null, value.checks&1 ? 'selected' : null)}} - {{:helper.link('Internal', null, { 'id_tag' : value.id_tag, 'command' : 'set_checks', 'val' : value.checks^2}, null, value.checks&2 ? 'selected' : null)}} -
    -
    -
    -
    - External Pressure Bound: -
    -
    - {{:helper.link(helper.fixed(value.external,2), null, { 'id_tag' : value.id_tag, 'command' : 'set_external_pressure'})}} - {{:helper.link('Reset', null, { 'id_tag' : value.id_tag, 'command' : 'reset_external_pressure'})}} -
    -
    -
    - {{empty}} - No vents connected. - {{/for}} - {{else data.screen == 3}} - {{for data.scrubbers}} -
    - {{:value.long_name}}
    -
    -
    - Operating: -
    -
    - {{:helper.link(value.power ? 'On' : 'Off', null, { 'id_tag' : value.id_tag, 'command' : 'set_power', 'val' : value.power ? 0 : 1}, null, value.power ? null : 'redButton')}} -
    -
    -
    -
    - Operation Mode: -
    -
    - {{:helper.link('Scrub', null, { 'id_tag' : value.id_tag, 'command' : 'set_scrubbing', 'scrub_mode' : 'scrub'}, null, value.scrubbing == 'scrub' ? 'selected' : null)}} - {{:helper.link('Exchange', null, { 'id_tag' : value.id_tag, 'command' : 'set_scrubbing', 'scrub_mode' : 'exchange'}, null, value.scrubbing == 'exchange' ? 'selected' : null)}} - {{:helper.link('Siphon', null, { 'id_tag' : value.id_tag, 'command' : 'set_scrubbing', 'scrub_mode' : 'siphon'}, null, value.scrubbing == 'siphon' ? 'redButton' : null)}} -
    -
    -
    -
    - Filters: -
    -
    - {{for value.filters :filterValue:filterIndex}} - {{:helper.link(filterValue.name, null, { 'id_tag' : value.id_tag, 'command' : 'set_scrub_gas', 'gas_id' : filterValue.id, 'val' : filterValue.val ? 0 : 1}, null, filterValue.val ? 'selected' : null)}} - {{/for}} -
    -
    -
    - {{empty}} - No scrubbers connected. - {{/for}} - {{else data.screen == 4}} -

    Environmental Modes

    - {{for data.modes}} -
    - {{:helper.link(value.name, null, { 'mode' : value.mode }, null, value.selected ? (value.danger ? 'redButton' : 'selected') : null)}} -
    - {{/for}} - {{else data.screen == 5}} -

    Alarm Threshold

    - Partial pressure for gases. - - - - - {{for data.thresholds}} - - - {{for value.settings :settingsValue:settingsIndex}} - - {{/for}} - - {{/for}} -
    min2min1max1max2
    {{:value.name}} - {{:helper.link(settingsValue.selected >= 0 ? helper.fixed(settingsValue.selected, 2) : "Off", null, { 'command' : 'set_threshold', 'env' : settingsValue.env, 'var' : settingsValue.val })}} -
    - {{/if}} -{{/if}} + +

    Air Status

    +{{if data.has_environment}} + {{for data.environment}} + {{:value.name}}: + {{if value.danger_level == 2}} + + {{else value.danger_level == 1}} + + {{else}} + + {{/if}} + {{:helper.fixed(value.value, 1)}} + {{:value.unit}}
    + {{/for}} + Local Status: {{if data.total_danger == 2}} + DANGER: Internals Required + {{else data.total_danger == 1}} + Caution + {{else}} + Optimal + {{/if}} +
    + Area Status: {{if data.atmos_alarm}}Atmosphere alert in area{{else data.fire_alarm}}Fire alarm in area{{else}}No alerts{{/if}} +{{else}} + Warning: Cannot obtain air sample for analysis. +{{/if}} +
    +
    + + + + + + + + + + + + +
    +
    +

    Remote Control

    +
    +

    Thermostat

    +
    +
    +
    +
    + {{:helper.link('Off', null, { 'rcon' : 1}, !data.rcon_access ? (data.rcon == 1 ? 'yellowButton' : 'disabled') : null, data.rcon == 1 ? 'selected' : null)}} + {{:helper.link('Auto', null, { 'rcon' : 2}, !data.rcon_access ? (data.rcon == 2 ? 'yellowButton' : 'disabled') : null, data.rcon == 2 ? 'selected' : null)}} + {{:helper.link('On', null, { 'rcon' : 3}, !data.rcon_access ? (data.rcon == 3 ? 'yellowButton' : 'disabled') : null, data.rcon == 3 ? 'selected' : null)}} +
    +
    +
    + {{:helper.link(data.target_temperature, null, { 'temperature' : 1})}} +
    +
    +{{if (data.locked && !data.remote_connection) || (data.remote_connection && ! data.remote_access)}} + {{if data.remote_connection}} + (Current remote control settings and alarm status restricts access.) + {{else}} + (Swipe ID card to unlock interface.) + {{/if}} +{{else}} + {{if data.screen != 1}} +
    {{:helper.link('Main Menu', null, { 'screen' : 1})}}
    + {{/if}} + {{if data.screen == 1}} +
    + {{if data.atmos_alarm}} + {{:helper.link('Reset - Area Atmospheric Alarm', null, { 'atmos_reset' : 1})}} + {{else}} + {{:helper.link('Activate - Area Atmospheric Alarm', null, { 'atmos_alarm' : 1})}} + {{/if}} +
    +
    +
    + {{:helper.link('Scrubbers Control', null, { 'screen' : 3})}} +
    +
    + {{:helper.link('Vents Control', null, { 'screen' : 2})}} +
    +
    + {{:helper.link('Set Environmental Mode', null, { 'screen' : 4})}} +
    +
    + {{:helper.link('Sensor Settings', null, { 'screen' : 5})}} +
    +
    + {{if data.mode==3}} + {{:helper.link('PANIC SIPHON ACTIVE - Turn siphoning off', null, { 'mode' : 1}, null, 'redButton')}} + {{else}} + {{:helper.link('ACTIVATE PANIC SIPHON IN AREA', null, { 'mode' : 3}, null, 'yellowButton')}} + {{/if}} + {{else data.screen == 2}} + {{for data.vents}} +
    + {{:value.long_name}}
    +
    +
    + Operating: +
    +
    + {{:helper.link(value.power ? 'On' : 'Off', null, { 'id_tag' : value.id_tag, 'command' : 'set_power', 'val' : value.power ? 0 : 1}, null, value.power ? null : 'redButton')}} +
    +
    +
    +
    + Operation Mode: +
    +
    + {{:value.direction == "siphon" ? 'Siphoning' : 'Pressurizing'}} +
    +
    +
    +
    + Pressure Checks: +
    +
    + {{:helper.link('External', null, { 'id_tag' : value.id_tag, 'command' : 'set_checks', 'val' : value.checks^1}, null, value.checks&1 ? 'selected' : null)}} + {{:helper.link('Internal', null, { 'id_tag' : value.id_tag, 'command' : 'set_checks', 'val' : value.checks^2}, null, value.checks&2 ? 'selected' : null)}} +
    +
    +
    +
    + External Pressure Bound: +
    +
    + {{:helper.link(helper.fixed(value.external,2), null, { 'id_tag' : value.id_tag, 'command' : 'set_external_pressure'})}} + {{:helper.link('Reset', null, { 'id_tag' : value.id_tag, 'command' : 'reset_external_pressure'})}} +
    +
    +
    + {{empty}} + No vents connected. + {{/for}} + {{else data.screen == 3}} + {{for data.scrubbers}} +
    + {{:value.long_name}}
    +
    +
    + Operating: +
    +
    + {{:helper.link(value.power ? 'On' : 'Off', null, { 'id_tag' : value.id_tag, 'command' : 'set_power', 'val' : value.power ? 0 : 1}, null, value.power ? null : 'redButton')}} +
    +
    +
    +
    + Operation Mode: +
    +
    + {{:helper.link('Scrub', null, { 'id_tag' : value.id_tag, 'command' : 'set_scrubbing', 'scrub_mode' : 'scrub'}, null, value.scrubbing == 'scrub' ? 'selected' : null)}} + {{:helper.link('Exchange', null, { 'id_tag' : value.id_tag, 'command' : 'set_scrubbing', 'scrub_mode' : 'exchange'}, null, value.scrubbing == 'exchange' ? 'selected' : null)}} + {{:helper.link('Siphon', null, { 'id_tag' : value.id_tag, 'command' : 'set_scrubbing', 'scrub_mode' : 'siphon'}, null, value.scrubbing == 'siphon' ? 'redButton' : null)}} +
    +
    +
    +
    + Filters: +
    +
    + {{for value.filters :filterValue:filterIndex}} + {{:helper.link(filterValue.name, null, { 'id_tag' : value.id_tag, 'command' : 'set_scrub_gas', 'gas_id' : filterValue.id, 'val' : filterValue.val ? 0 : 1}, null, filterValue.val ? 'selected' : null)}} + {{/for}} +
    +
    +
    + {{empty}} + No scrubbers connected. + {{/for}} + {{else data.screen == 4}} +

    Environmental Modes

    + {{for data.modes}} +
    + {{:helper.link(value.name, null, { 'mode' : value.mode }, null, value.selected ? (value.danger ? 'redButton' : 'selected') : null)}} +
    + {{/for}} + {{else data.screen == 5}} +

    Alarm Threshold

    + Partial pressure for gases. + + + + + {{for data.thresholds}} + + + {{for value.settings :settingsValue:settingsIndex}} + + {{/for}} + + {{/for}} +
    min2min1max1max2
    {{:value.name}} + {{:helper.link(settingsValue.selected >= 0 ? helper.fixed(settingsValue.selected, 2) : "Off", null, { 'command' : 'set_threshold', 'env' : settingsValue.env, 'var' : settingsValue.val })}} +
    + {{/if}} +{{/if}} \ No newline at end of file diff --git a/nano/templates/alarm_monitor.tmpl b/nano/templates/alarm_monitor.tmpl index f39f248f0d99..4b5459ab48c6 100644 --- a/nano/templates/alarm_monitor.tmpl +++ b/nano/templates/alarm_monitor.tmpl @@ -1,37 +1,37 @@ - -{{for data.categories}} -

    {{:value.category}}

    - {{for value.alarms :alarmValue:alarmIndex}} - {{if alarmValue.origin_lost}} - {{:alarmValue.name}} Alarm Origin Lost
    - {{else}} - {{:alarmValue.name}}
    - {{/if}} - {{if alarmValue.has_cameras || alarmValue.lost_sources != ""}} -
    - {{if alarmValue.has_cameras}} -
    - {{for alarmValue.cameras :cameraValue:cameraIndex}} - {{if cameraValue.deact}} - {{:helper.link(cameraValue.name + " (deactivated)", '', {}, 'inactive')}} - {{else}} - {{:helper.link(cameraValue.name, '', {'switchTo' : cameraValue.camera})}} - {{/if}} - {{/for}} -
    - {{/if}} - {{if alarmValue.lost_sources != ""}} -
    -

    Lost Alarm Sources: {{:alarmValue.lost_sources}}

    -
    - {{/if}} -
    - {{/if}} - {{empty}} - --All Systems Nominal - {{/for}} -{{/for}} + +{{for data.categories}} +

    {{:value.category}}

    + {{for value.alarms :alarmValue:alarmIndex}} + {{if alarmValue.origin_lost}} + {{:alarmValue.name}} Alarm Origin Lost
    + {{else}} + {{:alarmValue.name}}
    + {{/if}} + {{if alarmValue.has_cameras || alarmValue.lost_sources != ""}} +
    + {{if alarmValue.has_cameras}} +
    + {{for alarmValue.cameras :cameraValue:cameraIndex}} + {{if cameraValue.deact}} + {{:helper.link(cameraValue.name + " (deactivated)", '', {}, 'inactive')}} + {{else}} + {{:helper.link(cameraValue.name, '', {'switchTo' : cameraValue.camera})}} + {{/if}} + {{/for}} +
    + {{/if}} + {{if alarmValue.lost_sources != ""}} +
    +

    Lost Alarm Sources: {{:alarmValue.lost_sources}}

    +
    + {{/if}} +
    + {{/if}} + {{empty}} + --All Systems Nominal + {{/for}} +{{/for}} diff --git a/nano/templates/appearance_changer.tmpl b/nano/templates/appearance_changer.tmpl index 00a1b62d1b5c..6d390e787157 100644 --- a/nano/templates/appearance_changer.tmpl +++ b/nano/templates/appearance_changer.tmpl @@ -1,89 +1,89 @@ -{{if data.change_race}} -
    -
    - Species: -
    -
    - {{for data.species}} - {{:helper.link(value.name, null, { 'race' : value.uid}, null, data.current_species_uid == value.uid ? 'selected' : null)}} - {{/for}} -
    -
    -{{/if}} - -{{if data.change_gender}} -
    -
    - Pronouns: -
    -
    - {{for data.genders}} - {{:helper.link(value.gender_name, null, { 'gender' : value.gender_key}, null, data.gender == value.gender_key ? 'selected' : null)}} - {{/for}} -
    -
    -{{/if}} - -{{if data.change_bodytype}} -
    -
    - Bodytype: -
    -
    - {{for data.bodytypes}} - {{:helper.link(value, null, { 'bodytype' : value}, null, data.bodytype == value ? 'selected' : null)}} - {{/for}} -
    -
    -{{/if}} - -{{if data.change_eye_color || data.change_skin_tone || data.change_skin_color || data.change_hair_color || data.change_facial_hair_color}} -
    -
    - Colors: -
    -
    - {{if data.change_eye_color}} - {{:helper.link('Change eye color', null, { 'eye_color' : 1})}} - {{/if}} - {{if data.change_skin_tone}} - {{:helper.link('Change skin tone', null, { 'skin_tone' : 1})}} - {{/if}} - {{if data.change_skin_color}} - {{:helper.link('Change skin color', null, { 'skin_color' : 1})}} - {{/if}} - {{if data.change_hair_color}} - {{:helper.link('Change hair color', null, { 'hair_color' : 1})}} - {{/if}} - {{if data.change_facial_hair_color}} - {{:helper.link('Change facial hair color', null, { 'facial_hair_color' : 1})}} - {{/if}} -
    -
    -{{/if}} - -{{if data.change_hair}} -
    -
    - Hair styles: -
    -
    - {{for data.hair_styles}} - {{:helper.link(value.hairstyle, null, { 'hair' : value.ref}, null, data.hair_style == value.hairstyle ? 'selected' : null)}} - {{/for}} -
    -
    -{{/if}} - -{{if data.change_facial_hair}} -
    -
    - Facial hair styles: -
    -
    - {{for data.facial_hair_styles}} - {{:helper.link(value.facialhairstyle, null, { 'facial_hair' : value.ref}, null, data.facial_hair_style == value.facialhairstyle ? 'selected' : null)}} - {{/for}} -
    -
    -{{/if}} +{{if data.change_race}} +
    +
    + Species: +
    +
    + {{for data.species}} + {{:helper.link(value.name, null, { 'race' : value.uid}, null, data.current_species_uid == value.uid ? 'selected' : null)}} + {{/for}} +
    +
    +{{/if}} + +{{if data.change_gender}} +
    +
    + Pronouns: +
    +
    + {{for data.genders}} + {{:helper.link(value.gender_name, null, { 'gender' : value.gender_key}, null, data.gender == value.gender_key ? 'selected' : null)}} + {{/for}} +
    +
    +{{/if}} + +{{if data.change_bodytype}} +
    +
    + Bodytype: +
    +
    + {{for data.bodytypes}} + {{:helper.link(value, null, { 'bodytype' : value}, null, data.bodytype == value ? 'selected' : null)}} + {{/for}} +
    +
    +{{/if}} + +{{if data.change_eye_color || data.change_skin_tone || data.change_skin_color || data.change_hair_color || data.change_facial_hair_color}} +
    +
    + Colors: +
    +
    + {{if data.change_eye_color}} + {{:helper.link('Change eye color', null, { 'eye_color' : 1})}} + {{/if}} + {{if data.change_skin_tone}} + {{:helper.link('Change skin tone', null, { 'skin_tone' : 1})}} + {{/if}} + {{if data.change_skin_color}} + {{:helper.link('Change skin color', null, { 'skin_color' : 1})}} + {{/if}} + {{if data.change_hair_color}} + {{:helper.link('Change hair color', null, { 'hair_color' : 1})}} + {{/if}} + {{if data.change_facial_hair_color}} + {{:helper.link('Change facial hair color', null, { 'facial_hair_color' : 1})}} + {{/if}} +
    +
    +{{/if}} + +{{if data.change_hair}} +
    +
    + Hair styles: +
    +
    + {{for data.hair_styles}} + {{:helper.link(value.hairstyle, null, { 'hair' : value.ref}, null, data.hair_style == value.hairstyle ? 'selected' : null)}} + {{/for}} +
    +
    +{{/if}} + +{{if data.change_facial_hair}} +
    +
    + Facial hair styles: +
    +
    + {{for data.facial_hair_styles}} + {{:helper.link(value.facialhairstyle, null, { 'facial_hair' : value.ref}, null, data.facial_hair_style == value.facialhairstyle ? 'selected' : null)}} + {{/for}} +
    +
    +{{/if}} diff --git a/nano/templates/atmos_alert.tmpl b/nano/templates/atmos_alert.tmpl index 92946e8d312d..a36b1bb9bafe 100644 --- a/nano/templates/atmos_alert.tmpl +++ b/nano/templates/atmos_alert.tmpl @@ -1,18 +1,18 @@ -

    Priority Alerts

    -{{for data.priority_alarms}} -
    - {{:value.name}} {{:helper.link('Reset', null, {'clear_alarm' : value.ref})}} -
    -{{empty}} - No priority alerts detected. -{{/for}} - -

    Minor Alerts

    -{{for data.minor_alarms}} -
    - {{:value.name}} {{:helper.link('Reset', null, {'clear_alarm' : value.ref})}} -
    -{{empty}} - No minor alerts detected. -{{/for}} - +

    Priority Alerts

    +{{for data.priority_alarms}} +
    + {{:value.name}} {{:helper.link('Reset', null, {'clear_alarm' : value.ref})}} +
    +{{empty}} + No priority alerts detected. +{{/for}} + +

    Minor Alerts

    +{{for data.minor_alarms}} +
    + {{:value.name}} {{:helper.link('Reset', null, {'clear_alarm' : value.ref})}} +
    +{{empty}} + No minor alerts detected. +{{/for}} + diff --git a/nano/templates/atmos_control.tmpl b/nano/templates/atmos_control.tmpl index e7f3c94d80f2..cca5724ad935 100644 --- a/nano/templates/atmos_control.tmpl +++ b/nano/templates/atmos_control.tmpl @@ -1,26 +1,26 @@ -
    - {{:helper.link('Refresh', 'refresh', {'refresh' : 1})}} -
    -
    -
    - Filter term: -
    -
    - {{:helper.link(data.filter, null, {'filter_set' : 1})}} -
    -
    -
    - {{for data.alarmsAlert}} - {{:helper.link(value.name, null, {'alarm' : value.ref}, null, 'redButton')}} - {{/for}} -
    -
    - {{for data.alarmsDanger}} - {{:helper.link(value.name, null, {'alarm' : value.ref}, null, 'yellowButton')}} - {{/for}} -
    -
    - {{for data.alarms}} - {{:helper.link(value.name, null, {'alarm' : value.ref}, null, null)}} - {{/for}} +
    + {{:helper.link('Refresh', 'refresh', {'refresh' : 1})}} +
    +
    +
    + Filter term: +
    +
    + {{:helper.link(data.filter, null, {'filter_set' : 1})}} +
    +
    +
    + {{for data.alarmsAlert}} + {{:helper.link(value.name, null, {'alarm' : value.ref}, null, 'redButton')}} + {{/for}} +
    +
    + {{for data.alarmsDanger}} + {{:helper.link(value.name, null, {'alarm' : value.ref}, null, 'yellowButton')}} + {{/for}} +
    +
    + {{for data.alarms}} + {{:helper.link(value.name, null, {'alarm' : value.ref}, null, null)}} + {{/for}}
    \ No newline at end of file diff --git a/nano/templates/door_control.tmpl b/nano/templates/door_control.tmpl index a1b0e35a2646..4197497ce8fb 100644 --- a/nano/templates/door_control.tmpl +++ b/nano/templates/door_control.tmpl @@ -1,65 +1,65 @@ - - -
    -
    - Main power is - {{if data.main_power_loss == 0}} - online - {{else data.main_power_loss == -1}} - offline - {{else}} - offline for {{:data.main_power_loss}} second{{:data.main_power_loss == 1 ? '' : 's'}} - {{/if}}. -
    -
    - {{:helper.link(data.main_power_loss ? 'Disabled' : 'Disable', null, {'command' : 'main_power'}, data.main_power_loss == 0 ? null : 'disabled', data.main_power_loss == 0 ? 'redButton' : null)}} -
    -
    - -
    -
    - Backup power is - {{if data.backup_power_loss == 0}} - online - {{else data.backup_power_loss == -1}} - offline - {{else}} - offline for {{:data.backup_power_loss}} second{{:data.backup_power_loss == 1 ? '' : 's'}} - {{/if}}. -
    -
    - {{:helper.link(data.backup_power_loss ? 'Disabled' : 'Disable', null, {'command' : 'backup_power'}, data.backup_power_loss == 0 ? null : 'disabled', data.backup_power_loss == 0 ? 'redButton' : null)}} -
    -
    - -
    -
    - Electrified Status: -
    -
    - {{:helper.link('Offline' , null, {'command' : 'electrify_permanently', 'activate' : "0" }, data.electrified == 0 ? 'selected' : null)}} - {{:helper.link(data.electrified <= 0 ? 'Temporary (30s)' : 'Temporary (' + data.electrified +'s)', null, {'command' : 'electrify_temporary', 'activate' : "1"}, data.electrified > 0 ? 'redButton' : null)}} - {{:helper.link('Permanent', null, {'command' : 'electrify_permanently', 'activate' : "1"}, data.electrified == -1 ? 'redButton' : null)}} -
    -
    - -
    - -
    - {{for data.commands}} - - - - - - {{/for}} -
    {{:value.name}}:{{:helper.link(value.enabled, null, {'command' : value.command, 'activate' : value.act ? 1 : 0}, value.active ? 'selected' : null)}}{{:helper.link(value.disabled,null, {'command' : value.command, 'activate' : value.act ? 0 : 1}, !value.active ? (value.danger ? 'redButton' : 'selected') : null)}}
    + + +
    +
    + Main power is + {{if data.main_power_loss == 0}} + online + {{else data.main_power_loss == -1}} + offline + {{else}} + offline for {{:data.main_power_loss}} second{{:data.main_power_loss == 1 ? '' : 's'}} + {{/if}}. +
    +
    + {{:helper.link(data.main_power_loss ? 'Disabled' : 'Disable', null, {'command' : 'main_power'}, data.main_power_loss == 0 ? null : 'disabled', data.main_power_loss == 0 ? 'redButton' : null)}} +
    +
    + +
    +
    + Backup power is + {{if data.backup_power_loss == 0}} + online + {{else data.backup_power_loss == -1}} + offline + {{else}} + offline for {{:data.backup_power_loss}} second{{:data.backup_power_loss == 1 ? '' : 's'}} + {{/if}}. +
    +
    + {{:helper.link(data.backup_power_loss ? 'Disabled' : 'Disable', null, {'command' : 'backup_power'}, data.backup_power_loss == 0 ? null : 'disabled', data.backup_power_loss == 0 ? 'redButton' : null)}} +
    +
    + +
    +
    + Electrified Status: +
    +
    + {{:helper.link('Offline' , null, {'command' : 'electrify_permanently', 'activate' : "0" }, data.electrified == 0 ? 'selected' : null)}} + {{:helper.link(data.electrified <= 0 ? 'Temporary (30s)' : 'Temporary (' + data.electrified +'s)', null, {'command' : 'electrify_temporary', 'activate' : "1"}, data.electrified > 0 ? 'redButton' : null)}} + {{:helper.link('Permanent', null, {'command' : 'electrify_permanently', 'activate' : "1"}, data.electrified == -1 ? 'redButton' : null)}} +
    +
    + +
    + + + {{for data.commands}} + + + + + + {{/for}} +
    {{:value.name}}:{{:helper.link(value.enabled, null, {'command' : value.command, 'activate' : value.act ? 1 : 0}, value.active ? 'selected' : null)}}{{:helper.link(value.disabled,null, {'command' : value.command, 'activate' : value.act ? 0 : 1}, !value.active ? (value.danger ? 'redButton' : 'selected') : null)}}
    diff --git a/nano/templates/law_manager.tmpl b/nano/templates/law_manager.tmpl index 1e0012bae7c1..6ba59e041797 100644 --- a/nano/templates/law_manager.tmpl +++ b/nano/templates/law_manager.tmpl @@ -1,253 +1,253 @@ - - -{{if data.isSlaved}} -
    Law synced to {{:data.isSlaved}}.
    -{{/if}} - -
    -
    - {{:helper.link('Law Management', null, {'set_view' : 0}, data.view == 0 ? 'selected' : null)}} - {{:helper.link('Law Sets', null, {'set_view' : 1}, data.view == 1 ? 'selected' : null)}} -
    -
    - -{{if data.view == 0}} - {{if data.has_ion_laws}} - - - {{if data.isMalf}} - - - {{/if}} - - -
    - {{:data.ion_law_nr}} Laws: -
    - {{for data.ion_laws}} - - - - - {{if data.isMalf}} - - - {{/if}} - - {{/for}} -
    IndexLawStateEditDelete
    {{:value.index}}.{{:value.law}}{{:helper.link('Yes', null, {'ref': value.ref, 'state_law' : 1}, value.state == 1 ? 'selected' : null)}}{{:helper.link('No', null, {'ref': value.ref, 'state_law' : 0}, value.state == 0 ? 'selected' : null)}}{{:helper.link('Edit', null, {'edit_law': value.ref})}}{{:helper.link('Delete', null, {'delete_law': value.ref}, null, 'redButton')}}
    - {{/if}} - - {{if data.has_inherent_laws || data.has_zeroth_laws}} - - - {{if data.isMalf}} - - - {{/if}} - - -
    - Inherent Laws: -
    - - {{for data.zeroth_laws}} - - - - - {{if data.isMalf}} - - - {{/if}} - - {{/for}} - - {{for data.inherent_laws}} - - - - - {{if data.isMalf}} - - - {{/if}} - - {{/for}} -
    IndexLawStateEditDelete
    {{:value.index}}.{{:value.law}}{{:helper.link('Yes', null, {'ref': value.ref, 'state_law' : 1}, value.state == 1 ? 'selected' : null)}}{{:helper.link('No', null, {'ref': value.ref, 'state_law' : 0}, value.state != 1 ? 'selected' : null)}}{{:helper.link('Edit', null, {'edit_law': value.ref}, data.isAdmin ? null : 'disabled')}}{{:helper.link('Delete', null, {'delete_law': value.ref}, data.isAdmin ? null : 'disabled', data.isAdmin ? 'redButton' : null)}}
    {{:value.index}}.{{:value.law}}{{:helper.link('Yes', null, {'ref': value.ref, 'state_law' : 1}, value.state == 1 ? 'selected' : null)}}{{:helper.link('No', null, {'ref': value.ref, 'state_law' : 0}, value.state == 0 ? 'selected' : null)}}{{:helper.link('Edit', null, {'edit_law': value.ref})}}{{:helper.link('Delete', null, {'delete_law': value.ref}, null, 'redButton')}}
    - {{/if}} - - {{if data.has_supplied_laws}} - - - {{if data.isMalf}} - - - {{/if}} - - -
    - Supplied Laws: -
    - {{for data.supplied_laws}} - - - - - {{if data.isMalf}} - - - {{/if}} - - {{/for}} -
    IndexLawStateEditDelete
    {{:value.index}}.{{:value.law}}{{:helper.link('Yes', null, {'ref': value.ref, 'state_law' : 1}, value.state == 1 ? 'selected' : null)}}{{:helper.link('No', null, {'ref': value.ref, 'state_law' : 0}, value.state == 0 ? 'selected' : null)}}{{:helper.link('Edit', null, {'edit_law': value.ref})}}{{:helper.link('Delete', null, {'delete_law': value.ref}, null, 'redButton')}}
    - {{/if}} - -
    -
    - Statement Channel: -
    -
    - {{for data.channels}} - {{:helper.link(value.channel, null, {'law_channel' : value.channel}, value.channel == data.channel ? 'selected' : null)}} - {{/for}} -
    -
    - -
    -
    - State Laws: -
    -
    - {{:helper.link('State Laws', null, {'state_laws' : 1})}} -
    -
    - - {{if data.isMalf}} -
    -
    - Add Laws: -
    -
    - - - {{if data.isAdmin && !data.has_zeroth_laws}} - - {{/if}} - - - -
    TypeLawIndexEditAdd
    Zero{{:data.zeroth_law}}N/A{{:helper.link('Edit', null, {'change_zeroth_law' : 1})}}{{:helper.link('Add', null, {'add_zeroth_law' : 1})}}
    Ion{{:data.ion_law}}N/A{{:helper.link('Edit', null, {'change_ion_law' : 1})}}{{:helper.link('Add', null, {'add_ion_law' : 1})}}
    Inherent{{:data.inherent_law}}N/A{{:helper.link('Edit', null, {'change_inherent_law' : 1})}}{{:helper.link('Add', null, {'add_inherent_law' : 1})}}
    Supplied{{:data.supplied_law}}{{:helper.link(data.supplied_law_position, null, {'change_supplied_law_position' : 1})}}{{:helper.link('Edit', null, {'change_supplied_law' : 1})}}{{:helper.link('Add', null, {'add_supplied_law' : 1})}}
    -
    -
    - {{/if}} - - {{if data.isAI}} -
    -
    - Law Notification: -
    -
    - {{:helper.link('Notify', null, {'notify_laws' : 1})}} -
    -
    - {{/if}} -{{else data.view == 1}} -
    Remember: Stating laws other than those currently loaded may be grounds for decommissioning.
    - - {{for data.law_sets}} -
    -
    -

    {{:value.name}}

    {{:value.header}} -
    - - {{if value.laws.has_ion_laws}} - - - {{for value.laws.ion_laws :lawValue:lawindex}} - - - - - {{/for}} -
    IndexLaw
    {{:lawValue.index}}.{{:lawValue.law}}
    - {{/if}} - - {{if value.laws.has_zeroth_laws || value.laws.has_inherent_laws}} - - - {{for value.laws.zeroth_laws :lawValue:lawindex}} - - - - - {{/for}} - {{for value.laws.inherent_laws :lawValue:lawindex}} - - - - - {{/for}} -
    IndexLaw
    {{:lawValue.index}}.{{:lawValue.law}}
    {{:lawValue.index}}.{{:lawValue.law}}
    - {{/if}} - - {{if value.laws.has_supplied_laws}} - - - {{for value.laws.supplied_laws :lawValue:lawindex}} - - - - - {{/for}} -
    IndexLaw
    {{:lawValue.index}}.{{:lawValue.law}}
    - {{/if}} - -
    -
    - {{:helper.link('Load Laws', null, {'transfer_laws' : value.ref}, data.isMalf ? null : 'disabled')}}{{:helper.link('State Laws', null, {'state_law_set' : value.ref})}} -
    -
    - {{/for}} + + +{{if data.isSlaved}} +
    Law synced to {{:data.isSlaved}}.
    +{{/if}} + +
    +
    + {{:helper.link('Law Management', null, {'set_view' : 0}, data.view == 0 ? 'selected' : null)}} + {{:helper.link('Law Sets', null, {'set_view' : 1}, data.view == 1 ? 'selected' : null)}} +
    +
    + +{{if data.view == 0}} + {{if data.has_ion_laws}} + + + {{if data.isMalf}} + + + {{/if}} + + +
    + {{:data.ion_law_nr}} Laws: +
    + {{for data.ion_laws}} + + + + + {{if data.isMalf}} + + + {{/if}} + + {{/for}} +
    IndexLawStateEditDelete
    {{:value.index}}.{{:value.law}}{{:helper.link('Yes', null, {'ref': value.ref, 'state_law' : 1}, value.state == 1 ? 'selected' : null)}}{{:helper.link('No', null, {'ref': value.ref, 'state_law' : 0}, value.state == 0 ? 'selected' : null)}}{{:helper.link('Edit', null, {'edit_law': value.ref})}}{{:helper.link('Delete', null, {'delete_law': value.ref}, null, 'redButton')}}
    + {{/if}} + + {{if data.has_inherent_laws || data.has_zeroth_laws}} + + + {{if data.isMalf}} + + + {{/if}} + + +
    + Inherent Laws: +
    + + {{for data.zeroth_laws}} + + + + + {{if data.isMalf}} + + + {{/if}} + + {{/for}} + + {{for data.inherent_laws}} + + + + + {{if data.isMalf}} + + + {{/if}} + + {{/for}} +
    IndexLawStateEditDelete
    {{:value.index}}.{{:value.law}}{{:helper.link('Yes', null, {'ref': value.ref, 'state_law' : 1}, value.state == 1 ? 'selected' : null)}}{{:helper.link('No', null, {'ref': value.ref, 'state_law' : 0}, value.state != 1 ? 'selected' : null)}}{{:helper.link('Edit', null, {'edit_law': value.ref}, data.isAdmin ? null : 'disabled')}}{{:helper.link('Delete', null, {'delete_law': value.ref}, data.isAdmin ? null : 'disabled', data.isAdmin ? 'redButton' : null)}}
    {{:value.index}}.{{:value.law}}{{:helper.link('Yes', null, {'ref': value.ref, 'state_law' : 1}, value.state == 1 ? 'selected' : null)}}{{:helper.link('No', null, {'ref': value.ref, 'state_law' : 0}, value.state == 0 ? 'selected' : null)}}{{:helper.link('Edit', null, {'edit_law': value.ref})}}{{:helper.link('Delete', null, {'delete_law': value.ref}, null, 'redButton')}}
    + {{/if}} + + {{if data.has_supplied_laws}} + + + {{if data.isMalf}} + + + {{/if}} + + +
    + Supplied Laws: +
    + {{for data.supplied_laws}} + + + + + {{if data.isMalf}} + + + {{/if}} + + {{/for}} +
    IndexLawStateEditDelete
    {{:value.index}}.{{:value.law}}{{:helper.link('Yes', null, {'ref': value.ref, 'state_law' : 1}, value.state == 1 ? 'selected' : null)}}{{:helper.link('No', null, {'ref': value.ref, 'state_law' : 0}, value.state == 0 ? 'selected' : null)}}{{:helper.link('Edit', null, {'edit_law': value.ref})}}{{:helper.link('Delete', null, {'delete_law': value.ref}, null, 'redButton')}}
    + {{/if}} + +
    +
    + Statement Channel: +
    +
    + {{for data.channels}} + {{:helper.link(value.channel, null, {'law_channel' : value.channel}, value.channel == data.channel ? 'selected' : null)}} + {{/for}} +
    +
    + +
    +
    + State Laws: +
    +
    + {{:helper.link('State Laws', null, {'state_laws' : 1})}} +
    +
    + + {{if data.isMalf}} +
    +
    + Add Laws: +
    +
    + + + {{if data.isAdmin && !data.has_zeroth_laws}} + + {{/if}} + + + +
    TypeLawIndexEditAdd
    Zero{{:data.zeroth_law}}N/A{{:helper.link('Edit', null, {'change_zeroth_law' : 1})}}{{:helper.link('Add', null, {'add_zeroth_law' : 1})}}
    Ion{{:data.ion_law}}N/A{{:helper.link('Edit', null, {'change_ion_law' : 1})}}{{:helper.link('Add', null, {'add_ion_law' : 1})}}
    Inherent{{:data.inherent_law}}N/A{{:helper.link('Edit', null, {'change_inherent_law' : 1})}}{{:helper.link('Add', null, {'add_inherent_law' : 1})}}
    Supplied{{:data.supplied_law}}{{:helper.link(data.supplied_law_position, null, {'change_supplied_law_position' : 1})}}{{:helper.link('Edit', null, {'change_supplied_law' : 1})}}{{:helper.link('Add', null, {'add_supplied_law' : 1})}}
    +
    +
    + {{/if}} + + {{if data.isAI}} +
    +
    + Law Notification: +
    +
    + {{:helper.link('Notify', null, {'notify_laws' : 1})}} +
    +
    + {{/if}} +{{else data.view == 1}} +
    Remember: Stating laws other than those currently loaded may be grounds for decommissioning.
    + + {{for data.law_sets}} +
    +
    +

    {{:value.name}}

    {{:value.header}} +
    + + {{if value.laws.has_ion_laws}} + + + {{for value.laws.ion_laws :lawValue:lawindex}} + + + + + {{/for}} +
    IndexLaw
    {{:lawValue.index}}.{{:lawValue.law}}
    + {{/if}} + + {{if value.laws.has_zeroth_laws || value.laws.has_inherent_laws}} + + + {{for value.laws.zeroth_laws :lawValue:lawindex}} + + + + + {{/for}} + {{for value.laws.inherent_laws :lawValue:lawindex}} + + + + + {{/for}} +
    IndexLaw
    {{:lawValue.index}}.{{:lawValue.law}}
    {{:lawValue.index}}.{{:lawValue.law}}
    + {{/if}} + + {{if value.laws.has_supplied_laws}} + + + {{for value.laws.supplied_laws :lawValue:lawindex}} + + + + + {{/for}} +
    IndexLaw
    {{:lawValue.index}}.{{:lawValue.law}}
    + {{/if}} + +
    +
    + {{:helper.link('Load Laws', null, {'transfer_laws' : value.ref}, data.isMalf ? null : 'disabled')}}{{:helper.link('State Laws', null, {'state_law_set' : value.ref})}} +
    +
    + {{/for}} {{/if}} \ No newline at end of file diff --git a/nano/templates/nuclear_bomb.tmpl b/nano/templates/nuclear_bomb.tmpl index c22984160022..68fc9d42a64f 100644 --- a/nano/templates/nuclear_bomb.tmpl +++ b/nano/templates/nuclear_bomb.tmpl @@ -1,72 +1,72 @@ - -
    - Authorization Disk: {{if data.auth}}{{:helper.link('++++++++++', 'eject', {'auth' : 1})}} {{else}} {{:helper.link('----------', 'disk', {'auth' : 1})}}{{/if}} -
    -
    -
    -
    Status: {{:data.authstatus}} - {{:data.safe}}
    -
    Timer: {{:data.time}}
    -
    -
    -
    - {{if data.auth && data.yescode}} -
    - Timer: {{:helper.link('On', 'play', {'timer' : 1}, data.timer ? 'redButton' : '')}}{{:helper.link('Off', 'stop', {'timer' : 0}, !data.timer ? 'selected' : '')}} -
    -
    - Time: {{:helper.link('--', '', {'time' : -10}, data.time <= 120 ? 'disabled' : '')}}{{:helper.link('-', '', {'time' : -1}, data.time <= 120 ? 'disabled' : '')}} {{:data.time}} {{:helper.link('+', '', {'time' : 1})}}{{:helper.link('++', '', {'time' : 10})}} -
    - {{else}} -
    - Timer: {{:helper.link('On', 'play', null, 'disabled')}}{{:helper.link('Off', 'pause', null, 'disabled')}} -
    -
    - Time: {{:helper.link('-', '', null, 'disabled')}}{{:helper.link('-', '', null, 'disabled')}} {{:data.time}} {{:helper.link('+', '', null, 'disabled')}}{{:helper.link('++', '', null, 'disabled')}} -
    - {{/if}} -
    -
    - {{if data.auth && data.yescode}} -
    - Safety: {{:helper.link('Engaged', 'info', {'safety' : 1}, data.safety ? 'selected' : '')}}{{:helper.link('Disengaged', 'alert', {'safety' : 0}, data.safety ? '' : 'redButton')}} -
    - {{if data.moveable_anchor}} -
    - Anchor: {{:helper.link('Engaged', 'locked', {'anchor' : 1}, data.anchored ? 'selected' : '')}}{{:helper.link('Disengaged', 'unlocked', {'anchor' : 0}, data.anchored ? '' : 'selected')}} -
    - {{/if}} - {{else}} -
    - Safety: {{:helper.link('Engaged', 'info', null, 'disabled')}}{{:helper.link('Disengaged', 'alert', null, 'disabled')}} -
    - {{if data.moveable_anchor}} -
    - Anchor: {{:helper.link('Engaged', 'locked', null, 'disabled')}}{{:helper.link('Disengaged', 'unlocked', null, 'disabled')}} -
    - {{/if}} - {{/if}} -
    -
    -
    -
    -
    - >{{if data.message}} {{:data.message}}{{/if}} -
    -
    -
    - {{:helper.link('1', '', {'type' : 1})}}{{:helper.link('2', '', {'type' : 2})}}{{:helper.link('3', '', {'type' : 3})}} -
    -
    - {{:helper.link('4', '', {'type' : 4})}}{{:helper.link('5', '', {'type' : 5})}}{{:helper.link('6', '', {'type' : 6})}} -
    -
    - {{:helper.link('7', '', {'type' : 7})}}{{:helper.link('8', '', {'type' : 8})}}{{:helper.link('9', '', {'type' : 9})}} -
    -
    - {{:helper.link('R', '', {'type' : 'R'})}}{{:helper.link('0', '', {'type' : 0})}}{{:helper.link('E', '', {'type' : 'E'})}} -
    -
    -
    + +
    + Authorization Disk: {{if data.auth}}{{:helper.link('++++++++++', 'eject', {'auth' : 1})}} {{else}} {{:helper.link('----------', 'disk', {'auth' : 1})}}{{/if}} +
    +
    +
    +
    Status: {{:data.authstatus}} - {{:data.safe}}
    +
    Timer: {{:data.time}}
    +
    +
    +
    + {{if data.auth && data.yescode}} +
    + Timer: {{:helper.link('On', 'play', {'timer' : 1}, data.timer ? 'redButton' : '')}}{{:helper.link('Off', 'stop', {'timer' : 0}, !data.timer ? 'selected' : '')}} +
    +
    + Time: {{:helper.link('--', '', {'time' : -10}, data.time <= 120 ? 'disabled' : '')}}{{:helper.link('-', '', {'time' : -1}, data.time <= 120 ? 'disabled' : '')}} {{:data.time}} {{:helper.link('+', '', {'time' : 1})}}{{:helper.link('++', '', {'time' : 10})}} +
    + {{else}} +
    + Timer: {{:helper.link('On', 'play', null, 'disabled')}}{{:helper.link('Off', 'pause', null, 'disabled')}} +
    +
    + Time: {{:helper.link('-', '', null, 'disabled')}}{{:helper.link('-', '', null, 'disabled')}} {{:data.time}} {{:helper.link('+', '', null, 'disabled')}}{{:helper.link('++', '', null, 'disabled')}} +
    + {{/if}} +
    +
    + {{if data.auth && data.yescode}} +
    + Safety: {{:helper.link('Engaged', 'info', {'safety' : 1}, data.safety ? 'selected' : '')}}{{:helper.link('Disengaged', 'alert', {'safety' : 0}, data.safety ? '' : 'redButton')}} +
    + {{if data.moveable_anchor}} +
    + Anchor: {{:helper.link('Engaged', 'locked', {'anchor' : 1}, data.anchored ? 'selected' : '')}}{{:helper.link('Disengaged', 'unlocked', {'anchor' : 0}, data.anchored ? '' : 'selected')}} +
    + {{/if}} + {{else}} +
    + Safety: {{:helper.link('Engaged', 'info', null, 'disabled')}}{{:helper.link('Disengaged', 'alert', null, 'disabled')}} +
    + {{if data.moveable_anchor}} +
    + Anchor: {{:helper.link('Engaged', 'locked', null, 'disabled')}}{{:helper.link('Disengaged', 'unlocked', null, 'disabled')}} +
    + {{/if}} + {{/if}} +
    +
    +
    +
    +
    + >{{if data.message}} {{:data.message}}{{/if}} +
    +
    +
    + {{:helper.link('1', '', {'type' : 1})}}{{:helper.link('2', '', {'type' : 2})}}{{:helper.link('3', '', {'type' : 3})}} +
    +
    + {{:helper.link('4', '', {'type' : 4})}}{{:helper.link('5', '', {'type' : 5})}}{{:helper.link('6', '', {'type' : 6})}} +
    +
    + {{:helper.link('7', '', {'type' : 7})}}{{:helper.link('8', '', {'type' : 8})}}{{:helper.link('9', '', {'type' : 9})}} +
    +
    + {{:helper.link('R', '', {'type' : 'R'})}}{{:helper.link('0', '', {'type' : 0})}}{{:helper.link('E', '', {'type' : 'E'})}} +
    +
    +
    diff --git a/nano/templates/omni_filter.tmpl b/nano/templates/omni_filter.tmpl index 54f757ecb799..eaa587a77788 100644 --- a/nano/templates/omni_filter.tmpl +++ b/nano/templates/omni_filter.tmpl @@ -1,103 +1,103 @@ -
    -
    - {{:helper.link(data.power ? 'On' : 'Off', null, {'command' : 'power'}, data.config ? 'disabled' : null)}} -
    -
    - {{:helper.link('Configure', null, {'command' : 'configure'}, null, data.config ? 'selected' : null)}} -
    -
    -
    - {{if data.config}} - -
    -
    -
    Port
    - {{for data.ports}} -
    {{:value.dir}} Port
    - {{/for}} -
    -
    -
    None
    - {{for data.ports}} -
    - {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'none', 'dir' : value.dir}, null, value.output ? 'selected' : null)}} -
    - {{/for}} -
    -
    -
    Input
    - {{for data.ports}} -
    - {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'in', 'dir' : value.dir}, null, value.input ? 'selected' : null)}} -
    - {{/for}} -
    -
    -
    Output
    - {{for data.ports}} -
    - {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'out', 'dir' : value.dir}, null, value.output ? 'selected' : null)}} -
    - {{/for}} -
    -
    -
    Filtering
    - {{for data.ports}} -
    - {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'filtering', 'dir' : value.dir}, null, value.filter ? 'selected' : null)}} -
    - {{/for}} -
    -
    -
    Filter
    - {{for data.ports}} -
    - {{:helper.link(value.f_type ? value.f_type : 'None', null, {'command' : 'switch_filter', 'mode' : value.f_type, 'dir' : value.dir}, value.filter ? null : 'disabled', value.f_type ? 'selected' : null)}} -
    - {{/for}} -
    -
    - -
    - Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s -
    -
    - {{:helper.link('Set Flow Rate Limit', null, {'command' : 'set_flow_rate'})}} -
    - - {{else}} - -
    -
    -
    Port
    - {{for data.ports}} -
    {{:value.dir}} Port
    - {{/for}} -
    -
    -
    Mode
    - {{for data.ports}} -
    - {{if value.input}} - Input - {{else value.output}} - Output - {{else value.f_type}} - {{:value.f_type}} - {{else}} - Disabled - {{/if}} -
    - {{/for}} -
    -
    - -
    - Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s -
    - -
    - Flow Rate: {{:(data.last_flow_rate/10)}} L/s -
    - {{/if}} +
    +
    + {{:helper.link(data.power ? 'On' : 'Off', null, {'command' : 'power'}, data.config ? 'disabled' : null)}} +
    +
    + {{:helper.link('Configure', null, {'command' : 'configure'}, null, data.config ? 'selected' : null)}} +
    +
    +
    + {{if data.config}} + +
    +
    +
    Port
    + {{for data.ports}} +
    {{:value.dir}} Port
    + {{/for}} +
    +
    +
    None
    + {{for data.ports}} +
    + {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'none', 'dir' : value.dir}, null, value.output ? 'selected' : null)}} +
    + {{/for}} +
    +
    +
    Input
    + {{for data.ports}} +
    + {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'in', 'dir' : value.dir}, null, value.input ? 'selected' : null)}} +
    + {{/for}} +
    +
    +
    Output
    + {{for data.ports}} +
    + {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'out', 'dir' : value.dir}, null, value.output ? 'selected' : null)}} +
    + {{/for}} +
    +
    +
    Filtering
    + {{for data.ports}} +
    + {{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'filtering', 'dir' : value.dir}, null, value.filter ? 'selected' : null)}} +
    + {{/for}} +
    +
    +
    Filter
    + {{for data.ports}} +
    + {{:helper.link(value.f_type ? value.f_type : 'None', null, {'command' : 'switch_filter', 'mode' : value.f_type, 'dir' : value.dir}, value.filter ? null : 'disabled', value.f_type ? 'selected' : null)}} +
    + {{/for}} +
    +
    + +
    + Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s +
    +
    + {{:helper.link('Set Flow Rate Limit', null, {'command' : 'set_flow_rate'})}} +
    + + {{else}} + +
    +
    +
    Port
    + {{for data.ports}} +
    {{:value.dir}} Port
    + {{/for}} +
    +
    +
    Mode
    + {{for data.ports}} +
    + {{if value.input}} + Input + {{else value.output}} + Output + {{else value.f_type}} + {{:value.f_type}} + {{else}} + Disabled + {{/if}} +
    + {{/for}} +
    +
    + +
    + Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s +
    + +
    + Flow Rate: {{:(data.last_flow_rate/10)}} L/s +
    + {{/if}}
    \ No newline at end of file diff --git a/nano/templates/omni_mixer.tmpl b/nano/templates/omni_mixer.tmpl index 77c4573880b0..985f49ecaae3 100644 --- a/nano/templates/omni_mixer.tmpl +++ b/nano/templates/omni_mixer.tmpl @@ -1,102 +1,102 @@ -
    -
    - {{:helper.link(data.power ? 'On' : 'Off', null, {'command' : 'power'}, data.config ? 'disabled' : null)}} -
    -
    - {{:helper.link('Configure', null, {'command' : 'configure'}, null, data.config ? 'selected' : null)}} -
    -
    -
    - {{if data.config}} - -
    -
    -
    Port
    - {{for data.ports}} -
    {{:value.dir}} Port
    - {{/for}} -
    -
    -
    Input
    - {{for data.ports}} -
    - {{:helper.link(' ', null, value.input ? {'command' : 'switch_mode', 'mode' : 'none', 'dir' : value.dir} : {'command' : 'switch_mode', 'mode' : 'in', 'dir' : value.dir}, value.output ? 'disabled' : null, value.input ? 'selected' : null)}} -
    - {{/for}} -
    -
    -
    Output
    - {{for data.ports}} -
    - {{:helper.link(' ', null, value.output ? null : {'command' : 'switch_mode', 'mode' : 'out', 'dir' : value.dir}, null, value.output ? 'selected' : null)}} -
    - {{/for}} -
    -
    -
    Concentration
    - {{for data.ports}} -
    - {{:helper.link( value.input ? helper.round(value.concentration*100)+' %' : '-', null, {'command' : 'switch_con', 'dir' : value.dir}, value.input ? null : 'disabled')}} -
    - {{/for}} -
    -
    -
    Lock
    - {{for data.ports}} -
    - {{:helper.link(' ', value.con_lock ? 'locked' : 'unlocked', {'command' : 'switch_conlock', 'dir' : value.dir}, value.input ? null : 'disabled', value.con_lock ? 'selected' : null)}} -
    - {{/for}} -
    -
    - -
    - Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s -
    -
    - {{:helper.link('Set Flow Rate Limit', null, {'command' : 'set_flow_rate'})}} -
    - - {{else}} - -
    -
    -
    Port
    - {{for data.ports}} -
    {{:value.dir}} Port
    - {{/for}} -
    -
    -
    Mode
    - {{for data.ports}} -
    - {{if value.input}} - Input - {{else value.output}} - Output - {{else}} - Disabled - {{/if}} -
    - {{/for}} -
    -
    -
    Concentration
    - {{for data.ports}} -
    - {{if value.input}} - {{:helper.round(value.concentration*100)}} % - {{else}} - - - {{/if}} -
    - {{/for}} -
    -
    - -
    - Flow Rate: {{:(data.last_flow_rate/10)}} L/s -
    - - {{/if}} +
    +
    + {{:helper.link(data.power ? 'On' : 'Off', null, {'command' : 'power'}, data.config ? 'disabled' : null)}} +
    +
    + {{:helper.link('Configure', null, {'command' : 'configure'}, null, data.config ? 'selected' : null)}} +
    +
    +
    + {{if data.config}} + +
    +
    +
    Port
    + {{for data.ports}} +
    {{:value.dir}} Port
    + {{/for}} +
    +
    +
    Input
    + {{for data.ports}} +
    + {{:helper.link(' ', null, value.input ? {'command' : 'switch_mode', 'mode' : 'none', 'dir' : value.dir} : {'command' : 'switch_mode', 'mode' : 'in', 'dir' : value.dir}, value.output ? 'disabled' : null, value.input ? 'selected' : null)}} +
    + {{/for}} +
    +
    +
    Output
    + {{for data.ports}} +
    + {{:helper.link(' ', null, value.output ? null : {'command' : 'switch_mode', 'mode' : 'out', 'dir' : value.dir}, null, value.output ? 'selected' : null)}} +
    + {{/for}} +
    +
    +
    Concentration
    + {{for data.ports}} +
    + {{:helper.link( value.input ? helper.round(value.concentration*100)+' %' : '-', null, {'command' : 'switch_con', 'dir' : value.dir}, value.input ? null : 'disabled')}} +
    + {{/for}} +
    +
    +
    Lock
    + {{for data.ports}} +
    + {{:helper.link(' ', value.con_lock ? 'locked' : 'unlocked', {'command' : 'switch_conlock', 'dir' : value.dir}, value.input ? null : 'disabled', value.con_lock ? 'selected' : null)}} +
    + {{/for}} +
    +
    + +
    + Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s +
    +
    + {{:helper.link('Set Flow Rate Limit', null, {'command' : 'set_flow_rate'})}} +
    + + {{else}} + +
    +
    +
    Port
    + {{for data.ports}} +
    {{:value.dir}} Port
    + {{/for}} +
    +
    +
    Mode
    + {{for data.ports}} +
    + {{if value.input}} + Input + {{else value.output}} + Output + {{else}} + Disabled + {{/if}} +
    + {{/for}} +
    +
    +
    Concentration
    + {{for data.ports}} +
    + {{if value.input}} + {{:helper.round(value.concentration*100)}} % + {{else}} + - + {{/if}} +
    + {{/for}} +
    +
    + +
    + Flow Rate: {{:(data.last_flow_rate/10)}} L/s +
    + + {{/if}}
    \ No newline at end of file diff --git a/nano/templates/portpump.tmpl b/nano/templates/portpump.tmpl index 3e14aac8f92d..59ada0a54ac2 100644 --- a/nano/templates/portpump.tmpl +++ b/nano/templates/portpump.tmpl @@ -1,100 +1,100 @@ -

    Pump Status

    -
    -
    - Tank Pressure: -
    -
    - {{:data.tankPressure}} kPa -
    -
    - -
    -
    - Port Status: -
    -
    - {{:data.portConnected ? 'Connected' : 'Disconnected'}} -
    -
    - -
    -
    - Load: -
    -
    - {{:data.powerDraw}} W -
    -
    - -
    -
    - Cell Charge: -
    -
    - {{:helper.displayBar(data.cellCharge, 0, data.cellMaxCharge)}} -
    -
    - -

    Holding Tank Status

    -{{if data.hasHoldingTank}} -
    -
    - Tank Label: -
    -
    -
    {{:data.holdingTank.name}}
    {{:helper.link('Eject', 'eject', {'remove_tank' : 1})}} -
    -
    - -
    -
    - Tank Pressure: -
    -
    - {{:data.holdingTank.tankPressure}} kPa -
    -
    -{{else}} -
    No holding tank inserted.
    -
     
    -{{/if}} - - -

    Power Regulator Status

    -
    -
    - Target Pressure: -
    -
    - {{:helper.displayBar(data.targetpressure, data.minpressure, data.maxpressure)}} -
    - {{:helper.link('-', null, {'pressure_adj' : -1000}, (data.targetpressure > data.minpressure) ? null : 'disabled')}} - {{:helper.link('-', null, {'pressure_adj' : -100}, (data.targetpressure > data.minpressure) ? null : 'disabled')}} - {{:helper.link('-', null, {'pressure_adj' : -10}, (data.targetpressure > data.minpressure) ? null : 'disabled')}} - {{:helper.link('-', null, {'pressure_adj' : -1}, (data.targetpressure > data.minpressure) ? null : 'disabled')}} -
     {{:data.targetpressure}} kPa 
    - {{:helper.link('+', null, {'pressure_adj' : 1}, (data.targetpressure < data.maxpressure) ? null : 'disabled')}} - {{:helper.link('+', null, {'pressure_adj' : 10}, (data.targetpressure < data.maxpressure) ? null : 'disabled')}} - {{:helper.link('+', null, {'pressure_adj' : 100}, (data.targetpressure < data.maxpressure) ? null : 'disabled')}} - {{:helper.link('+', null, {'pressure_adj' : 1000}, (data.targetpressure < data.maxpressure) ? null : 'disabled')}} -
    -
    -
    - -
    -
    - Power Switch: -
    -
    - {{:helper.link('On', 'unlocked', {'power' : 1}, data.on ? 'selected' : null)}} {{:helper.link('Off', 'locked', {'power' : 1}, data.on ? null : 'selected')}} -
    -
    - -
    -
    - Pump Direction: -
    -
    - {{:helper.link('Out', 'arrowreturn-1-e', {'direction' : 1}, data.pump_dir ? 'selected' : null)}} {{:helper.link('In', 'arrowreturn-1-w', {'direction' : 1}, data.pump_dir ? null : 'selected')}} -
    -
    +

    Pump Status

    +
    +
    + Tank Pressure: +
    +
    + {{:data.tankPressure}} kPa +
    +
    + +
    +
    + Port Status: +
    +
    + {{:data.portConnected ? 'Connected' : 'Disconnected'}} +
    +
    + +
    +
    + Load: +
    +
    + {{:data.powerDraw}} W +
    +
    + +
    +
    + Cell Charge: +
    +
    + {{:helper.displayBar(data.cellCharge, 0, data.cellMaxCharge)}} +
    +
    + +

    Holding Tank Status

    +{{if data.hasHoldingTank}} +
    +
    + Tank Label: +
    +
    +
    {{:data.holdingTank.name}}
    {{:helper.link('Eject', 'eject', {'remove_tank' : 1})}} +
    +
    + +
    +
    + Tank Pressure: +
    +
    + {{:data.holdingTank.tankPressure}} kPa +
    +
    +{{else}} +
    No holding tank inserted.
    +
     
    +{{/if}} + + +

    Power Regulator Status

    +
    +
    + Target Pressure: +
    +
    + {{:helper.displayBar(data.targetpressure, data.minpressure, data.maxpressure)}} +
    + {{:helper.link('-', null, {'pressure_adj' : -1000}, (data.targetpressure > data.minpressure) ? null : 'disabled')}} + {{:helper.link('-', null, {'pressure_adj' : -100}, (data.targetpressure > data.minpressure) ? null : 'disabled')}} + {{:helper.link('-', null, {'pressure_adj' : -10}, (data.targetpressure > data.minpressure) ? null : 'disabled')}} + {{:helper.link('-', null, {'pressure_adj' : -1}, (data.targetpressure > data.minpressure) ? null : 'disabled')}} +
     {{:data.targetpressure}} kPa 
    + {{:helper.link('+', null, {'pressure_adj' : 1}, (data.targetpressure < data.maxpressure) ? null : 'disabled')}} + {{:helper.link('+', null, {'pressure_adj' : 10}, (data.targetpressure < data.maxpressure) ? null : 'disabled')}} + {{:helper.link('+', null, {'pressure_adj' : 100}, (data.targetpressure < data.maxpressure) ? null : 'disabled')}} + {{:helper.link('+', null, {'pressure_adj' : 1000}, (data.targetpressure < data.maxpressure) ? null : 'disabled')}} +
    +
    +
    + +
    +
    + Power Switch: +
    +
    + {{:helper.link('On', 'unlocked', {'power' : 1}, data.on ? 'selected' : null)}} {{:helper.link('Off', 'locked', {'power' : 1}, data.on ? null : 'selected')}} +
    +
    + +
    +
    + Pump Direction: +
    +
    + {{:helper.link('Out', 'arrowreturn-1-e', {'direction' : 1}, data.pump_dir ? 'selected' : null)}} {{:helper.link('In', 'arrowreturn-1-w', {'direction' : 1}, data.pump_dir ? null : 'selected')}} +
    +
    diff --git a/nano/templates/portscrubber.tmpl b/nano/templates/portscrubber.tmpl index c99f53344c41..f2f216f630b1 100644 --- a/nano/templates/portscrubber.tmpl +++ b/nano/templates/portscrubber.tmpl @@ -1,91 +1,91 @@ -

    Scrubber Status

    -
    -
    - Tank Pressure: -
    -
    - {{:data.tankPressure}} kPa -
    -
    - -
    -
    - Port Status: -
    -
    - {{:data.portConnected ? 'Connected' : 'Disconnected'}} -
    -
    - -
    -
    - Load: -
    -
    - {{:data.powerDraw}} W -
    -
    - -
    -
    - Cell Charge: -
    -
    - {{:helper.displayBar(data.cellCharge, 0, data.cellMaxCharge)}} -
    -
    - -

    Holding Tank Status

    -{{if data.hasHoldingTank}} -
    -
    - Tank Label: -
    -
    -
    {{:data.holdingTank.name}}
    {{:helper.link('Eject', 'eject', {'remove_tank' : 1})}} -
    -
    q - -
    -
    - Tank Pressure: -
    -
    - {{:data.holdingTank.tankPressure}} kPa -
    -
    -{{else}} -
    No holding tank inserted.
    -
     
    -{{/if}} - - -

    Power Regulator Status

    -
    -
    - Volume Rate: -
    -
    - {{:helper.displayBar(data.rate, data.minrate, data.maxrate)}} -
    - {{:helper.link('-', null, {'volume_adj' : -1000}, (data.rate > data.minrate) ? null : 'disabled')}} - {{:helper.link('-', null, {'volume_adj' : -100}, (data.rate > data.minrate) ? null : 'disabled')}} - {{:helper.link('-', null, {'volume_adj' : -10}, (data.rate > data.minrate) ? null : 'disabled')}} - {{:helper.link('-', null, {'volume_adj' : -1}, (data.rate > data.minrate) ? null : 'disabled')}} -
     {{:data.rate}} L/s 
    - {{:helper.link('+', null, {'volume_adj' : 1}, (data.rate < data.maxrate) ? null : 'disabled')}} - {{:helper.link('+', null, {'volume_adj' : 10}, (data.rate < data.maxrate) ? null : 'disabled')}} - {{:helper.link('+', null, {'volume_adj' : 100}, (data.rate < data.maxrate) ? null : 'disabled')}} - {{:helper.link('+', null, {'volume_adj' : 1000}, (data.rate < data.maxrate) ? null : 'disabled')}} -
    -
    -
    - -
    -
    - Power Switch: -
    -
    - {{:helper.link('On', 'unlocked', {'power' : 1}, data.on ? 'selected' : null)}} {{:helper.link('Off', 'locked', {'power' : 1}, data.on ? null : 'selected')}} -
    -
    +

    Scrubber Status

    +
    +
    + Tank Pressure: +
    +
    + {{:data.tankPressure}} kPa +
    +
    + +
    +
    + Port Status: +
    +
    + {{:data.portConnected ? 'Connected' : 'Disconnected'}} +
    +
    + +
    +
    + Load: +
    +
    + {{:data.powerDraw}} W +
    +
    + +
    +
    + Cell Charge: +
    +
    + {{:helper.displayBar(data.cellCharge, 0, data.cellMaxCharge)}} +
    +
    + +

    Holding Tank Status

    +{{if data.hasHoldingTank}} +
    +
    + Tank Label: +
    +
    +
    {{:data.holdingTank.name}}
    {{:helper.link('Eject', 'eject', {'remove_tank' : 1})}} +
    +
    q + +
    +
    + Tank Pressure: +
    +
    + {{:data.holdingTank.tankPressure}} kPa +
    +
    +{{else}} +
    No holding tank inserted.
    +
     
    +{{/if}} + + +

    Power Regulator Status

    +
    +
    + Volume Rate: +
    +
    + {{:helper.displayBar(data.rate, data.minrate, data.maxrate)}} +
    + {{:helper.link('-', null, {'volume_adj' : -1000}, (data.rate > data.minrate) ? null : 'disabled')}} + {{:helper.link('-', null, {'volume_adj' : -100}, (data.rate > data.minrate) ? null : 'disabled')}} + {{:helper.link('-', null, {'volume_adj' : -10}, (data.rate > data.minrate) ? null : 'disabled')}} + {{:helper.link('-', null, {'volume_adj' : -1}, (data.rate > data.minrate) ? null : 'disabled')}} +
     {{:data.rate}} L/s 
    + {{:helper.link('+', null, {'volume_adj' : 1}, (data.rate < data.maxrate) ? null : 'disabled')}} + {{:helper.link('+', null, {'volume_adj' : 10}, (data.rate < data.maxrate) ? null : 'disabled')}} + {{:helper.link('+', null, {'volume_adj' : 100}, (data.rate < data.maxrate) ? null : 'disabled')}} + {{:helper.link('+', null, {'volume_adj' : 1000}, (data.rate < data.maxrate) ? null : 'disabled')}} +
    +
    +
    + +
    +
    + Power Switch: +
    +
    + {{:helper.link('On', 'unlocked', {'power' : 1}, data.on ? 'selected' : null)}} {{:helper.link('Off', 'locked', {'power' : 1}, data.on ? null : 'selected')}} +
    +
    diff --git a/nano/templates/shuttle_control_console_antag.tmpl b/nano/templates/shuttle_control_console_antag.tmpl index 57214b5d8cea..28aa38c82888 100644 --- a/nano/templates/shuttle_control_console_antag.tmpl +++ b/nano/templates/shuttle_control_console_antag.tmpl @@ -1,94 +1,94 @@ -

    Shuttle Status

    -
    -
    - {{:data.shuttle_status}} -
    -
    - Cloaking field is {{ cloaked? "enabled" : "disabled" }}. {{:helper.link('Toggle', 'arrowreturn-1-s', {'toggle_cloaked' : '1'} }} -
    -
    -
    -
    -
    - Drive: -
    -
    - {{if data.shuttle_state == "idle"}} - IDLE - {{else data.shuttle_state == "warmup"}} - SPINNING UP - {{else data.shuttle_state == "in_transit"}} - ENGAGED - {{else}} - ERROR - {{/if}} -
    -
    -
    -
    -
    - ETA: -
    -
    - {{if data.shuttle_state == "warmup"}} - CALIBRATING - {{else data.shuttle_state == "in_transit"}} - {{if data.timeleft > 0}} - {{:data.timeleft}} s - {{else}} - IMMINENT - {{/if}} - {{else}} - NONE - {{/if}} -
    -
    -{{if data.has_docking}} -
    -
    -
    - Docking Status: -
    -
    - {{if data.docking_status == "docked"}} - DOCKED - {{else data.docking_status == "docking"}} - {{if !data.docking_override}} - DOCKING - {{else}} - DOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocking"}} - {{if !data.docking_override}} - UNDOCKING - {{else}} - UNDOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocked"}} - UNDOCKED - {{else}} - ERROR - {{/if}} -
    -
    -
    -{{/if}} -
    -
    - Current Destination: -
    - {{:data.destination_name}} -
    - {{:helper.link('Choose Destination', 'arrowreturn-1-s', {'pick' : '1'}, data.can_pick ? null : 'disabled' , null)}} -
    -
    -

    Shuttle Control

    -
    -
    -
    - {{:helper.link('Launch Shuttle', 'arrowthickstop-1-e', {'move' : '1'}, data.can_launch ? null : 'disabled' , null)}} - {{:helper.link('Cancel Launch', 'cancel', {'cancel' : '1'}, data.can_cancel ? null : 'disabled' , null)}} - {{:helper.link('Force Launch', 'alert', {'force' : '1'}, data.can_force ? null : 'disabled' , data.can_force ? 'redButton' : null)}} -
    -
    +

    Shuttle Status

    +
    +
    + {{:data.shuttle_status}} +
    +
    + Cloaking field is {{ cloaked? "enabled" : "disabled" }}. {{:helper.link('Toggle', 'arrowreturn-1-s', {'toggle_cloaked' : '1'} }} +
    +
    +
    +
    +
    + Drive: +
    +
    + {{if data.shuttle_state == "idle"}} + IDLE + {{else data.shuttle_state == "warmup"}} + SPINNING UP + {{else data.shuttle_state == "in_transit"}} + ENGAGED + {{else}} + ERROR + {{/if}} +
    +
    +
    +
    +
    + ETA: +
    +
    + {{if data.shuttle_state == "warmup"}} + CALIBRATING + {{else data.shuttle_state == "in_transit"}} + {{if data.timeleft > 0}} + {{:data.timeleft}} s + {{else}} + IMMINENT + {{/if}} + {{else}} + NONE + {{/if}} +
    +
    +{{if data.has_docking}} +
    +
    +
    + Docking Status: +
    +
    + {{if data.docking_status == "docked"}} + DOCKED + {{else data.docking_status == "docking"}} + {{if !data.docking_override}} + DOCKING + {{else}} + DOCKING-MANUAL + {{/if}} + {{else data.docking_status == "undocking"}} + {{if !data.docking_override}} + UNDOCKING + {{else}} + UNDOCKING-MANUAL + {{/if}} + {{else data.docking_status == "undocked"}} + UNDOCKED + {{else}} + ERROR + {{/if}} +
    +
    +
    +{{/if}} +
    +
    + Current Destination: +
    + {{:data.destination_name}} +
    + {{:helper.link('Choose Destination', 'arrowreturn-1-s', {'pick' : '1'}, data.can_pick ? null : 'disabled' , null)}} +
    +
    +

    Shuttle Control

    +
    +
    +
    + {{:helper.link('Launch Shuttle', 'arrowthickstop-1-e', {'move' : '1'}, data.can_launch ? null : 'disabled' , null)}} + {{:helper.link('Cancel Launch', 'cancel', {'cancel' : '1'}, data.can_cancel ? null : 'disabled' , null)}} + {{:helper.link('Force Launch', 'alert', {'force' : '1'}, data.can_force ? null : 'disabled' , data.can_force ? 'redButton' : null)}} +
    +
    \ No newline at end of file diff --git a/nano/templates/shuttle_control_console_multi.tmpl b/nano/templates/shuttle_control_console_multi.tmpl index aac27d274a69..f1de01362def 100644 --- a/nano/templates/shuttle_control_console_multi.tmpl +++ b/nano/templates/shuttle_control_console_multi.tmpl @@ -1,97 +1,97 @@ -

    Shuttle Status

    -
    -
    - {{:data.shuttle_status}} -
    -
    -
    -
    -
    - Drive: -
    -
    - {{if data.shuttle_state == "idle"}} - IDLE - {{else data.shuttle_state == "warmup"}} - SPINNING UP - {{else data.shuttle_state == "in_transit"}} - ENGAGED - {{else}} - ERROR - {{/if}} -
    -
    -
    -
    -
    - ETA: -
    -
    - {{if data.shuttle_state == "warmup"}} - CALIBRATING - {{else data.shuttle_state == "in_transit"}} - {{if data.timeleft > 0}} - {{:data.timeleft}} s - {{else}} - IMMINENT - {{/if}} - {{else}} - NONE - {{/if}} -
    -
    -{{if data.has_docking}} -
    -
    -
    - Docking Status: -
    -
    - {{if data.docking_status == "docked"}} - DOCKED - {{else data.docking_status == "docking"}} - {{if !data.docking_override}} - DOCKING - {{else}} - DOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocking"}} - {{if !data.docking_override}} - UNDOCKING - {{else}} - UNDOCKING-MANUAL - {{/if}} - {{else data.docking_status == "undocked"}} - UNDOCKED - {{else}} - ERROR - {{/if}} -
    -
    - Docking Codes: -
    -
    - {{:helper.link(data.docking_codes ? data.docking_codes : 'Not set', null, {'set_codes' : '1'}, null , null)}} -
    -
    -
    -{{/if}} -
    -
    - Current Destination: -
    - {{:data.destination_name}} -
    - {{:helper.link('Choose Destination', 'arrowreturn-1-s', {'pick' : '1'}, data.can_pick ? null : 'disabled' , null)}} -
    -
    -

    Shuttle Control

    -
    -
    -
    - {{:helper.link('Launch Shuttle', 'arrowthickstop-1-e', {'move' : '1'}, data.can_launch ? null : 'disabled' , null)}} - {{:helper.link('Cancel Launch', 'cancel', {'cancel' : '1'}, data.can_cancel ? null : 'disabled' , null)}} - {{:helper.link('Force Launch', 'alert', {'force' : '1'}, data.can_force ? null : 'disabled' , data.can_force ? 'redButton' : null)}} -
    -
    +

    Shuttle Status

    +
    +
    + {{:data.shuttle_status}} +
    +
    +
    +
    +
    + Drive: +
    +
    + {{if data.shuttle_state == "idle"}} + IDLE + {{else data.shuttle_state == "warmup"}} + SPINNING UP + {{else data.shuttle_state == "in_transit"}} + ENGAGED + {{else}} + ERROR + {{/if}} +
    +
    +
    +
    +
    + ETA: +
    +
    + {{if data.shuttle_state == "warmup"}} + CALIBRATING + {{else data.shuttle_state == "in_transit"}} + {{if data.timeleft > 0}} + {{:data.timeleft}} s + {{else}} + IMMINENT + {{/if}} + {{else}} + NONE + {{/if}} +
    +
    +{{if data.has_docking}} +
    +
    +
    + Docking Status: +
    +
    + {{if data.docking_status == "docked"}} + DOCKED + {{else data.docking_status == "docking"}} + {{if !data.docking_override}} + DOCKING + {{else}} + DOCKING-MANUAL + {{/if}} + {{else data.docking_status == "undocking"}} + {{if !data.docking_override}} + UNDOCKING + {{else}} + UNDOCKING-MANUAL + {{/if}} + {{else data.docking_status == "undocked"}} + UNDOCKED + {{else}} + ERROR + {{/if}} +
    +
    + Docking Codes: +
    +
    + {{:helper.link(data.docking_codes ? data.docking_codes : 'Not set', null, {'set_codes' : '1'}, null , null)}} +
    +
    +
    +{{/if}} +
    +
    + Current Destination: +
    + {{:data.destination_name}} +
    + {{:helper.link('Choose Destination', 'arrowreturn-1-s', {'pick' : '1'}, data.can_pick ? null : 'disabled' , null)}} +
    +
    +

    Shuttle Control

    +
    +
    +
    + {{:helper.link('Launch Shuttle', 'arrowthickstop-1-e', {'move' : '1'}, data.can_launch ? null : 'disabled' , null)}} + {{:helper.link('Cancel Launch', 'cancel', {'cancel' : '1'}, data.can_cancel ? null : 'disabled' , null)}} + {{:helper.link('Force Launch', 'alert', {'force' : '1'}, data.can_force ? null : 'disabled' , data.can_force ? 'redButton' : null)}} +
    +
    \ No newline at end of file diff --git a/nano/templates/turret.tmpl b/nano/templates/turret.tmpl index 476e203090c0..a2f2d4ab0e8c 100644 --- a/nano/templates/turret.tmpl +++ b/nano/templates/turret.tmpl @@ -1,88 +1,88 @@ -
    - {{if data.network}} -
    -
    {{:helper.link("Network Settings", null, { "settings" : 1 })}}
    -
    -
    - {{/if}} -

    Power System

    -
    -
    - Power: -
    -
    - {{:helper.link('On', 'power', {'set_enabled' : 1}, data.enabled ? 'selected' : null)}} - {{:helper.link('Off', 'close', {'set_enabled' : 0}, data.enabled ? null : 'selected')}} -
    -
    -

    Weapon System

    -
    -
    - Installed Weapon: -
    -
    - {{if data.weaponName == null}} -
    - No weapon detected! -
    - {{else}} - {{:helper.link(data.weaponName, 'alert', {'eject_gun' : 1})}} - {{/if}} -
    -
    - {{if data.firemodes}} -
    -
    - Fire modes: -
    -
    - {{for data.firemodes}} - {{:helper.link(value.name, null, {'switch_firemode' : value.index}, value.selected ? 'selected' : null)}} - {{/for}} -
    -
    - {{/if}} -

    Targeting Settings

    - {{for data.settings}} -
    -
    - {{:value.category}} -
    -
    - {{:helper.link('On', null, {'targeting_comm' : value.setting, 'targeting_value' : 1}, value.value ? 'selected' : null)}} - {{:helper.link('Off',null, {'targeting_comm' : value.setting, 'targeting_value' : 0}, !value.value ? 'selected' : null)}} -
    -
    - {{/for}} -

    Manual Control

    -
    -
    - Bearing: -
    -
    - {{:helper.link('-10°', 'triangle-1-w', {'adjust_bearing' : -10})}} - {{:helper.link('-5°', 'triangle-1-w', {'adjust_bearing' : -5})}} - {{:helper.link(data.currentBearing+'°', null, {'set_bearing' : 1})}} - {{:helper.link('+5°', 'triangle-1-e', {'adjust_bearing' : 5})}} - {{:helper.link('+10°', 'triangle-1-e', {'adjust_bearing' : 10})}} -
    -
    -
    -
    - Default Bearing: -
    -
    - {{:helper.link(data.defaultBearing+'°', null, {'set_default' : 1})}} -
    -
    -
    -
    - Control: -
    -
    - {{:helper.link('Manual Fire', 'alert', {'manual_fire' : 1}, null, data.weaponName ? 'redButton' : 'disabled')}} -
    -
    -
    - - +
    + {{if data.network}} +
    +
    {{:helper.link("Network Settings", null, { "settings" : 1 })}}
    +
    +
    + {{/if}} +

    Power System

    +
    +
    + Power: +
    +
    + {{:helper.link('On', 'power', {'set_enabled' : 1}, data.enabled ? 'selected' : null)}} + {{:helper.link('Off', 'close', {'set_enabled' : 0}, data.enabled ? null : 'selected')}} +
    +
    +

    Weapon System

    +
    +
    + Installed Weapon: +
    +
    + {{if data.weaponName == null}} +
    + No weapon detected! +
    + {{else}} + {{:helper.link(data.weaponName, 'alert', {'eject_gun' : 1})}} + {{/if}} +
    +
    + {{if data.firemodes}} +
    +
    + Fire modes: +
    +
    + {{for data.firemodes}} + {{:helper.link(value.name, null, {'switch_firemode' : value.index}, value.selected ? 'selected' : null)}} + {{/for}} +
    +
    + {{/if}} +

    Targeting Settings

    + {{for data.settings}} +
    +
    + {{:value.category}} +
    +
    + {{:helper.link('On', null, {'targeting_comm' : value.setting, 'targeting_value' : 1}, value.value ? 'selected' : null)}} + {{:helper.link('Off',null, {'targeting_comm' : value.setting, 'targeting_value' : 0}, !value.value ? 'selected' : null)}} +
    +
    + {{/for}} +

    Manual Control

    +
    +
    + Bearing: +
    +
    + {{:helper.link('-10°', 'triangle-1-w', {'adjust_bearing' : -10})}} + {{:helper.link('-5°', 'triangle-1-w', {'adjust_bearing' : -5})}} + {{:helper.link(data.currentBearing+'°', null, {'set_bearing' : 1})}} + {{:helper.link('+5°', 'triangle-1-e', {'adjust_bearing' : 5})}} + {{:helper.link('+10°', 'triangle-1-e', {'adjust_bearing' : 10})}} +
    +
    +
    +
    + Default Bearing: +
    +
    + {{:helper.link(data.defaultBearing+'°', null, {'set_default' : 1})}} +
    +
    +
    +
    + Control: +
    +
    + {{:helper.link('Manual Fire', 'alert', {'manual_fire' : 1}, null, data.weaponName ? 'redButton' : 'disabled')}} +
    +
    +
    + + diff --git a/nano/templates/turret_control.tmpl b/nano/templates/turret_control.tmpl index a529bcbb108f..944f4a73d3fe 100644 --- a/nano/templates/turret_control.tmpl +++ b/nano/templates/turret_control.tmpl @@ -1,41 +1,41 @@ -
    -
    - Behaviour controls are {{:data.locked ? "locked" : "unlocked"}}. -
    -
    -
    -{{if data.access}} -
    -
    - Turret Status: -
    -
    - {{:helper.link('Enabled', null, {'command' : 'enable', 'value' : 1}, data.enabled ?'redButton' : null)}} - {{:helper.link('Disabled',null, {'command' : 'enable', 'value' : 0}, !data.enabled ? 'selected' : null)}} -
    -
    - - {{if data.is_lethal}} -
    -
    - Lethal Mode: -
    -
    - {{:helper.link('On', null, {'command' : 'lethal', 'value' : 1}, data.lethal ?'redButton' : null)}} - {{:helper.link('Off',null, {'command' : 'lethal', 'value' : 0}, !data.lethal ? 'selected' : null)}} -
    -
    - {{/if}} - - {{for data.settings}} -
    -
    - {{:value.category}} -
    -
    - {{:helper.link('On', null, {'command' : value.setting, 'value' : 1}, value.value ? 'selected' : null)}} - {{:helper.link('Off',null, {'command' : value.setting, 'value' : 0}, !value.value ? 'selected' : null)}} -
    -
    - {{/for}} -{{/if}} +
    +
    + Behaviour controls are {{:data.locked ? "locked" : "unlocked"}}. +
    +
    +
    +{{if data.access}} +
    +
    + Turret Status: +
    +
    + {{:helper.link('Enabled', null, {'command' : 'enable', 'value' : 1}, data.enabled ?'redButton' : null)}} + {{:helper.link('Disabled',null, {'command' : 'enable', 'value' : 0}, !data.enabled ? 'selected' : null)}} +
    +
    + + {{if data.is_lethal}} +
    +
    + Lethal Mode: +
    +
    + {{:helper.link('On', null, {'command' : 'lethal', 'value' : 1}, data.lethal ?'redButton' : null)}} + {{:helper.link('Off',null, {'command' : 'lethal', 'value' : 0}, !data.lethal ? 'selected' : null)}} +
    +
    + {{/if}} + + {{for data.settings}} +
    +
    + {{:value.category}} +
    +
    + {{:helper.link('On', null, {'command' : value.setting, 'value' : 1}, value.value ? 'selected' : null)}} + {{:helper.link('Off',null, {'command' : value.setting, 'value' : 0}, !value.value ? 'selected' : null)}} +
    +
    + {{/for}} +{{/if}} diff --git a/nano/templates/uplink.tmpl b/nano/templates/uplink.tmpl index c01d79dc9a30..ce47818e2af9 100644 --- a/nano/templates/uplink.tmpl +++ b/nano/templates/uplink.tmpl @@ -1,89 +1,89 @@ - - -{{:helper.syndicateMode()}} -

    {{:data.welcome}}

    -
    -
    -
    - Functions: -
    -
    - {{:helper.link('Request Items', 'gear', {'menu' : 0}, null, 'fixedLeftWider')}} - {{:helper.link('Exploitable Information', 'gear', {'menu' : 2}, null, 'fixedLeftWider')}} - {{:helper.link('Return', 'arrowreturn-1-w', {'return' : 1}, null, 'fixedLeft')}} - {{:helper.link('Close', 'gear', {'lock' : "1"}, null, 'fixedLeft')}} -
    -
    -
    - -{{if data.menu == 0 || data.menu == 1}} -
    -
    - Telecrystals: -
    -
    - {{:data.crystals}} -
    -
    - - {{if data.discount_amount < 100}} -
    -
    - Currently discounted: -
    -
    - {{:data.discount_category}}
    {{:data.discount_name}}
    {{:data.discount_amount}}% off. Offer will expire at: {{:data.offer_expiry}} -
    -
    - {{/if}} -{{/if}} - -{{if data.menu == 0}} -

    Categories:

    - {{for data.categories}} -
    - {{:helper.link(value.name, 'gear', {'menu' : 1, 'category' : value.ref})}} -
    - {{/for}} -{{else data.menu == 1}} -

    Request items:

    - Each item costs a number of tele-crystals as indicated by the number following their name. - - {{for data.items}} -
    - {{:helper.link(value.name, 'gear', {'buy_item' : value.ref}, value.can_buy ? null : 'disabled')}} - {{:value.cost}} -
    -
    - {{:value.description}} -
    - {{/for}} -{{else data.menu == 2}} -

    Information Record List:

    -
    -
    - Select a Record -
    -
    - {{for data.exploit_records}} -
    - {{:helper.link(value.Name, value.exploit ? 'gear' : 'document', {'menu' : 21, 'id' : value.id}, null, value.exploit ? 'redButton' : null)}} -
    - {{/for}} -{{else data.menu == 21}} -

    Information Record:

    -
    -
    -
    -
    - {{if data.exploit_exists == 1}} - {{for data.exploit.fields}} - {{:value.name}}: {{:value.value}}
    - {{/for}} - {{/if}} -
    -
    -
    -{{/if}} + + +{{:helper.syndicateMode()}} +

    {{:data.welcome}}

    +
    +
    +
    + Functions: +
    +
    + {{:helper.link('Request Items', 'gear', {'menu' : 0}, null, 'fixedLeftWider')}} + {{:helper.link('Exploitable Information', 'gear', {'menu' : 2}, null, 'fixedLeftWider')}} + {{:helper.link('Return', 'arrowreturn-1-w', {'return' : 1}, null, 'fixedLeft')}} + {{:helper.link('Close', 'gear', {'lock' : "1"}, null, 'fixedLeft')}} +
    +
    +
    + +{{if data.menu == 0 || data.menu == 1}} +
    +
    + Telecrystals: +
    +
    + {{:data.crystals}} +
    +
    + + {{if data.discount_amount < 100}} +
    +
    + Currently discounted: +
    +
    + {{:data.discount_category}}
    {{:data.discount_name}}
    {{:data.discount_amount}}% off. Offer will expire at: {{:data.offer_expiry}} +
    +
    + {{/if}} +{{/if}} + +{{if data.menu == 0}} +

    Categories:

    + {{for data.categories}} +
    + {{:helper.link(value.name, 'gear', {'menu' : 1, 'category' : value.ref})}} +
    + {{/for}} +{{else data.menu == 1}} +

    Request items:

    + Each item costs a number of tele-crystals as indicated by the number following their name. + + {{for data.items}} +
    + {{:helper.link(value.name, 'gear', {'buy_item' : value.ref}, value.can_buy ? null : 'disabled')}} - {{:value.cost}} +
    +
    + {{:value.description}} +
    + {{/for}} +{{else data.menu == 2}} +

    Information Record List:

    +
    +
    + Select a Record +
    +
    + {{for data.exploit_records}} +
    + {{:helper.link(value.Name, value.exploit ? 'gear' : 'document', {'menu' : 21, 'id' : value.id}, null, value.exploit ? 'redButton' : null)}} +
    + {{/for}} +{{else data.menu == 21}} +

    Information Record:

    +
    +
    +
    +
    + {{if data.exploit_exists == 1}} + {{for data.exploit.fields}} + {{:value.name}}: {{:value.value}}
    + {{/for}} + {{/if}} +
    +
    +
    +{{/if}} diff --git a/tools/TagMatcher/checkTagMatches.bat b/tools/TagMatcher/checkTagMatches.bat index 191c30bbba4c..2e53f85782db 100644 --- a/tools/TagMatcher/checkTagMatches.bat +++ b/tools/TagMatcher/checkTagMatches.bat @@ -1,3 +1,3 @@ -@echo off -call python tag-matcher.py ../.. -pause +@echo off +call python tag-matcher.py ../.. +pause diff --git a/tools/TagMatcher/tag-matcher.py b/tools/TagMatcher/tag-matcher.py index a9864d7605f3..a8e6a1322980 100644 --- a/tools/TagMatcher/tag-matcher.py +++ b/tools/TagMatcher/tag-matcher.py @@ -1,120 +1,120 @@ -''' -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. -''' -import argparse, re, sys -from collections import defaultdict -from os import path, walk - -opt = argparse.ArgumentParser() -opt.add_argument('dir', help='The directory to scan for *.dm files with non-matching spans') -args = opt.parse_args() - -if(not path.isdir(args.dir)): - print('Not a directory') - sys.exit(1) - -# These tuples are expected to be ordered as: -# A unique human readable name (henceforth referred to as tuple name), a regex pattern matching an opening tag, a regex pattern matching a closing tag -tag_tuples = [ ('', re.compile('', re.IGNORECASE), re.compile('', re.IGNORECASE)), - ('', re.compile('', re.IGNORECASE), re.compile('', re.IGNORECASE)), - ('
    ', re.compile('
    ', re.IGNORECASE), re.compile('
    ', re.IGNORECASE)), - ('', re.compile('', re.IGNORECASE), re.compile('', re.IGNORECASE)), - ('', re.compile('', re.IGNORECASE), re.compile('', re.IGNORECASE))] - -# The keys of this dictionary will be the file path of each parsed *.dm file -# The values of this dictionary is a another dictionary with the key/value pair: tag/list of unmatched lines -mismatches_by_file = { } - -# Loops over all defined tag tuples and returns a dictionary with the key/value pair: tag/mismatch_count (positive means excess of opening tag, negative means excess of closing tags) -def get_tag_matches(line): - mismatch_count_by_tag = { } - for tag_tuple in tag_tuples: - mismatch_count = 0 - mismatch_count += len(tag_tuple[1].findall(line)) - mismatch_count -= len(tag_tuple[2].findall(line)) - if mismatch_count != 0: - mismatch_count_by_tag[tag_tuple[0]] = mismatch_count - return mismatch_count_by_tag - -# Support def that simply checks if a given dictionary in the format tag/list of unmatched lines has mismatch entries. -def has_mismatch(match_list): - for tag, list_of_mismatched_lines in match_list.items(): - if(len(list_of_mismatched_lines) > 0): - return 1 - return 0 - -def arrange_mismatches(mismatches_by_tag, mismatch_line, mismatch_counts): - for tag, mismatch_count in mismatch_counts.items(): - stack_of_existing_mismatches = mismatches_by_tag[tag] - for i in range(0, abs(mismatch_count)): - if len(stack_of_existing_mismatches) == 0: - if(mismatch_count > 0): - stack_of_existing_mismatches.append(mismatch_line) - else: - stack_of_existing_mismatches.append(-mismatch_line) - else: - if stack_of_existing_mismatches[0] > 0: - if mismatch_count > 0: - stack_of_existing_mismatches.append(mismatch_line) - else: - stack_of_existing_mismatches.pop() - else: - if mismatch_count < 0: - stack_of_existing_mismatches.append(-mismatch_line) - else: - stack_of_existing_mismatches.pop() - - -# This section parses all *.dm files in the given directory, recursively. -for root, subdirs, files in walk(args.dir): - for filename in files: - if filename.endswith('.dm'): - file_path = path.join(root, filename) - with open(file_path, 'r', encoding="latin-1") as file: - mismatches_by_file[file_path] = defaultdict(list) - for line_number, line in enumerate(file, 1): - # Then for each line in the file, conduct the tuple open/close matching. - mismatches_by_tag = get_tag_matches(line) - arrange_mismatches(mismatches_by_file[file_path], line_number, mismatches_by_tag) - -# Pretty printing section. -# Loops over all matches and checks if there is a mismatch of tags. -# If so, then and only then is the corresponding file path printed along with the number of unmatched open/close tags. -total_mismatches = 0 -for file, mismatches_by_tag in mismatches_by_file.items(): - if has_mismatch(mismatches_by_tag): - print(file) - for tag, mismatch_list in mismatches_by_tag.items(): - # A positive number means an excess of opening tag, a negative number means an excess of closing tags. - total_mismatches += len(mismatch_list) - if len(mismatch_list) > 0: - if mismatch_list[0] > 0: - print('\t{0} - Excess of {1} opening tag(s)'.format(tag, len(mismatch_list))) - elif mismatch_list[0] < 0: - print('\t{0} - Excess of {1} closing tag(s)'.format(tag, len(mismatch_list))) - for mismatch_line in sorted(set(mismatch_list)): - print('\t\tLine {0}'.format(abs(mismatch_line))) - -# Simply prints the total number of mismatches found and if so returns 1 to, for example, fail unit testing. -if(total_mismatches == 0): - print('No mismatches found.') -else: - print('') - print('Total number of mismatches: {0}'.format(total_mismatches)) - sys.exit(1) +''' +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. +''' +import argparse, re, sys +from collections import defaultdict +from os import path, walk + +opt = argparse.ArgumentParser() +opt.add_argument('dir', help='The directory to scan for *.dm files with non-matching spans') +args = opt.parse_args() + +if(not path.isdir(args.dir)): + print('Not a directory') + sys.exit(1) + +# These tuples are expected to be ordered as: +# A unique human readable name (henceforth referred to as tuple name), a regex pattern matching an opening tag, a regex pattern matching a closing tag +tag_tuples = [ ('', re.compile('', re.IGNORECASE), re.compile('', re.IGNORECASE)), + ('', re.compile('', re.IGNORECASE), re.compile('', re.IGNORECASE)), + ('
    ', re.compile('
    ', re.IGNORECASE), re.compile('
    ', re.IGNORECASE)), + ('', re.compile('', re.IGNORECASE), re.compile('', re.IGNORECASE)), + ('', re.compile('', re.IGNORECASE), re.compile('', re.IGNORECASE))] + +# The keys of this dictionary will be the file path of each parsed *.dm file +# The values of this dictionary is a another dictionary with the key/value pair: tag/list of unmatched lines +mismatches_by_file = { } + +# Loops over all defined tag tuples and returns a dictionary with the key/value pair: tag/mismatch_count (positive means excess of opening tag, negative means excess of closing tags) +def get_tag_matches(line): + mismatch_count_by_tag = { } + for tag_tuple in tag_tuples: + mismatch_count = 0 + mismatch_count += len(tag_tuple[1].findall(line)) + mismatch_count -= len(tag_tuple[2].findall(line)) + if mismatch_count != 0: + mismatch_count_by_tag[tag_tuple[0]] = mismatch_count + return mismatch_count_by_tag + +# Support def that simply checks if a given dictionary in the format tag/list of unmatched lines has mismatch entries. +def has_mismatch(match_list): + for tag, list_of_mismatched_lines in match_list.items(): + if(len(list_of_mismatched_lines) > 0): + return 1 + return 0 + +def arrange_mismatches(mismatches_by_tag, mismatch_line, mismatch_counts): + for tag, mismatch_count in mismatch_counts.items(): + stack_of_existing_mismatches = mismatches_by_tag[tag] + for i in range(0, abs(mismatch_count)): + if len(stack_of_existing_mismatches) == 0: + if(mismatch_count > 0): + stack_of_existing_mismatches.append(mismatch_line) + else: + stack_of_existing_mismatches.append(-mismatch_line) + else: + if stack_of_existing_mismatches[0] > 0: + if mismatch_count > 0: + stack_of_existing_mismatches.append(mismatch_line) + else: + stack_of_existing_mismatches.pop() + else: + if mismatch_count < 0: + stack_of_existing_mismatches.append(-mismatch_line) + else: + stack_of_existing_mismatches.pop() + + +# This section parses all *.dm files in the given directory, recursively. +for root, subdirs, files in walk(args.dir): + for filename in files: + if filename.endswith('.dm'): + file_path = path.join(root, filename) + with open(file_path, 'r', encoding="latin-1") as file: + mismatches_by_file[file_path] = defaultdict(list) + for line_number, line in enumerate(file, 1): + # Then for each line in the file, conduct the tuple open/close matching. + mismatches_by_tag = get_tag_matches(line) + arrange_mismatches(mismatches_by_file[file_path], line_number, mismatches_by_tag) + +# Pretty printing section. +# Loops over all matches and checks if there is a mismatch of tags. +# If so, then and only then is the corresponding file path printed along with the number of unmatched open/close tags. +total_mismatches = 0 +for file, mismatches_by_tag in mismatches_by_file.items(): + if has_mismatch(mismatches_by_tag): + print(file) + for tag, mismatch_list in mismatches_by_tag.items(): + # A positive number means an excess of opening tag, a negative number means an excess of closing tags. + total_mismatches += len(mismatch_list) + if len(mismatch_list) > 0: + if mismatch_list[0] > 0: + print('\t{0} - Excess of {1} opening tag(s)'.format(tag, len(mismatch_list))) + elif mismatch_list[0] < 0: + print('\t{0} - Excess of {1} closing tag(s)'.format(tag, len(mismatch_list))) + for mismatch_line in sorted(set(mismatch_list)): + print('\t\tLine {0}'.format(abs(mismatch_line))) + +# Simply prints the total number of mismatches found and if so returns 1 to, for example, fail unit testing. +if(total_mismatches == 0): + print('No mismatches found.') +else: + print('') + print('Total number of mismatches: {0}'.format(total_mismatches)) + sys.exit(1) diff --git a/tools/dmitool/git_merge_installer.bat b/tools/dmitool/git_merge_installer.bat index 18ab7c8026ab..c7ba2fa23a14 100644 --- a/tools/dmitool/git_merge_installer.bat +++ b/tools/dmitool/git_merge_installer.bat @@ -1,6 +1,6 @@ -@echo off -set tab= -echo. >> ../../.git/config -echo [merge "merge-dmi"] >> ../../.git/config -echo %tab%name = iconfile merge driver >> ../../.git/config -echo %tab%driver = ./tools/dmitool/dmimerge.sh %%O %%A %%B >> ../../.git/config +@echo off +set tab= +echo. >> ../../.git/config +echo [merge "merge-dmi"] >> ../../.git/config +echo %tab%name = iconfile merge driver >> ../../.git/config +echo %tab%driver = ./tools/dmitool/dmimerge.sh %%O %%A %%B >> ../../.git/config diff --git a/tools/expand_filedir_paths.py b/tools/expand_filedir_paths.py index d5a3d8d3f3a0..b58a8679398c 100644 --- a/tools/expand_filedir_paths.py +++ b/tools/expand_filedir_paths.py @@ -1,93 +1,93 @@ -#!/usr/bin/env python - -import re, os, sys, fnmatch - - -# Regex pattern to extract the directory path in a #define FILE_DIR -filedir_pattern = re.compile(r'^#define\s*FILE_DIR\s*"(.*?)"') - -# Regex pattern to extract any single quoted piece of text. This can also -# match single quoted strings inside of double quotes, which is part of a -# regular text string and should not be replaced. The replacement function -# however will any match that doesn't appear to be a filename so these -# extra matches should not be a problem. -rename_pattern = re.compile(r"'(.+?)'") - -# Only filenames matching this pattern will have their resources renamed -source_pattern = re.compile(r"^.*?\.(dm|dmm)$") - -# Open the .dme file and return a list of all FILE_DIR paths in it -def read_filedirs(filename): - result = [] - dme_file = file(filename, "rt") - - # Read each line from the file and check for regex pattern match - for row in dme_file: - match = filedir_pattern.match(row) - if match: - result.append(match.group(1)) - - dme_file.close() - return result - -# Search through a list of directories, and build a dictionary which -# maps every file to its full pathname (relative to the .dme file) -# If the same filename appears in more than one directory, the earlier -# directory in the list takes preference. -def index_files(file_dirs): - result = {} - - # Reverse the directory list so the earlier directories take precedence - # by replacing the previously indexed file of the same name - for directory in reversed(file_dirs): - for name in os.listdir(directory): - # Replace backslash path separators on Windows with forward slash - # Force "name" to lowercase when used as a key since BYOND resource - # names are case insensitive, even on Linux. - if name.find(".") == -1: - continue - result[name.lower()] = directory.replace('\\', '/') + '/' + name - - return result - -# Recursively search for every .dm/.dmm file in the .dme file directory. For -# each file, search it for any resource names in single quotes, and replace -# them with the full path previously found by index_files() -def rewrite_sources(resources): - # Create a closure for the regex replacement function to capture the - # resources dictionary which can't be passed directly to this function - def replace_func(name): - key = name.group(1).lower() - if key in resources: - replacement = resources[key] - else: - replacement = name.group(1) - return "'" + replacement + "'" - - # Search recursively for all .dm and .dmm files - for (dirpath, dirs, files) in os.walk("."): - for name in files: - if source_pattern.match(name): - path = dirpath + '/' + name - source_file = file(path, "rt") - output_file = file(path + ".tmp", "wt") - - # Read file one line at a time and perform replacement of all - # single quoted resource names with the fullpath to that resource - # file. Write the updated text back out to a temporary file. - for row in source_file: - row = rename_pattern.sub(replace_func, row) - output_file.write(row) - - output_file.close() - source_file.close() - - # Delete original source file and replace with the temporary - # output. On Windows, an atomic rename() operation is not - # possible like it is under POSIX. - os.remove(path) - os.rename(path + ".tmp", path) - -dirs = read_filedirs("tgstation.dme"); -resources = index_files(dirs) -rewrite_sources(resources) +#!/usr/bin/env python + +import re, os, sys, fnmatch + + +# Regex pattern to extract the directory path in a #define FILE_DIR +filedir_pattern = re.compile(r'^#define\s*FILE_DIR\s*"(.*?)"') + +# Regex pattern to extract any single quoted piece of text. This can also +# match single quoted strings inside of double quotes, which is part of a +# regular text string and should not be replaced. The replacement function +# however will any match that doesn't appear to be a filename so these +# extra matches should not be a problem. +rename_pattern = re.compile(r"'(.+?)'") + +# Only filenames matching this pattern will have their resources renamed +source_pattern = re.compile(r"^.*?\.(dm|dmm)$") + +# Open the .dme file and return a list of all FILE_DIR paths in it +def read_filedirs(filename): + result = [] + dme_file = file(filename, "rt") + + # Read each line from the file and check for regex pattern match + for row in dme_file: + match = filedir_pattern.match(row) + if match: + result.append(match.group(1)) + + dme_file.close() + return result + +# Search through a list of directories, and build a dictionary which +# maps every file to its full pathname (relative to the .dme file) +# If the same filename appears in more than one directory, the earlier +# directory in the list takes preference. +def index_files(file_dirs): + result = {} + + # Reverse the directory list so the earlier directories take precedence + # by replacing the previously indexed file of the same name + for directory in reversed(file_dirs): + for name in os.listdir(directory): + # Replace backslash path separators on Windows with forward slash + # Force "name" to lowercase when used as a key since BYOND resource + # names are case insensitive, even on Linux. + if name.find(".") == -1: + continue + result[name.lower()] = directory.replace('\\', '/') + '/' + name + + return result + +# Recursively search for every .dm/.dmm file in the .dme file directory. For +# each file, search it for any resource names in single quotes, and replace +# them with the full path previously found by index_files() +def rewrite_sources(resources): + # Create a closure for the regex replacement function to capture the + # resources dictionary which can't be passed directly to this function + def replace_func(name): + key = name.group(1).lower() + if key in resources: + replacement = resources[key] + else: + replacement = name.group(1) + return "'" + replacement + "'" + + # Search recursively for all .dm and .dmm files + for (dirpath, dirs, files) in os.walk("."): + for name in files: + if source_pattern.match(name): + path = dirpath + '/' + name + source_file = file(path, "rt") + output_file = file(path + ".tmp", "wt") + + # Read file one line at a time and perform replacement of all + # single quoted resource names with the fullpath to that resource + # file. Write the updated text back out to a temporary file. + for row in source_file: + row = rename_pattern.sub(replace_func, row) + output_file.write(row) + + output_file.close() + source_file.close() + + # Delete original source file and replace with the temporary + # output. On Windows, an atomic rename() operation is not + # possible like it is under POSIX. + os.remove(path) + os.rename(path + ".tmp", path) + +dirs = read_filedirs("tgstation.dme"); +resources = index_files(dirs) +rewrite_sources(resources) diff --git a/tools/mapcapturemerge/.gitignore b/tools/mapcapturemerge/.gitignore index 20379651e836..508577d9cb19 100644 --- a/tools/mapcapturemerge/.gitignore +++ b/tools/mapcapturemerge/.gitignore @@ -1,3 +1,3 @@ -*.png -*.pyc -captures/*.png +*.png +*.pyc +captures/*.png diff --git a/tools/mapcapturemerge/imageHelpers.py b/tools/mapcapturemerge/imageHelpers.py index b7cdb309552b..90c501021eee 100644 --- a/tools/mapcapturemerge/imageHelpers.py +++ b/tools/mapcapturemerge/imageHelpers.py @@ -1,15 +1,15 @@ -from PIL import Image -import re -reg_findnums = re.compile("[0-9]+") - -class ImageFile: - def __init__(self, filename, path): - self.filename = path - nums = reg_findnums.findall(filename) - self.cords = (int(nums[0]), int(nums[1]), int(nums[2])) - self.range = int(nums[3]) - - def getImage(self): - im = Image.open(self.filename) - im.load() - return im +from PIL import Image +import re +reg_findnums = re.compile("[0-9]+") + +class ImageFile: + def __init__(self, filename, path): + self.filename = path + nums = reg_findnums.findall(filename) + self.cords = (int(nums[0]), int(nums[1]), int(nums[2])) + self.range = int(nums[3]) + + def getImage(self): + im = Image.open(self.filename) + im.load() + return im diff --git a/tools/mapcapturemerge/merge.py b/tools/mapcapturemerge/merge.py index 66fcae967bef..02966a937162 100644 --- a/tools/mapcapturemerge/merge.py +++ b/tools/mapcapturemerge/merge.py @@ -1,41 +1,41 @@ -from PIL import Image -import os, re, imageHelpers - -def BYONDCordsToPixelCords(B, BMax): - y = (BMax[1] - B[1]) - 31 - return (B[0] * 32 - 32, y * 32 - 32) - -image_location = os.path.join(os.getcwd(), 'captures') - -print("Map capture merger by Karolis") - -capture_images = [] -capture_re = re.compile("map_capture_x[0-9]+_y[0-9]+_z[0-9]+_r32\.png") -for image_file in os.listdir(image_location): - if os.path.isfile(os.path.join(image_location, image_file)) and capture_re.match(image_file): - #print(image_file) - capture_images.append(imageHelpers.ImageFile(image_file, os.path.join(image_location, image_file))) - -max_x = 0 -max_y = 0 -z_levels = [] -captures = {} -for capture in capture_images: - max_x = max(max_x, capture.cords[0] + capture.range) - max_y = max(max_y, capture.cords[1] + capture.range) - if not capture.cords[2] in z_levels: - z_levels.append(capture.cords[2]) - captures[capture.cords[2]] = [] - captures[capture.cords[2]].append(capture) - -maxCords = (max_x, max_y) - -for z in z_levels: - print("Merging map from " + str(z) + " z level.") - map = Image.new("RGBA", ((max_x - 1) * 32, (max_y - 1) * 32)) - for capture in captures[z]: - part = capture.getImage() - map.paste(part, BYONDCordsToPixelCords(capture.cords, maxCords)) - filename = "map_z" + str(z) + ".png" - print("Saving map as: " + filename) - map.save(filename) +from PIL import Image +import os, re, imageHelpers + +def BYONDCordsToPixelCords(B, BMax): + y = (BMax[1] - B[1]) - 31 + return (B[0] * 32 - 32, y * 32 - 32) + +image_location = os.path.join(os.getcwd(), 'captures') + +print("Map capture merger by Karolis") + +capture_images = [] +capture_re = re.compile("map_capture_x[0-9]+_y[0-9]+_z[0-9]+_r32\.png") +for image_file in os.listdir(image_location): + if os.path.isfile(os.path.join(image_location, image_file)) and capture_re.match(image_file): + #print(image_file) + capture_images.append(imageHelpers.ImageFile(image_file, os.path.join(image_location, image_file))) + +max_x = 0 +max_y = 0 +z_levels = [] +captures = {} +for capture in capture_images: + max_x = max(max_x, capture.cords[0] + capture.range) + max_y = max(max_y, capture.cords[1] + capture.range) + if not capture.cords[2] in z_levels: + z_levels.append(capture.cords[2]) + captures[capture.cords[2]] = [] + captures[capture.cords[2]].append(capture) + +maxCords = (max_x, max_y) + +for z in z_levels: + print("Merging map from " + str(z) + " z level.") + map = Image.new("RGBA", ((max_x - 1) * 32, (max_y - 1) * 32)) + for capture in captures[z]: + part = capture.getImage() + map.paste(part, BYONDCordsToPixelCords(capture.cords, maxCords)) + filename = "map_z" + str(z) + ".png" + print("Saving map as: " + filename) + map.save(filename) From f9ea0f27a6a377d3f163e800e3244752618527fb Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 8 Oct 2025 21:38:12 -0400 Subject: [PATCH 33/36] Remove global military branch holder --- code/controllers/subsystems/jobs.dm | 6 +- code/controllers/verbs.dm | 3 - code/datums/mil_ranks.dm | 111 +----------------- code/game/jobs/job/_job.dm | 14 +-- code/game/movietitles.dm | 2 +- code/game/objects/items/weapons/cards_ids.dm | 4 +- .../items/weapons/cards_ids_syndicate.dm | 8 +- code/game/world.dm | 1 - .../preference_setup/loadout/loadout.dm | 2 +- .../preference_setup/occupation/occupation.dm | 39 +++--- .../occupation/skill_selection.dm | 2 +- .../mob/new_player/preferences_setup.dm | 4 +- .../modular_computers/file_system/manifest.dm | 4 +- .../file_system/reports/crew_record.dm | 6 +- .../file_system/reports/people.dm | 2 +- code/modules/submaps/submap_join.dm | 7 +- maps/~mapsystem/map_ranks.dm | 105 ++++++++++++++++- maps/~mapsystem/maps.dm | 2 + 18 files changed, 153 insertions(+), 169 deletions(-) diff --git a/code/controllers/subsystems/jobs.dm b/code/controllers/subsystems/jobs.dm index 88e40e689d9b..35519221dbfe 100644 --- a/code/controllers/subsystems/jobs.dm +++ b/code/controllers/subsystems/jobs.dm @@ -387,7 +387,7 @@ SUBSYSTEM_DEF(jobs) if(player.client.prefs.alternate_option == BE_ASSISTANT) var/datum/job/ass = global.using_map.default_job_type if((global.using_map.flags & MAP_HAS_BRANCH) && player.client.prefs.branches[initial(ass.title)]) - var/datum/mil_branch/branch = global.using_map.mil_branches.get_branch(player.client.prefs.branches[initial(ass.title)]) + var/datum/mil_branch/branch = global.using_map.get_branch(player.client.prefs.branches[initial(ass.title)]) ass = branch.assistant_job assign_role(player, initial(ass.title), mode = mode) //For ones returning to lobby @@ -475,9 +475,9 @@ SUBSYSTEM_DEF(jobs) if(job) if(H.client) if(global.using_map.flags & MAP_HAS_BRANCH) - H.char_branch = global.using_map.mil_branches.get_branch(H.client.prefs.branches[job_title]) + H.char_branch = global.using_map.get_branch(H.client.prefs.branches[job_title]) if(global.using_map.flags & MAP_HAS_RANK) - H.char_rank = global.using_map.mil_branches.get_rank(H.client.prefs.branches[job_title], H.client.prefs.ranks[job_title]) + H.char_rank = global.using_map.get_rank(H.client.prefs.branches[job_title], H.client.prefs.ranks[job_title]) // Transfers the skill settings for the job to the mob H.skillset.obtain_from_client(job, H.client) diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index 7bdb23ec96af..f9f58592fe19 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -34,8 +34,5 @@ if("Alt Appearance Manager") debug_variables(GET_DECL(/decl/appearance_manager)) SSstatistics.add_field_details("admin_verb", "DAltAppearanceManager") - if("Military Branches") - debug_variables(mil_branches) - SSstatistics.add_field_details("admin_verb", "DMilBranches") message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.") return diff --git a/code/datums/mil_ranks.dm b/code/datums/mil_ranks.dm index e0aa19bc4811..29a14bc5e985 100644 --- a/code/datums/mil_ranks.dm +++ b/code/datums/mil_ranks.dm @@ -2,93 +2,14 @@ * Datums for military branches and ranks * * Map datums can optionally specify a list of /datum/mil_branch paths. These paths - * are used to initialize the global mil_branches object, which contains a list of - * branch objects the map uses. Each branch definition specifies a list of + * are used to initialize ranks for the map, which contains a list of + * branch objects used on the map. Each branch definition specifies a list of * /datum/mil_rank paths, which are ranks available to that branch. * * Which branches and ranks can be selected for spawning is specifed in global.using_map * and each branch datum definition, respectively. */ -/** - * Global object for handling branches - */ -/datum/mil_branches - /// All branches that exist - var/list/branches = list() - /// Branches that a player can choose for spawning, not including species restrictions. - var/list/spawn_branches_ = list() - /// Branches that a player can choose for spawning, with species restrictions. Populated on a needed basis - var/list/spawn_branches_by_species_ = list() - -/** - * Retrieve branch object by branch name - */ -/datum/mil_branches/proc/get_branch(var/branch_name) - if(ispath(branch_name, /datum/mil_branch)) - var/datum/mil_branch/branch = branch_name - branch_name = initial(branch.name) - if(branch_name && branch_name != "None") - return branches[branch_name] - -/** - * Retrieve branch object by branch type - */ -/datum/mil_branches/proc/get_branch_by_type(var/branch_type) - for(var/name in branches) - if (istype(branches[name], branch_type)) - return branches[name] - -/** - * Retrieve a rank object from given branch by name - */ -/datum/mil_branches/proc/get_rank(var/branch_name, var/rank_name) - if(ispath(rank_name)) - var/datum/mil_rank/rank = rank_name - rank_name = initial(rank.name) - if(rank_name && rank_name != "None") - var/datum/mil_branch/branch = get_branch(branch_name) - if(branch) - return branch.ranks[rank_name] - -/** - * Return all spawn branches for the given input - */ -/datum/mil_branches/proc/spawn_branches(var/decl/species/S) - if(!S) - return spawn_branches_.Copy() - . = LAZYACCESS(spawn_branches_by_species_, S) - if(!.) - . = list() - LAZYSET(spawn_branches_by_species_, S, .) - for(var/spawn_branch in spawn_branches_) - if(!global.using_map.is_species_branch_restricted(S, spawn_branches_[spawn_branch])) - . += spawn_branch - -/** - * Return all spawn ranks for the given input - */ -/datum/mil_branches/proc/spawn_ranks(var/branch_name, var/decl/species/S) - var/datum/mil_branch/branch = get_branch(branch_name) - return branch && branch.spawn_ranks(S) - -/** - * Return a true value if branch_name is a valid spawn branch key - */ -/datum/mil_branches/proc/is_spawn_branch(var/branch_name, var/decl/species/S) - return (branch_name in spawn_branches(S)) - - -/** - * Return a true value if rank_name is a valid spawn rank in branch under branch_name - */ -/datum/mil_branches/proc/is_spawn_rank(var/branch_name, var/rank_name, var/decl/species/S) - var/datum/mil_branch/branch = get_branch(branch_name) - if(branch && (rank_name in branch.spawn_ranks(S))) - return TRUE - else - return FALSE - /** * A single military branch, such as Fleet or Marines */ @@ -140,34 +61,6 @@ if(!global.using_map.is_species_rank_restricted(S, src, spawn_ranks_[spawn_rank])) . += spawn_rank - -// todo: should this be on /datum/map? this will need heavy reworking if we promote submaps from second to first class map status anyway -/** - * Populate the global branches list from global.using_map - */ -/datum/map/proc/populate_branches() - if(!(global.using_map.flags & MAP_HAS_BRANCH) && !(global.using_map.flags & MAP_HAS_RANK)) - mil_branches.branches = null - mil_branches.spawn_branches_ = null - mil_branches.spawn_branches_by_species_ = null - return 1 - - mil_branches.branches = list() - mil_branches.spawn_branches_ = list() - mil_branches.spawn_branches_by_species_ = list() - for(var/branch_path in global.using_map.branch_types) - if(!ispath(branch_path, /datum/mil_branch)) - PRINT_STACK_TRACE("populate_branches() attempted to instantiate object with path [branch_path], which is not a subtype of /datum/mil_branch.") - continue - - var/datum/mil_branch/branch = new branch_path () - mil_branches.branches[branch.name] = branch - - if(branch_path in global.using_map.spawn_branch_types) - mil_branches.spawn_branches_[branch.name] = branch - - return 1 - /** * A military rank * diff --git a/code/game/jobs/job/_job.dm b/code/game/jobs/job/_job.dm index 40e6b29f42b3..ddd275fdf323 100644 --- a/code/game/jobs/job/_job.dm +++ b/code/game/jobs/job/_job.dm @@ -292,11 +292,9 @@ species_branch_rank_cache_[S] = list() . = species_branch_rank_cache_[S] - var/datum/mil_branches/branches = global.using_map.mil_branches - - var/spawn_branches = branches.spawn_branches(S) + var/spawn_branches = global.using_map.spawn_branches(S) for(var/branch_type in allowed_branches) - var/datum/mil_branch/branch = branches.get_branch_by_type(branch_type) + var/datum/mil_branch/branch = global.using_map.get_branch_by_type(branch_type) if(branch.name in spawn_branches) if(!allowed_ranks || !(global.using_map.flags & MAP_HAS_RANK)) LAZYADD(., branch.name) @@ -320,7 +318,7 @@ if(branch_name == "None") return 0 - var/datum/mil_branch/branch = global.using_map.mil_branches.get_branch(branch_name) + var/datum/mil_branch/branch = global.using_map.get_branch(branch_name) if(!branch) PRINT_STACK_TRACE("unknown branch \"[branch_name]\" passed to is_branch_allowed()") @@ -345,7 +343,7 @@ if(branch_name == "None" || rank_name == "None") return 0 - var/datum/mil_rank/rank = global.using_map.mil_branches.get_rank(branch_name, rank_name) + var/datum/mil_rank/rank = global.using_map.get_rank(branch_name, rank_name) if(!rank) PRINT_STACK_TRACE("unknown rank \"[rank_name]\" in branch \"[branch_name]\" passed to is_rank_allowed()") @@ -360,14 +358,14 @@ /datum/job/proc/get_branches() . = list() for(var/branch in allowed_branches) - var/datum/mil_branch/branch_datum = global.using_map.mil_branches.get_branch_by_type(branch) + var/datum/mil_branch/branch_datum = global.using_map.get_branch_by_type(branch) . += branch_datum.name return english_list(.) //Same as above but ranks /datum/job/proc/get_ranks(branch) . = list() - var/datum/mil_branch/branch_datum = global.using_map.mil_branches.get_branch(branch) + var/datum/mil_branch/branch_datum = global.using_map.get_branch(branch) for(var/datum/mil_rank/rank as anything in allowed_ranks) if(branch_datum && !(initial(rank.name) in branch_datum.ranks)) continue diff --git a/code/game/movietitles.dm b/code/game/movietitles.dm index 1fc735fc1306..7afbacf338d8 100644 --- a/code/game/movietitles.dm +++ b/code/game/movietitles.dm @@ -68,7 +68,7 @@ var/global/list/end_titles var/used_name = H.real_name var/datum/computer_file/report/crew_record/record = get_crewmember_record(H.real_name) if(record && record.get_rank()) - var/datum/mil_rank/rank = global.using_map.mil_branches.get_rank(record.get_branch(), record.get_rank()) + var/datum/mil_rank/rank = global.using_map.get_rank(record.get_branch(), record.get_rank()) if(rank.name_short) used_name = "[rank.name_short] [used_name]" var/showckey = 0 diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 0fc57c0989d2..c256274d7da0 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -338,7 +338,7 @@ var/global/const/NO_EMAG_ACT = -50 return if(ispath(var_value, /datum/mil_branch) || istext(var_value)) - var/datum/mil_branch/new_branch = global.using_map.mil_branches.get_branch(var_value) + var/datum/mil_branch/new_branch = global.using_map.get_branch(var_value) if(new_branch) if(new_branch != id.military_branch) id.military_branch = new_branch @@ -369,7 +369,7 @@ var/global/const/NO_EMAG_ACT = -50 var_value = rank.name if(istext(var_value)) - var/new_rank = global.using_map.mil_branches.get_rank(id.military_branch.name, var_value) + var/new_rank = global.using_map.get_rank(id.military_branch.name, var_value) if(new_rank) id.military_rank = new_rank return diff --git a/code/game/objects/items/weapons/cards_ids_syndicate.dm b/code/game/objects/items/weapons/cards_ids_syndicate.dm index 62fd8c26363b..d57a0910a492 100644 --- a/code/game/objects/items/weapons/cards_ids_syndicate.dm +++ b/code/game/objects/items/weapons/cards_ids_syndicate.dm @@ -214,15 +214,15 @@ to_chat(user, "All information has been deleted from \the [src].") . = 1 if("Branch") - var/new_branch = sanitize(input(user,"What branch of service would you like to put on this card?","Agent Card Branch") as null|anything in global.using_map.mil_branches.spawn_branches()) + var/new_branch = sanitize(input(user,"What branch of service would you like to put on this card?","Agent Card Branch") as null|anything in global.using_map.spawn_branches()) if(!isnull(new_branch) && CanUseTopic(user, state)) - src.military_branch = global.using_map.mil_branches.spawn_branches()[new_branch] + src.military_branch = global.using_map.spawn_branches()[new_branch] to_chat(user, "Branch changed to '[military_branch.name]'.") . = 1 if("Rank") - var/new_rank = sanitize(input(user,"What rank would you like to put on this card?","Agent Card Rank") as null|anything in global.using_map.mil_branches.spawn_ranks(military_branch.name)) + var/new_rank = sanitize(input(user,"What rank would you like to put on this card?","Agent Card Rank") as null|anything in global.using_map.spawn_ranks(military_branch.name)) if(!isnull(new_rank) && CanUseTopic(user, state)) - src.military_rank = global.using_map.mil_branches.spawn_ranks(military_branch.name)[new_rank] + src.military_rank = global.using_map.spawn_ranks(military_branch.name)[new_rank] to_chat(user, "Rank changed to '[military_rank.name]'.") . = 1 diff --git a/code/game/world.dm b/code/game/world.dm index 266e234d0a1b..1c65910d510c 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -101,7 +101,6 @@ GLOBAL_PROTECTED_UNTYPED(game_id, null) update_holiday() //Uncommenting ALLOW_HOLIDAYS in configuration will enable this. try_load_alien_whitelist() investigate_reset() - global.using_map.populate_branches() // Precache/build trait trees. for(var/decl/trait/trait in decls_repository.get_decls_of_type_unassociated(/decl/trait)) trait.build_references() diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm index 4aab1de30764..f893c8b49080 100644 --- a/code/modules/client/preference_setup/loadout/loadout.dm +++ b/code/modules/client/preference_setup/loadout/loadout.dm @@ -243,7 +243,7 @@ var/good_branch = 0 entry += "
    " for(var/branch in branches) - var/datum/mil_branch/player_branch = global.using_map.mil_branches.get_branch(branch) + var/datum/mil_branch/player_branch = global.using_map.get_branch(branch) if(player_branch.type in gear.allowed_branches) branch_checks += "[player_branch.name]" good_branch = 1 diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm index 944bc128c249..5613c8466500 100644 --- a/code/modules/client/preference_setup/occupation/occupation.dm +++ b/code/modules/client/preference_setup/occupation/occupation.dm @@ -81,8 +81,6 @@ if(!SSmapping || !SSjobs.job_lists_by_map_name) return - var/datum/mil_branches/using_branches = global.using_map.mil_branches - var/decl/species/S = pref.get_species_decl() . = list() . += "" @@ -121,9 +119,9 @@ var/datum/mil_branch/player_branch var/branch_string = "" var/rank_branch_string = "" - var/branch_rank = job.allowed_branches ? job.get_branch_rank(S) : using_branches.spawn_branches(S) + var/branch_rank = job.allowed_branches ? job.get_branch_rank(S) : global.using_map.spawn_branches(S) if(global.using_map && (global.using_map.flags & MAP_HAS_BRANCH) && LAZYLEN(branch_rank)) - player_branch = using_branches.get_branch(pref.branches[job.title]) + player_branch = global.using_map.get_branch(pref.branches[job.title]) if(player_branch) if(LAZYLEN(branch_rank) > 1) branch_string += "
    [player_branch.name_short || player_branch.name]-[player_rank.name_short || player_rank.name][skill_link]