diff --git a/.github/workflows/ci_suite.yml b/.github/workflows/ci_suite.yml index d22c6be2de5..81d435a4056 100644 --- a/.github/workflows/ci_suite.yml +++ b/.github/workflows/ci_suite.yml @@ -10,7 +10,7 @@ jobs: run_linters: if: "!contains(github.event.head_commit.message, '[ci skip]')" name: Run Linters - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 concurrency: group: run_linters-${{ github.ref }} cancel-in-progress: true @@ -56,7 +56,7 @@ jobs: compile_all_maps: if: "!contains(github.event.head_commit.message, '[ci skip]')" name: Compile Maps - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 concurrency: group: compile_all_maps-${{ github.ref }} cancel-in-progress: true @@ -76,7 +76,7 @@ jobs: run_all_tests: if: "!contains(github.event.head_commit.message, '[ci skip]')" name: Integration Tests - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 services: mysql: image: mysql:latest @@ -127,7 +127,7 @@ jobs: if: "!contains(github.event.head_commit.message, '[ci skip]') && always()" needs: [run_all_tests] name: Compare Screenshot Tests - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v3 # If we ever add more artifacts, this is going to break, but it'll be obvious. diff --git a/cev_eris.dme b/cev_eris.dme index 232ffbd9467..95a6ad58348 100644 --- a/cev_eris.dme +++ b/cev_eris.dme @@ -171,6 +171,7 @@ #include "code\ATMOSPHERICS\he_pipes.dm" #include "code\ATMOSPHERICS\mainspipe.dm" #include "code\ATMOSPHERICS\pipes.dm" +#include "code\ATMOSPHERICS\tanks.dm" #include "code\ATMOSPHERICS\components\portables_connector.dm" #include "code\ATMOSPHERICS\components\tvalve.dm" #include "code\ATMOSPHERICS\components\valve.dm" @@ -280,7 +281,6 @@ #include "code\datums\callback.dm" #include "code\datums\category.dm" #include "code\datums\contract.dm" -#include "code\datums\datacore.dm" #include "code\datums\datum.dm" #include "code\datums\datum_click_handlers.dm" #include "code\datums\datum_hud.dm" @@ -750,14 +750,12 @@ #include "code\game\machinery\computer\computer.dm" #include "code\game\machinery\computer\guestpass.dm" #include "code\game\machinery\computer\law.dm" -#include "code\game\machinery\computer\medical.dm" #include "code\game\machinery\computer\message.dm" #include "code\game\machinery\computer\Operating.dm" #include "code\game\machinery\computer\pod.dm" #include "code\game\machinery\computer\prisoner.dm" #include "code\game\machinery\computer\prisonshuttle.dm" #include "code\game\machinery\computer\robot.dm" -#include "code\game\machinery\computer\security.dm" #include "code\game\machinery\computer\station_alert.dm" #include "code\game\machinery\doors\airlock.dm" #include "code\game\machinery\doors\airlock_control.dm" @@ -1457,6 +1455,7 @@ #include "code\modules\asset_cache\asset_cache_item.dm" #include "code\modules\asset_cache\asset_list.dm" #include "code\modules\asset_cache\asset_list_items.dm" +#include "code\modules\asset_cache\assets\legacyuiicons.dm" #include "code\modules\asset_cache\assets\sanity.dm" #include "code\modules\asset_cache\assets\sheetmaterials.dm" #include "code\modules\asset_cache\assets\stats.dm" @@ -2276,6 +2275,7 @@ #include "code\modules\nano\modules\human_appearance.dm" #include "code\modules\nano\modules\law_manager.dm" #include "code\modules\nano\modules\nano_module.dm" +#include "code\modules\nano\modules\tgui_type.dm" #include "code\modules\onestar\generator.dm" #include "code\modules\onestar\os_cash.dm" #include "code\modules\onestar\os_turret.dm" @@ -2465,7 +2465,9 @@ #include "code\modules\projectiles\guns\projectile\battle_rifle\boltgun.dm" #include "code\modules\projectiles\guns\projectile\battle_rifle\kovacs.dm" #include "code\modules\projectiles\guns\projectile\battle_rifle\levergun.dm" +#include "code\modules\projectiles\guns\projectile\modular\interactions.dm" #include "code\modules\projectiles\guns\projectile\modular\modular_AK.dm" +#include "code\modules\projectiles\guns\projectile\modular\modular_bolt.dm" #include "code\modules\projectiles\guns\projectile\modular\modular_MK58.dm" #include "code\modules\projectiles\guns\projectile\modular\modular_wintermute.dm" #include "code\modules\projectiles\guns\projectile\other\RPG.dm" diff --git a/code/ATMOSPHERICS/atmospherics.dm b/code/ATMOSPHERICS/atmospherics.dm index 317e27d4d4c..d9467989c30 100644 --- a/code/ATMOSPHERICS/atmospherics.dm +++ b/code/ATMOSPHERICS/atmospherics.dm @@ -48,7 +48,7 @@ Pipelines + Other Objects -> Pipe network /obj/machinery/atmospherics/Destroy() GLOB.atmos_machinery -= src - ..() + . = ..() /obj/machinery/atmospherics/proc/atmos_init() return diff --git a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm index 96d914be2ab..f6cd55f77cb 100644 --- a/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm +++ b/code/ATMOSPHERICS/components/binary_devices/binary_atmos_base.dm @@ -56,7 +56,7 @@ node2.disconnect(src) QDEL_NULL(network2) node2 = null - ..() + . = ..() /obj/machinery/atmospherics/binary/atmos_init() diff --git a/code/ATMOSPHERICS/components/unary/unary_base.dm b/code/ATMOSPHERICS/components/unary/unary_base.dm index aa62e93caea..3c5508530ae 100644 --- a/code/ATMOSPHERICS/components/unary/unary_base.dm +++ b/code/ATMOSPHERICS/components/unary/unary_base.dm @@ -28,7 +28,7 @@ node1.disconnect(src) QDEL_NULL(network) node1 = null - ..() + . = ..() /obj/machinery/atmospherics/unary/atmos_init() diff --git a/code/ATMOSPHERICS/pipes.dm b/code/ATMOSPHERICS/pipes.dm index ae48ca0d338..f86def37c21 100644 --- a/code/ATMOSPHERICS/pipes.dm +++ b/code/ATMOSPHERICS/pipes.dm @@ -72,8 +72,6 @@ return QDEL_HINT_QUEUE /obj/machinery/atmospherics/pipe/attackby(obj/item/I, mob/user) - if (istype(src, /obj/machinery/atmospherics/pipe/tank)) - return ..() if (istype(src, /obj/machinery/atmospherics/pipe/vent)) return ..() @@ -130,8 +128,6 @@ */ /obj/machinery/atmospherics/pipe/color_cache_name(var/obj/machinery/atmospherics/node) - if(istype(src, /obj/machinery/atmospherics/pipe/tank)) - return ..() if(istype(node, /obj/machinery/atmospherics/pipe/manifold) || istype(node, /obj/machinery/atmospherics/pipe/manifold4w)) if(pipe_color == node.pipe_color) @@ -1034,166 +1030,6 @@ icon_connect_type = "-supply" color = PIPE_COLOR_BLUE - -/obj/machinery/atmospherics/pipe/tank - icon = 'icons/atmos/tank.dmi' - icon_state = "air_map" - - name = "Pressure Tank" - desc = "A large vessel containing pressurized gas." - - volume = 10000 //in liters, 1 meters by 1 meters by 2 meters ~tweaked it a little to simulate a pressure tank without needing to recode them yet - var/start_pressure = 25*ONE_ATMOSPHERE - - level = BELOW_PLATING_LEVEL - dir = SOUTH - initialize_directions = SOUTH - density = TRUE - layer = ABOVE_WINDOW_LAYER - -/obj/machinery/atmospherics/pipe/tank/LateInitialize() - icon_state = "air" - initialize_directions = dir - ..() - -/obj/machinery/atmospherics/pipe/tank/Process() - if(!parent) - ..() - else - . = PROCESS_KILL - -/obj/machinery/atmospherics/pipe/tank/Destroy() - if(node1) - node1.disconnect(src) - - . = ..() - -/obj/machinery/atmospherics/pipe/tank/pipeline_expansion() - return list(node1) - -/obj/machinery/atmospherics/pipe/tank/update_underlays() - if(..()) - underlays.Cut() - var/turf/T = get_turf(src) - if(!istype(T)) - return - add_underlay(T, node1, dir) - -/obj/machinery/atmospherics/pipe/tank/hide() - update_underlays() - -/obj/machinery/atmospherics/pipe/tank/atmos_init() - var/connect_direction = dir - - for(var/obj/machinery/atmospherics/target in get_step(src, connect_direction)) - if(target.initialize_directions & get_dir(target, src)) - if (check_connect_types(target, src)) - node1 = target - break - - update_underlays() - -/obj/machinery/atmospherics/pipe/tank/disconnect(obj/machinery/atmospherics/reference) - if(reference == node1) - if(istype(node1, /obj/machinery/atmospherics/pipe)) - QDEL_NULL(parent) - node1 = null - - update_underlays() - - return null - -/obj/machinery/atmospherics/pipe/tank/attackby(var/obj/item/W as obj, var/mob/user as mob) - if(istype(W, /obj/item/device/pipe_painter)) - return - -/obj/machinery/atmospherics/pipe/tank/air - name = "Pressure Tank (Air)" - icon_state = "air_map" - -/obj/machinery/atmospherics/pipe/tank/air/LateInitialize() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T20C - - air_temporary.adjust_multi("oxygen", (start_pressure*O2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature), \ - "nitrogen",(start_pressure*N2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - - ..() - icon_state = "air" - -/obj/machinery/atmospherics/pipe/tank/oxygen - name = "Pressure Tank (Oxygen)" - icon_state = "o2_map" - -/obj/machinery/atmospherics/pipe/tank/oxygen/LateInitialize() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T20C - - air_temporary.adjust_gas("oxygen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - ..() - icon_state = "o2" - -/obj/machinery/atmospherics/pipe/tank/nitrogen - name = "Pressure Tank (Nitrogen)" - icon_state = "n2_map" - -/obj/machinery/atmospherics/pipe/tank/nitrogen/LateInitialize() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T20C - - air_temporary.adjust_gas("nitrogen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - ..() - icon_state = "n2" - -/obj/machinery/atmospherics/pipe/tank/carbon_dioxide - name = "Pressure Tank (Carbon Dioxide)" - icon_state = "co2_map" - -/obj/machinery/atmospherics/pipe/tank/carbon_dioxide/LateInitialize() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T20C - - air_temporary.adjust_gas("carbon_dioxide", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - ..() - icon_state = "co2" - -/obj/machinery/atmospherics/pipe/tank/plasma - name = "Pressure Tank (Plasma)" - description_antag = "Will blind people if they do not wear face-covering gear" - icon_state = "plasma_map" - -/obj/machinery/atmospherics/pipe/tank/plasma/LateInitialize() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T20C - - air_temporary.adjust_gas("plasma", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - ..() - icon_state = "plasma" - -/obj/machinery/atmospherics/pipe/tank/nitrous_oxide - name = "Pressure Tank (Nitrous Oxide)" - icon_state = "n2o_map" - -/obj/machinery/atmospherics/pipe/tank/nitrous_oxide/LateInitialize() - air_temporary = new - air_temporary.volume = volume - air_temporary.temperature = T0C - - air_temporary.adjust_gas("sleeping_agent", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) - - ..() - icon_state = "n2o" - /obj/machinery/atmospherics/pipe/vent icon = 'icons/obj/atmospherics/pipe_vent.dmi' icon_state = "intact" diff --git a/code/ATMOSPHERICS/tanks.dm b/code/ATMOSPHERICS/tanks.dm new file mode 100644 index 00000000000..21c30552bfb --- /dev/null +++ b/code/ATMOSPHERICS/tanks.dm @@ -0,0 +1,221 @@ +/obj/machinery/atmospherics/tank + icon = 'icons/atmos/tank.dmi' + icon_state = "air_map" + + name = "Pressure Tank" + desc = "A large vessel containing pressurized gas." + + var/volume = 10000 //in liters, 1 meters by 1 meters by 2 meters ~tweaked it a little to simulate a pressure tank without needing to recode them yet + var/start_pressure = 25*ONE_ATMOSPHERE + + level = BELOW_PLATING_LEVEL + dir = SOUTH + initialize_directions = SOUTH + density = TRUE + layer = ABOVE_WINDOW_LAYER + var/datum/gas_mixture/air_temporary // used when reconstructing a pipeline that broke + + var/obj/machinery/atmospherics/node + + var/datum/pipe_network/network + + use_power = NO_POWER_USE + + can_buckle = TRUE + buckle_require_restraints = 1 + buckle_lying = -1 + +/obj/machinery/atmospherics/tank/drain_power() + return -1 + +/obj/machinery/atmospherics/tank/LateInitialize() + icon_state = "air" + initialize_directions = dir + ..() + +/obj/machinery/atmospherics/tank/hides_under_flooring() + return level != 2 + +/obj/machinery/atmospherics/tank/return_air() + return air_temporary + +/obj/machinery/atmospherics/tank/build_network() + if(!network && node) + network = new /datum/pipe_network() + network.normal_members += src + network.build_network(node, src) + +/obj/machinery/atmospherics/tank/return_network(obj/machinery/atmospherics/reference) + build_network() + + if(reference==node) + return network + + return null + +/obj/machinery/atmospherics/tank/reassign_network(datum/pipe_network/old_network, datum/pipe_network/new_network) + if(network == old_network) + network = new_network + + return TRUE + +/obj/machinery/atmospherics/tank/return_network_air(datum/pipe_network/reference) + var/list/results = list() + + if(air_temporary) + results += air_temporary + + return results + + +/obj/machinery/atmospherics/tank/network_expand(datum/pipe_network/new_network, obj/machinery/atmospherics/pipe/reference) + if(reference == node) + network = new_network + + if(new_network.normal_members.Find(src)) + return 0 + + new_network.normal_members += src + + return null + +/obj/machinery/atmospherics/tank/Process() + if(!network) + ..() + network?.update = 1 + else + . = PROCESS_KILL + +/obj/machinery/atmospherics/tank/Destroy() + if(node) + node.disconnect(src) + QDEL_NULL(network) + + if(air_temporary) + loc.assume_air(air_temporary) + QDEL_NULL(air_temporary) + + loc = null + node = null + + . = ..() + return QDEL_HINT_QUEUE + +/obj/machinery/atmospherics/tank/update_underlays() + if(..()) + underlays.Cut() + var/turf/T = get_turf(src) + if(!istype(T)) + return + add_underlay(T, node, dir) + +/obj/machinery/atmospherics/tank/hide() + update_underlays() + +/obj/machinery/atmospherics/tank/atmos_init() + if(node) return + var/connect_direction = dir + + for(var/obj/machinery/atmospherics/target in get_step(src, connect_direction)) + if(target.initialize_directions & get_dir(target, src)) + if (check_connect_types(target, src)) + node = target + break + + update_underlays() + +/obj/machinery/atmospherics/tank/disconnect(obj/machinery/atmospherics/reference) + if(reference==node) + QDEL_NULL(network) + node = null + + update_underlays() + + return null + +/obj/machinery/atmospherics/tank/air + name = "Pressure Tank (Air)" + icon_state = "air_map" + +/obj/machinery/atmospherics/tank/air/LateInitialize() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.adjust_multi("oxygen", (start_pressure*O2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature), \ + "nitrogen",(start_pressure*N2STANDARD)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + + ..() + icon_state = "air" + +/obj/machinery/atmospherics/tank/oxygen + name = "Pressure Tank (Oxygen)" + icon_state = "o2_map" + +/obj/machinery/atmospherics/tank/oxygen/LateInitialize() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.adjust_gas("oxygen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + ..() + icon_state = "o2" + +/obj/machinery/atmospherics/tank/nitrogen + name = "Pressure Tank (Nitrogen)" + icon_state = "n2_map" + +/obj/machinery/atmospherics/tank/nitrogen/LateInitialize() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.adjust_gas("nitrogen", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + ..() + icon_state = "n2" + +/obj/machinery/atmospherics/tank/carbon_dioxide + name = "Pressure Tank (Carbon Dioxide)" + icon_state = "co2_map" + +/obj/machinery/atmospherics/tank/carbon_dioxide/LateInitialize() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.adjust_gas("carbon_dioxide", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + ..() + icon_state = "co2" + +/obj/machinery/atmospherics/tank/plasma + name = "Pressure Tank (Plasma)" + description_antag = "Will blind people if they do not wear face-covering gear" + icon_state = "plasma_map" + +/obj/machinery/atmospherics/tank/plasma/LateInitialize() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T20C + + air_temporary.adjust_gas("plasma", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + ..() + icon_state = "plasma" + +/obj/machinery/atmospherics/tank/nitrous_oxide + name = "Pressure Tank (Nitrous Oxide)" + icon_state = "n2o_map" + +/obj/machinery/atmospherics/tank/nitrous_oxide/LateInitialize() + air_temporary = new + air_temporary.volume = volume + air_temporary.temperature = T0C + + air_temporary.adjust_gas("sleeping_agent", (start_pressure)*(air_temporary.volume)/(R_IDEAL_GAS_EQUATION*air_temporary.temperature)) + + ..() + icon_state = "n2o" \ No newline at end of file diff --git a/code/__DEFINES/items.dm b/code/__DEFINES/items.dm index e288b79ab3d..4f682d97fa1 100644 --- a/code/__DEFINES/items.dm +++ b/code/__DEFINES/items.dm @@ -63,6 +63,9 @@ #define GUN_UPGRADE_OVERCHARGE_MAX "overcharge_max_mult" #define GUN_UPGRADE_OVERCHARGE_RATE "overcharge_rate_mult" #define GUN_UPGRADE_ONEHANDPENALTY "onehandpenalty_mult" +#define GUN_UPGRADE_MOVEPENALTY "movementpenalty_mult" +#define GUN_UPGRADE_RECOILBUILDUP "recoilbuildup_mult" +#define GUN_UPGRADE_BASESLOW "slowdown_base_add" //Int additive #define GUN_UPGRADE_DAMAGEMOD_PLUS "damage_plus" @@ -81,14 +84,29 @@ #define GUN_UPGRADE_OFFSET "offset" //Constant offset, in degrees #define GUN_UPGRADE_ZOOM "zoom" +#define GUN_UPGRADE_SCOPEVISION "scopeseeinvis" +#define GUN_UPGRADE_SCOPECORRECTION "scopeoffset" +#define GUN_UPGRADE_DARKSCOPE "scopedarksight" //Type configuration +#define GUN_UPGRADE_REPLACE_INTERACTIONS "interactions" #define GUN_UPGRADE_DEFINE_OK_CALIBERS "ok_calibers" #define GUN_UPGRADE_DEFINE_CALIBER "caliber" #define GUN_UPGRADE_DEFINE_MAG_WELL "mag_well" #define GUN_UPGRADE_DEFINE_STOCK "stock" #define GUN_UPGRADE_FIREMODES "firemodes" #define GUN_UPGRADE_DEFINE_GRIP "grip" +#define GUN_UPGRADE_DEFINE_LOADER "loadtype" +#define GUN_UPGRADE_DENY_MAG "no_mag" +#define GUN_UPGRADE_DEFINE_WCLASS "add_wclass" +#define GUN_UPGRADE_SCOPE_POWER "scope_power" + +//Gun Interaction flags +#define GI_ATTACKSELF 1 +#define GI_LOAD 2 +#define GI_UNLOAD 4 +#define GI_SPIN 8 +#define GI_SPECIAL 16 //boolean #define GUN_UPGRADE_SILENCER "silencable" diff --git a/code/__DEFINES/jobs.dm b/code/__DEFINES/jobs.dm index 18a82d9b01c..2bebcf467e3 100644 --- a/code/__DEFINES/jobs.dm +++ b/code/__DEFINES/jobs.dm @@ -8,10 +8,10 @@ #define JOBS_MEDICAL "Moebius Biolab Officer","Moebius Doctor","Moebius Psychiatrist","Moebius Chemist","Moebius Paramedic","Moebius Bio-Engineer" #define JOBS_SCIENCE "Moebius Expedition Overseer","Moebius Scientist","Moebius Roboticist" #define JOBS_MOEBIUS "Moebius Biolab Officer","Moebius Doctor","Moebius Psychiatrist","Moebius Chemist","Moebius Paramedic","Moebius Bio-Engineer","Moebius Expedition Overseer","Moebius Scientist","Moebius Roboticist" -#define JOBS_CARGO "Guild Merchant","Guild Technician","Guild Miner", +#define JOBS_GUILD "Guild Merchant","Guild Technician","Guild Miner", #define JOBS_CIVILIAN "Club Manager","Club Worker","Club Artist",ASSISTANT_TITLE #define JOBS_CHURCH "NeoTheology Preacher","NeoTheology Acolyte","NeoTheology Agrolyte","NeoTheology Custodian" -#define JOBS_NONHUMAN "AI","Robot","pAI" +#define JOBS_SILICON "AI","Robot","pAI" #define CREDITS "¢" #define CREDS "¢" diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 81457891953..7ed87bd3a0d 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -106,10 +106,10 @@ #define COIN_GOLD "Gold coin" #define COIN_SILVER "Silver coin" #define COIN_DIAMOND "Diamond coin" -#define COIN_IRON "Iron coin" +#define COIN_PLASTEEL "Plasteel coin" #define COIN_PLASMA "Solid plasma coin" #define COIN_URANIUM "Uranium coin" -#define COIN_PLATINUM "Platunum coin" +#define COIN_PLATINUM "Platinum coin" #define SHARD_SHARD "shard" #define SHARD_SHRAPNEL "shrapnel" diff --git a/code/__DEFINES/perks.dm b/code/__DEFINES/perks.dm index 210eaa70c3e..d6571683e42 100644 --- a/code/__DEFINES/perks.dm +++ b/code/__DEFINES/perks.dm @@ -1,6 +1,6 @@ //fate perks #define PERK_PAPER_WORM /datum/perk/fate/paper_worm -#define PERK_FREELACER /datum/perk/fate/freelancer +#define PERK_FREELANCER /datum/perk/fate/freelancer #define PERK_NIHILIST /datum/perk/fate/nihilist #define PERK_MORALIST /datum/perk/fate/moralist #define PERK_ALCOHOLIC /datum/perk/fate/alcoholic @@ -49,6 +49,8 @@ #define PERK_CODESPEAK_COP /datum/perk/codespeak #define PERK_CODESPEAK_SERB /datum/perk/codespeak/serbian #define PERK_TECHNOMANCER /datum/perk/inspiration +#define PERK_NEAT /datum/perk/neat +#define PERK_GREEN_THUMB /datum/perk/greenthumb #define PERK_CLUB /datum/perk/job/club #define PERK_CHANNELING /datum/perk/channeling diff --git a/code/__DEFINES/weapons.dm b/code/__DEFINES/weapons.dm index c737c7ce3e1..ea223064507 100644 --- a/code/__DEFINES/weapons.dm +++ b/code/__DEFINES/weapons.dm @@ -107,3 +107,4 @@ #define RIFLE_RECOIL(x) list(0.8 *x, 5, 2.4*x ) #define LMG_RECOIL(x) list(0.7 *x, 8, 3*x ) #define HMG_RECOIL(x) list(0.6 *x, 12, 3.6*x ) +#define SLATE_RECOIL(x) list(1 *x, 1, 1 *x) diff --git a/code/__HELPERS/manifest.dm b/code/__HELPERS/manifest.dm index 334e07960d3..2215f1bbb96 100644 --- a/code/__HELPERS/manifest.dm +++ b/code/__HELPERS/manifest.dm @@ -142,13 +142,13 @@ "sec" = filtered_nano_crew_manifest(security_positions),\ "eng" = filtered_nano_crew_manifest(engineering_positions),\ "med" = filtered_nano_crew_manifest(medical_positions),\ - "sup" = filtered_nano_crew_manifest(cargo_positions),\ + "sup" = filtered_nano_crew_manifest(guild_positions),\ "chr" = filtered_nano_crew_manifest(church_positions),\ - "bot" = silicon_nano_crew_manifest(nonhuman_positions),\ + "bot" = silicon_nano_crew_manifest(silicon_positions),\ "civ" = filtered_nano_crew_manifest(civilian_positions)\ ) /proc/flat_nano_crew_manifest() . = list() . += filtered_nano_crew_manifest(null, TRUE) - . += silicon_nano_crew_manifest(nonhuman_positions) \ No newline at end of file + . += silicon_nano_crew_manifest(silicon_positions) \ No newline at end of file diff --git a/code/__HELPERS/names.dm b/code/__HELPERS/names.dm index c87268b454f..2c8a171b4e2 100644 --- a/code/__HELPERS/names.dm +++ b/code/__HELPERS/names.dm @@ -94,8 +94,8 @@ var/syndicate_code_response//Code response for contractors. var/locations[] = LAZYLEN(SSmapping.main_ship_areas_by_name) ? SSmapping.main_ship_areas_by_name : drinks // If null, defaults to drinks instead. var/names[] = list() - for(var/datum/data/record/t in data_core.general)//Picks from crew manifest. - names += t.fields["name"] + for(var/datum/computer_file/report/crew_record/t in GLOB.all_crew_records)//Picks from crew manifest. + names += t.get_name() var/maxwords = words//Extra var to check for duplicates. diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 0785b29e9fc..7a6bf8d5007 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -276,26 +276,21 @@ Turf and target are seperate in case you want to teleport some distance from a t mind.name = newname if(oldname) - //update the datacore records! This is goig to be a bit costly. - for(var/list/L in list(data_core.general, data_core.medical, data_core.security, data_core.locked)) - for(var/datum/data/record/R in L) - if(R.fields["name"] == oldname) - R.fields["name"] = newname - break + for(var/datum/computer_file/report/crew_record/R in GLOB.all_crew_records) + if(R.get_name() == oldname) + R.set_name(newname) //update our pda and id if we have them on our person - var/list/searching = GetAllContents(searchDepth = 3) - var/search_id = 1 - var/search_pda = 1 - - for(var/A in searching) - if( search_id && istype(A,/obj/item/card/id) ) + for(var/obj/A in GetAllContents(searchDepth = 3)) + if(istype(A,/obj/item/card/id)) var/obj/item/card/id/ID = A if(ID.registered_name == oldname) ID.registered_name = newname ID.name = "[newname]'s ID Card ([ID.assignment])" - if(!search_pda) break - search_id = 0 + if(istype(A.loc, /obj/item/modular_computer)) + var/obj/item/modular_computer/tolabel = A.loc + tolabel.update_label() + break return 1 diff --git a/code/controllers/subsystems/ticker.dm b/code/controllers/subsystems/ticker.dm index 1777bd31dcf..1fe7dfc2abc 100644 --- a/code/controllers/subsystems/ticker.dm +++ b/code/controllers/subsystems/ticker.dm @@ -241,7 +241,6 @@ SUBSYSTEM_DEF(ticker) if(!H.mind || player_is_antag(H.mind, only_offstation_roles = 1) || !SSjob.ShouldCreateRecords(H.mind.assigned_role)) continue CreateModularRecord(H) - data_core.manifest() CHECK_TICK diff --git a/code/controllers/subsystems/trade.dm b/code/controllers/subsystems/trade.dm index 764d7bd4bb3..a14e2fc89a7 100644 --- a/code/controllers/subsystems/trade.dm +++ b/code/controllers/subsystems/trade.dm @@ -541,7 +541,7 @@ SUBSYSTEM_DEF(trade) create_log_entry("Export", guild_account.get_name(), invoice_contents_info, cost, FALSE, get_turf(senderBeacon)) /datum/controller/subsystem/trade/proc/get_export_price_multiplier(atom/movable/target) - if(!target || target.anchored) + if(!target || isturf(target) || target.anchored) return NONEXPORTABLE . = EXPORTABLE diff --git a/code/datums/craft/gun_parts.dm b/code/datums/craft/gun_parts.dm index e98868bd083..95bca9de5af 100644 --- a/code/datums/craft/gun_parts.dm +++ b/code/datums/craft/gun_parts.dm @@ -67,7 +67,7 @@ semi accepts weird caliber - +1 points w_class = ITEM_SIZE_SMALL matter = list(MATERIAL_PLASTEEL = 5) generic = TRUE - var/part_overlay + var/part_overlay = "" var/part_itemstring var/needs_grip_type generic = FALSE @@ -75,6 +75,7 @@ semi accepts weird caliber - +1 points var/datum/component/item_upgrade/I // For changing stats when needed var/old_quality = 0 var/max_quality = 2 + var/interactions // Bonuses from forging/type or maluses from printing var/cheap = FALSE // Set this to true for cheap variants @@ -82,8 +83,11 @@ semi accepts weird caliber - +1 points /obj/item/part/gun/modular/New(location) ..() I = AddComponent(/datum/component/item_upgrade) + if(interactions) + interactions = new interactions(src) I.weapon_upgrades = list( - UPGRADE_MAXUPGRADES = 1 // Since this takes an upgrade slot, we want to give it back + UPGRADE_MAXUPGRADES = 1, // Since this takes an upgrade slot, we want to give it back + GUN_UPGRADE_REPLACE_INTERACTIONS = interactions // used for overriding gun behavior ) I.req_gun_tags = list(GUN_MODULAR) I.removable = MOD_INTEGRAL // Will get unique removal handling when we get there, until then works by disassembling the frame @@ -374,21 +378,34 @@ semi accepts weird caliber - +1 points price_tag = 100 rarity_value = 6 var/list/accepted_calibers = list(CAL_PISTOL, CAL_MAGNUM, CAL_SRIFLE, CAL_CLRIFLE, CAL_LRIFLE, CAL_SHOTGUN) + var/loader = MAGAZINE var/mag_well = MAG_WELL_GENERIC var/divisor_bonus = 0 var/recoil_bonus = 0 var/damage_bonus = 0 + var/onehandpenalty = 0 + var/max_shells = 0 var/list/bonus_firemodes = list() + var/no_internal_mag = FALSE + + /obj/item/part/gun/modular/mechanism/New(location, var/quality = 0) ..(quality) I.weapon_upgrades[GUN_UPGRADE_FIREMODES] = bonus_firemodes I.weapon_upgrades[GUN_UPGRADE_DEFINE_MAG_WELL] = mag_well I.weapon_upgrades[GUN_UPGRADE_DEFINE_OK_CALIBERS] = accepted_calibers + I.weapon_upgrades[GUN_UPGRADE_DEFINE_LOADER] = loader + if(divisor_bonus) I.weapon_upgrades[GUN_UPGRADE_PEN_MULT] = divisor_bonus if(recoil_bonus) I.weapon_upgrades[GUN_UPGRADE_RECOIL] = recoil_bonus + if(max_shells) + I.weapon_upgrades[GUN_UPGRADE_MAGUP] = max_shells + if(no_internal_mag) + I.weapon_upgrades[GUN_UPGRADE_DENY_MAG] = TRUE + I.gun_loc_tag = PART_MECHANISM /obj/item/part/gun/modular/mechanism/set_quality(var/quality = 0) @@ -419,6 +436,10 @@ semi accepts weird caliber - +1 points name = "revolver mechanism" desc = "All the bits that makes the bullet go bang, rolling round and round." icon_state = "mechanism_revolver" + max_shells = 6 + +/obj/item/part/gun/modular/mechanism/revolver/seven + max_shells = 7 /obj/item/part/gun/modular/mechanism/shotgun name = "shotgun mechanism" @@ -565,6 +586,43 @@ semi accepts weird caliber - +1 points desc = "All the bits that makes the bullet go bang, slow and methodical." icon_state = "mechanism_boltaction" matter = list(MATERIAL_STEEL = 3) + accepted_calibers = list(CAL_LRIFLE, CAL_SRIFLE, CAL_PISTOL, CAL_MAGNUM) // used by boltrifles + loader = SINGLE_CASING|SPEEDLOADER + interactions = /datum/guninteraction/bolted + max_shells = 10 + divisor_bonus = 0.3 + damage_bonus = 0.4 + +/obj/item/part/gun/modular/mechanism/boltgun/power + accepted_calibers = list(CAL_SRIFLE, CAL_MAGNUM) + max_shells = 6 + divisor_bonus = 1 + damage_bonus = 0.8 + +/obj/item/part/gun/modular/mechanism/boltgun/heavy + name = "heavy manual-action mechanism" + desc = "All the bits that makes the bullet go bang, slow and methodical; for larger calibers." + matter = list(MATERIAL_STEEL = 4) + accepted_calibers = list(CAL_SHOTGUN, CAL_MAGNUM, CAL_FLARE, CAL_ANTIM) // used by AMRs + part_overlay = "big_" // the full entry is handled by the guninteraction + loader = SINGLE_CASING + max_shells = 1 + divisor_bonus = 0 + damage_bonus = 1 + +/obj/item/part/gun/modular/mechanism/boltgun/junk + name = "handmade manual-action mechanism" + max_shells = 5 + divisor_bonus = -0.3 + damage_bonus = 0.5 + +/obj/item/part/gun/modular/mechanism/levergun + name = "break-action mechanism" + desc = "This one breaks in half!" + // no icon state available + matter = list(MATERIAL_STEEL = 4) + accepted_calibers = list(CAL_MAGNUM, CAL_SHOTGUN) // used by leverguns only + max_shells = 7 /obj/item/part/gun/modular/mechanism/autorifle/steel name = "cheap self-loading mechanism" @@ -583,10 +641,25 @@ semi accepts weird caliber - +1 points price_tag = 200 rarity_value = 15 var/caliber = CAL_357 + var/speed + var/onehandpenalty + var/recoilbuildup + var/pierce + var/basemove /obj/item/part/gun/modular/barrel/New(location, var/quality = 0) ..(quality) I.weapon_upgrades[GUN_UPGRADE_DEFINE_CALIBER] = caliber + if(!isnull(speed)) + I.weapon_upgrades[GUN_UPGRADE_STEPDELAY_MULT] = speed + if(onehandpenalty) + I.weapon_upgrades[GUN_UPGRADE_ONEHANDPENALTY] = onehandpenalty + if(recoilbuildup) + I.weapon_upgrades[GUN_UPGRADE_RECOILBUILDUP] = recoilbuildup + if(pierce) + I.weapon_upgrades[GUN_UPGRADE_PIERC_MULT] = pierce + if(basemove) + I.weapon_upgrades[GUN_UPGRADE_BASESLOW] = basemove I.gun_loc_tag = PART_BARREL @@ -632,6 +705,13 @@ semi accepts weird caliber - +1 points caliber = CAL_SRIFLE part_overlay = "well_srifle" +/obj/item/part/gun/modular/barrel/srifle/long + name = "long .20 barrel" + desc = "A gun barrel, which keeps the bullet going in the right direction efficiently. Chambered in .20 caliber." + onehandpenalty = 1.2 + recoilbuildup = 1.2 + speed = 0.8 + /obj/item/part/gun/modular/barrel/clrifle name = ".25 barrel" desc = "A gun barrel, which keeps the bullet going in the right direction. Chambered in .25 caliber." @@ -671,10 +751,21 @@ semi accepts weird caliber - +1 points name = ".60 barrel" desc = "A gun barrel, which keeps the bullet going in the right direction. Chambered in .60 caliber." icon_state = "barrel_60" - matter = list(MATERIAL_PLASTEEL = 16) + matter = list(MATERIAL_PLASTEEL = 10) caliber = CAL_ANTIM part_overlay = "well_amr" +/obj/item/part/gun/modular/barrel/antim/long + name = "long .60 barrel" + desc = "A long gun barrel, which keeps the bullet moving in the right direction efficiently. Chambered in .60 caliber." + matter = list(MATERIAL_PLASTEEL = 15) + speed = 0 + part_overlay = "well_amr_long" + onehandpenalty = 2 + recoilbuildup = 2 + pierce = 6 + basemove = 3 + // steel barrels /obj/item/part/gun/modular/barrel/pistol/steel name = "cheap .35 barrel" @@ -720,8 +811,124 @@ semi accepts weird caliber - +1 points generic = FALSE part_overlay = "stock" needs_grip_type = TRUE + var/brace = 0 + var/recoilbuildup + var/movementcost + var/onehandpenalty + var/wclassmod = 1 /obj/item/part/gun/modular/stock/New(location, var/quality = 0) ..() // No stat change, so no need for price change either I.weapon_upgrades[GUN_UPGRADE_DEFINE_STOCK] = TRUE I.gun_loc_tag = PART_STOCK + + if(movementcost) + I.weapon_upgrades[GUN_UPGRADE_MOVEPENALTY] = movementcost + if(recoilbuildup) + I.weapon_upgrades[GUN_UPGRADE_RECOILBUILDUP] = recoilbuildup + if(onehandpenalty) + I.weapon_upgrades[GUN_UPGRADE_ONEHANDPENALTY] = onehandpenalty + I.weapon_upgrades[GUN_UPGRADE_DEFINE_WCLASS] = wclassmod + +/obj/item/part/gun/modular/stock/heavy + recoilbuildup = 0.7 + movementcost = 8 + onehandpenalty = 3 + +/obj/item/part/gun/modular/stock/longrifle + recoilbuildup = 0.8 + movementcost = 5 + onehandpenalty = 2.4 + +/obj/item/part/gun/modular/sights + name = "ironsights" + desc = "A set of sights for aiming through." + var/list/scopes = list() + interactions = /datum/guninteraction/zoomed + var/scopeaccuracy + var/scopeseeinvis + var/darksight + var/list/powerboost + +/obj/item/part/gun/modular/sights/New(location, var/quality = 0) + ..(quality) + I.weapon_upgrades[GUN_UPGRADE_ZOOM] = scopes + if(scopeseeinvis) + I.weapon_upgrades[GUN_UPGRADE_SCOPEVISION] = scopeseeinvis + if(scopeaccuracy) + I.weapon_upgrades[GUN_UPGRADE_SCOPECORRECTION] = scopeaccuracy + if(darksight) + I.weapon_upgrades[GUN_UPGRADE_DARKSCOPE] = darksight + if(powerboost) + I.weapon_upgrades[GUN_UPGRADE_SCOPE_POWER] = powerboost + I.gun_loc_tag = GUN_SCOPE + +/obj/item/part/gun/modular/sights/scopesmall // Arasaka boltgun + name = "small scope" + desc = "A sight for aiming through. This one is on the smaller side." + icon_state = "scope_small" + scopes = list(0.5) + part_overlay = "scope_small" + +/obj/item/part/gun/modular/sights/scopebig // Kadmin + name = "medium scope" + desc = "A sight for aiming through. This one is medium." + icon_state = "scope_big" + scopes = list(0.8) + part_overlay = "scope_big" + +/obj/item/part/gun/modular/sights/customizable + +/obj/item/part/gun/modular/sights/customizable/attackby(obj/item/Item, mob/living/user) + if(istype(Item, /obj/item/clothing/glasses/powered/thermal)) + user.visible_message(SPAN_NOTICE("[user] inserts \a [Item] into [src]."), SPAN_NOTICE("You insert [Item] into \the [src]."), "You hear a faint click.", 5) + I.weapon_upgrades[GUN_UPGRADE_THERMAL] = TRUE + user.drop_from_inventory(Item, src) + else if(Item.has_quality(QUALITY_SCREW_DRIVING)) + var/list/choices = contents.Copy() + choices += "Cancel" + var/obj/toremove = input("Which upgrade would you like to try to remove?","Removing Upgrades") in choices + if(toremove == "Cancel") + return TRUE + else if(!isnull(toremove)) + toremove.forceMove(get_turf(src)) + if(istype(toremove, /obj/item/clothing/glasses/powered/thermal)) + I.weapon_upgrades[GUN_UPGRADE_THERMAL] = FALSE + to_chat(user, SPAN_NOTICE("You successfully remove [toremove] from \the [src]!")) + + +/obj/item/part/gun/modular/sights/customizable/scopeheavy // AMR + name = "sniper scope" + desc = "A large adjustable sight for aiming through. Provides night vision. Can add advanced lenses to improve vision." + icon_state = "scope_heavy" + scopes = list(1,2) + part_overlay = "scope_heavy" + darksight = 7 + scopeseeinvis = SEE_INVISIBLE_NOLIGHTING + scopeaccuracy = 8 + powerboost = list(0.2, 0.4) + interactions = /datum/guninteraction/zoomed/multizoom + +/obj/item/part/gun/modular/bayonet + name = "integrated bayonet" + desc = "A bayonet designed for a firmer attachment, applied during assembly." + matter = list(MATERIAL_PLASTEEL = 3, MATERIAL_STEEL = 2) + icon = 'icons/obj/weapons.dmi' + icon_state = "dagger" + part_overlay = "bayonet" + var/damagedone = 6 + +/obj/item/part/gun/modular/bayonet/New(location, var/quality = 0) + ..(quality) + I.weapon_upgrades = list( + GUN_UPGRADE_BAYONET = TRUE, + GUN_UPGRADE_MELEEDAMAGE = damagedone, + GUN_UPGRADE_MELEEPENETRATION = ARMOR_PEN_MODERATE, + GUN_UPGRADE_OFFSET = 4 + ) + +/obj/item/part/gun/modular/bayonet/steel + name = "cheap integrated bayonet" + desc = "A bayonet designed for a firmer attachment, applied during assembly. This one's made from cheap steel." + matter = list(MATERIAL_STEEL = 2) + damagedone = 3 diff --git a/code/datums/craft/recipes/guns.dm b/code/datums/craft/recipes/guns.dm index 86d2824ac06..439cb6ee0a4 100644 --- a/code/datums/craft/recipes/guns.dm +++ b/code/datums/craft/recipes/guns.dm @@ -27,8 +27,8 @@ name = "HM BR \"Riose\"" result = /obj/item/gun/projectile/boltgun/handmade steps = list( - list(CRAFT_MATERIAL, 10, MATERIAL_STEEL), - list(CRAFT_MATERIAL, 10, MATERIAL_WOOD), + list(CRAFT_MATERIAL, 13, MATERIAL_STEEL), + list(CRAFT_MATERIAL, 5, MATERIAL_WOOD), list(QUALITY_HAMMERING, 10), list(QUALITY_ADHESIVE, 15, 70) ) diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm deleted file mode 100644 index 5fbabd76693..00000000000 --- a/code/datums/datacore.dm +++ /dev/null @@ -1,454 +0,0 @@ -var/global/list/PDA_Manifest = list() -var/global/ManifestJSON - -/hook/startup/proc/createDatacore() - data_core = new /datum/datacore() - return 1 - -/datum/datacore - var/name = "datacore" - var/medical[] = list() - var/general[] = list() - var/security[] = list() - //This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character(). - var/locked[] = list() - - -/datum/datacore/proc/get_manifest(monochrome, OOC) - var/list/heads = new() - var/list/sec = new() - var/list/eng = new() - var/list/med = new() - var/list/sci = new() - var/list/car = new() - var/list/chr = new() - var/list/civ = new() - var/list/bot = new() - var/list/misc = new() - var/list/isactive = new() - var/dat = {" - - - - "} - var/even = 0 - // sort mobs - for(var/datum/data/record/t in data_core.general) - var/name = t.fields["name"] - var/rank = t.fields["rank"] - var/real_rank = make_list_rank(t.fields["real_rank"]) - - if(OOC) - var/active = 0 - for(var/mob/M in GLOB.player_list) - if(M.real_name == name && M.client && M.client.inactivity <= 10 * 60 * 10) - active = 1 - break - isactive[name] = active ? "Active" : "Inactive" - else - isactive[name] = t.fields["p_stat"] - //world << "[name]: [rank]" - //cael - to prevent multiple appearances of a player/job combination, add a continue after each line - var/department = 0 - if(real_rank in command_positions) - heads[name] = rank - department = 1 - if(real_rank in security_positions) - sec[name] = rank - department = 1 - if(real_rank in engineering_positions) - eng[name] = rank - department = 1 - if(real_rank in medical_positions) - med[name] = rank - department = 1 - if(real_rank in science_positions) - sci[name] = rank - department = 1 - if(real_rank in cargo_positions) - car[name] = rank - department = 1 - if(real_rank in church_positions) - chr[name] = rank - department = 1 - if(real_rank in civilian_positions) - civ[name] = rank - department = 1 - if(!department && !(name in heads)) - misc[name] = rank - - // Synthetics don't have actual records, so we will pull them from here. -/* for(var/mob/living/silicon/ai/ai in SSmobs.mob_list) - bot[ai.name] = "Artificial Intelligence" - - for(var/mob/living/silicon/robot/robot in SSmobs.mob_list) - // No combat/syndicate cyborgs, no drones. - if(robot.module && robot.module.hide_on_manifest) - continue - - bot[robot.name] = "[robot.modtype] [robot.braintype]"*/ - - if(bot.len > 0) - dat += "" - for(name in bot) - dat += "" - even = !even - - if(heads.len > 0) - dat += "" - for(name in heads) - dat += "" - even = !even - if(sec.len > 0) - dat += "" - for(name in sec) - dat += "" - even = !even - if(eng.len > 0) - dat += "" - for(name in eng) - dat += "" - even = !even - if(med.len > 0) - dat += "" - for(name in med) - dat += "" - even = !even - if(sci.len > 0) - dat += "" - for(name in sci) - dat += "" - even = !even - if(car.len > 0) - dat += "" - for(name in car) - dat += "" - even = !even - if(chr.len > 0) - dat += "" - for(name in chr) - dat += "" - even = !even - if(civ.len > 0) - dat += "" - for(name in civ) - dat += "" - even = !even - if(misc.len > 0) - dat += "" - for(name in misc) - dat += "" - even = !even - - dat += "
NameRankActivity
Silicon
[name][bot[name]][isactive[name]]
Heads
[name][heads[name]][isactive[name]]
Security
[name][sec[name]][isactive[name]]
Engineering
[name][eng[name]][isactive[name]]
Medical
[name][med[name]][isactive[name]]
Science
[name][sci[name]][isactive[name]]
Guild
[name][car[name]][isactive[name]]
Church
[name][chr[name]][isactive[name]]
Civilian
[name][civ[name]][isactive[name]]
Miscellaneous
[name][misc[name]][isactive[name]]
" - dat = replacetext(dat, "\n", "") // so it can be placed on paper correctly - dat = replacetext(dat, "\t", "") - return dat - -/datum/datacore/proc/manifest() - spawn() - for(var/mob/living/carbon/human/H in GLOB.player_list) - manifest_inject(H) - return - -/datum/datacore/proc/manifest_modify(var/name, var/assignment) - ResetPDAManifest() - var/datum/data/record/foundrecord - var/real_title = assignment - - for(var/datum/data/record/t in data_core.general) - if (t) - if(t.fields["name"] == name) - foundrecord = t - break - - if(foundrecord) - foundrecord.fields["rank"] = assignment - foundrecord.fields["real_rank"] = real_title - -/datum/datacore/proc/manifest_inject(var/mob/living/carbon/human/H) - if(H.mind && !player_is_antag(H.mind, only_offstation_roles = 1) && H.job != ASSISTANT_TITLE) - var/assignment = GetAssignment(H) - - var/id = generate_record_id() - //General Record - var/datum/data/record/G = CreateGeneralRecord(H, id) - G.fields["name"] = H.real_name - G.fields["real_rank"] = H.mind.assigned_role - G.fields["rank"] = assignment - G.fields["age"] = H.age - G.fields["fingerprint"] = H.fingers_trace - if(H.mind.initial_account) - G.fields["pay_account"] = H.mind.initial_account.account_number ? H.mind.initial_account.account_number : "N/A" - G.fields["email"] = H.mind.initial_email_login["login"] - G.fields["p_stat"] = "Active" - G.fields["m_stat"] = "Stable" - G.fields["sex"] = H.gender - if(H.gen_record && !jobban_isbanned(H, "Records")) - G.fields["notes"] = H.gen_record - - //Medical Record - var/datum/data/record/M = CreateMedicalRecord(H.real_name, id) - M.fields["b_type"] = H.b_type - M.fields["b_dna"] = H.dna_trace - //M.fields["id_gender"] = gender2text(H.identifying_gender) - if(H.med_record && !jobban_isbanned(H, "Records")) - M.fields["notes"] = H.med_record - - //Security Record - var/datum/data/record/S = CreateSecurityRecord(H.real_name, id) - if(H.sec_record && !jobban_isbanned(H, "Records")) - S.fields["notes"] = H.sec_record - - //Locked Record - var/datum/data/record/L = new() - L.fields["id"] = md5("[H.real_name][H.mind.assigned_role]") - L.fields["name"] = H.real_name - L.fields["rank"] = H.mind.assigned_role - L.fields["age"] = H.age - L.fields["fingerprint"] = H.fingers_trace - L.fields["sex"] = H.gender - L.fields["b_type"] = H.b_type - L.fields["b_dna"] = H.dna_trace - L.fields["image"] = getFlatIcon(H) //This is god-awful - if(H.exploit_record && !jobban_isbanned(H, "Records")) - L.fields["exploit_record"] = H.exploit_record - else - L.fields["exploit_record"] = "No additional information acquired." - locked += L - return - -/proc/generate_record_id() - return add_zero(num2hex(rand(1, 65535)), 4) //no point generating higher numbers because of the limitations of num2hex - -/proc/get_id_photo(var/mob/living/carbon/human/H, var/assigned_role) - - var/icon/preview_icon = new(H.stand_icon) - var/icon/temp - - var/datum/sprite_accessory/hair_style = GLOB.hair_styles_list[H.h_style] - if(hair_style) - temp = new/icon(hair_style.icon, hair_style.icon_state) - temp.Blend(H.hair_color, ICON_ADD) - - hair_style = GLOB.facial_hair_styles_list[H.h_style] - if(hair_style) - var/icon/facial = new/icon(hair_style.icon, hair_style.icon_state) - facial.Blend(H.facial_color, ICON_ADD) - temp.Blend(facial, ICON_OVERLAY) - - preview_icon.Blend(temp, ICON_OVERLAY) - - - var/datum/job/J = SSjob.GetJob(H.mind.assigned_role) - if(J) - var/t_state - temp = new /icon('icons/inventory/uniform/mob.dmi', t_state) - - temp.Blend(new /icon('icons/inventory/feet/mob.dmi', t_state), ICON_OVERLAY) - else - temp = new /icon('icons/inventory/uniform/mob.dmi', "grey") - temp.Blend(new /icon('icons/inventory/feet/mob.dmi', "black"), ICON_OVERLAY) - - preview_icon.Blend(temp, ICON_OVERLAY) - - qdel(temp) - - return preview_icon - -/datum/datacore/proc/CreateGeneralRecord(var/mob/living/carbon/human/H, var/id) - ResetPDAManifest() - var/icon/front - var/icon/side - if(H) - front = getFlatIcon(H, SOUTH) - side = getFlatIcon(H, WEST) - else - var/mob/living/carbon/human/dummy = new() - front = new(get_id_photo(dummy), dir = SOUTH) - side = new(get_id_photo(dummy), dir = WEST) - qdel(dummy) - - if(!id) id = text("[]", add_zero(num2hex(rand(1, 1.6777215E7)), 6)) - var/datum/data/record/G = new /datum/data/record() - G.name = "Employee Record #[id]" - G.fields["name"] = "New Record" - G.fields["id"] = id - G.fields["rank"] = "Unassigned" - G.fields["real_rank"] = "Unassigned" - G.fields["sex"] = "Male" - G.fields["age"] = "Unknown" - G.fields["fingerprint"] = "Unknown" - G.fields["p_stat"] = "Active" - G.fields["m_stat"] = "Stable" - G.fields["species"] = SPECIES_HUMAN - G.fields["photo_front"] = front - G.fields["photo_side"] = side - G.fields["notes"] = "No notes found." - general += G - - return G - -/datum/datacore/proc/CreateSecurityRecord(var/name, var/id) - ResetPDAManifest() - var/datum/data/record/R = new /datum/data/record() - R.name = "Security Record #[id]" - R.fields["name"] = name - R.fields["id"] = id - R.fields["criminal"] = "None" - R.fields["mi_crim"] = "None" - R.fields["mi_crim_d"] = "No minor crime convictions." - R.fields["ma_crim"] = "None" - R.fields["ma_crim_d"] = "No major crime convictions." - R.fields["notes"] = "No notes." - R.fields["notes"] = "No notes." - data_core.security += R - - return R - -/datum/datacore/proc/CreateMedicalRecord(var/name, var/id) - ResetPDAManifest() - var/datum/data/record/M = new() - M.name = "Medical Record #[id]" - M.fields["id"] = id - M.fields["name"] = name - M.fields["b_type"] = "AB+" - M.fields["b_dna"] = md5(name) - M.fields["mi_dis"] = "None" - M.fields["mi_dis_d"] = "No minor disabilities have been declared." - M.fields["ma_dis"] = "None" - M.fields["ma_dis_d"] = "No major disabilities have been diagnosed." - M.fields["alg"] = "None" - M.fields["alg_d"] = "No allergies have been detected in this patient." - M.fields["cdi"] = "None" - M.fields["cdi_d"] = "No diseases have been diagnosed at the moment." - M.fields["notes"] = "No notes found." - data_core.medical += M - - return M - -/datum/datacore/proc/ResetPDAManifest() - if(PDA_Manifest.len) - PDA_Manifest.Cut() - -/proc/find_general_record(field, value) - return find_record(field, value, data_core.general) - -/proc/find_medical_record(field, value) - return find_record(field, value, data_core.medical) - -/proc/find_security_record(field, value) - return find_record(field, value, data_core.security) - -/proc/find_record(field, value, list/L) - for(var/datum/data/record/R in L) - if(R.fields[field] == value) - return R - -/*/proc/GetAssignment(var/mob/living/carbon/human/H) - if(H.mind.assigned_role) - return H.mind.assigned_role - else if(H.job) - return H.job - else - return "Unassigned" -*/ -/var/list/acting_rank_prefixes = list("acting", "temporary", "interim", "provisional") - -/proc/make_list_rank(rank) - for(var/prefix in acting_rank_prefixes) - if(findtext(rank, "[prefix] ", 1, 2+length(prefix))) - return copytext(rank, 2+length(prefix)) - return rank - -/datum/datacore/proc/get_manifest_json() - if(PDA_Manifest.len) - return - var/heads[0] - var/sec[0] - var/eng[0] - var/med[0] - var/sci[0] - var/chr[0] - var/civ[0] - var/bot[0] - var/misc[0] - for(var/datum/data/record/t in data_core.general) - var/name = sanitize(t.fields["name"]) - var/rank = sanitize(t.fields["rank"]) - var/real_rank = make_list_rank(t.fields["real_rank"]) - - var/isactive = t.fields["p_stat"] - var/department = 0 - var/depthead = 0 // Department Heads will be placed at the top of their lists. - if(real_rank in command_positions) - heads[++heads.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - depthead = 1 - if(rank=="Captain" && heads.len != 1) - heads.Swap(1, heads.len) - - if(real_rank in security_positions) - sec[++sec.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && sec.len != 1) - sec.Swap(1, sec.len) - - if(real_rank in engineering_positions) - eng[++eng.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && eng.len != 1) - eng.Swap(1, eng.len) - - if(real_rank in medical_positions) - med[++med.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && med.len != 1) - med.Swap(1, med.len) - - if(real_rank in science_positions) - sci[++sci.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && sci.len != 1) - sci.Swap(1, sci.len) - - if(real_rank in church_positions) - chr[++chr.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && chr.len != 1) - chr.Swap(1, chr.len) - - if(real_rank in civilian_positions) - civ[++civ.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - if(depthead && civ.len != 1) - civ.Swap(1, civ.len) - - if(real_rank in nonhuman_positions) - bot[++bot.len] = list("name" = name, "rank" = rank, "active" = isactive) - department = 1 - - if(!department && !(name in heads)) - misc[++misc.len] = list("name" = name, "rank" = rank, "active" = isactive) - - - PDA_Manifest = list( - "heads" = heads, - "sec" = sec, - "eng" = eng, - "med" = med, - "sci" = sci, - "chr" = chr, - "civ" = civ, - "bot" = bot, - "misc" = misc - ) - ManifestJSON = json_encode(PDA_Manifest) - return diff --git a/code/datums/setup_option/backgrounds/fate.dm b/code/datums/setup_option/backgrounds/fate.dm index 8093c95bbc3..3cda4c9d8e7 100644 --- a/code/datums/setup_option/backgrounds/fate.dm +++ b/code/datums/setup_option/backgrounds/fate.dm @@ -26,7 +26,7 @@ You were always on the move, looking for a brighter future on the other side. \ And because of that you never specialised as much as you should, but have broader array of other skills." - perks = list(PERK_FREELACER) + perks = list(PERK_FREELANCER) /datum/category_item/setup_option/background/fate/nihilist name = "Nihilist" diff --git a/code/datums/topic/admin.dm b/code/datums/topic/admin.dm index 8200320a178..f3af9e40f72 100644 --- a/code/datums/topic/admin.dm +++ b/code/datums/topic/admin.dm @@ -387,8 +387,8 @@ body += source.formatJobGroup(M, "Church Positions", "ecd37d", "churchdept", church_positions) //Civilian (Grey) body += source.formatJobGroup(M, "Civilian Positions", "dddddd", "civiliandept", civilian_positions) - //Non-Human (Green) - body += source.formatJobGroup(M, "Non-human Positions", "ccffcc", "nonhumandept", nonhuman_positions + "Antag HUD") + //Silicon (Green) + body += source.formatJobGroup(M, "Non-human Positions", "ccffcc", "silicondept", silicon_positions + "Antag HUD") //Antagonist (Orange) var/jobban_list = list() @@ -459,9 +459,9 @@ var/datum/job/temp = SSjob.GetJob(jobPos) if(!temp) continue joblist += temp.title - if("nonhumandept") + if("silicondept") joblist += "pAI" - for(var/jobPos in nonhuman_positions) + for(var/jobPos in silicon_positions) if(!jobPos) continue var/datum/job/temp = SSjob.GetJob(jobPos) if(!temp) continue diff --git a/code/datums/topic/world.dm b/code/datums/topic/world.dm index f596fd2b7b5..0d9b2df53c0 100644 --- a/code/datums/topic/world.dm +++ b/code/datums/topic/world.dm @@ -94,31 +94,16 @@ /datum/world_topic/manifest/Run(list/input) var/list/positions = list() - var/list/set_names = list( - "heads" = command_positions, - "sec" = security_positions, - "eng" = engineering_positions, - "med" = medical_positions, - "sci" = science_positions, - "car" = cargo_positions, - "civ" = civilian_positions, - "chr" = church_positions, - "bot" = nonhuman_positions - ) - - for(var/datum/data/record/t in data_core.general) - var/name = t.fields["name"] - var/rank = t.fields["rank"] - var/real_rank = make_list_rank(t.fields["real_rank"]) - - var/department = FALSE - for(var/k in set_names) - if(real_rank in set_names[k]) - if(!positions[k]) - positions[k] = list() - positions[k][name] = rank - department = TRUE - if(!department) + + for(var/datum/computer_file/report/crew_record/t in GLOB.all_crew_records) + var/name = t.get_name() + var/rank = t.get_job() + + var/department = t.get_department() + + if(department && department != "Unset") + positions[department][name] = rank + else if(!positions["misc"]) positions["misc"] = list() positions["misc"][name] = rank diff --git a/code/datums/uplink/announcements.dm b/code/datums/uplink/announcements.dm index ae51fc9b055..694d0563cb3 100644 --- a/code/datums/uplink/announcements.dm +++ b/code/datums/uplink/announcements.dm @@ -38,48 +38,42 @@ return 0 var/obj/item/card/id/I = user.GetIdCard() - var/datum/data/record/random_general_record - var/datum/data/record/random_medical_record - if(data_core.general.len) - random_general_record = pick(data_core.general) - random_medical_record = find_medical_record("id", random_general_record.fields["id"]) + var/datum/computer_file/report/crew_record/random_record + if(GLOB.all_crew_records.len) + random_record = pick(GLOB.all_crew_records) - var/datum/data/record/general = data_core.CreateGeneralRecord(user) + var/datum/computer_file/report/crew_record/general = new() if(I) - general.fields["age"] = I.age - general.fields["rank"] = I.assignment - general.fields["real_rank"] = I.assignment - general.fields["name"] = I.registered_name - general.fields["sex"] = I.sex + general.set_age(I.age) + general.set_job(I.assignment) + general.set_name(I.registered_name) + general.set_sex(I.sex) else var/mob/living/carbon/human/H if(ishuman(user)) H = user - general.fields["age"] = H.age + general.set_age(H.age) else - general.fields["age"] = initial(H.age) + general.set_age(initial(H.age)) var/assignment = GetAssignment(user) - general.fields["rank"] = assignment - general.fields["real_rank"] = assignment - general.fields["name"] = user.real_name - general.fields["sex"] = capitalize(user.gender) + general.set_job(assignment) + general.set_department(args["department"]) + general.set_name(user.real_name) + general.set_sex(capitalize(user.gender)) - general.fields["species"] = user.get_species() - var/datum/data/record/medical = data_core.CreateMedicalRecord(general.fields["name"], general.fields["id"]) - data_core.CreateSecurityRecord(general.fields["name"], general.fields["id"]) + general.set_species(user.get_species()) - if(!random_general_record) - general.fields["fingerprint"] = random_general_record.fields["fingerprint"] - if(random_medical_record) - medical.fields["b_type"] = random_medical_record.fields["b_type"] - medical.fields["b_dna"] = random_medical_record.fields["b_type"] + if(random_record) + general.set_fingerprint(random_record.get_fingerprint()) + general.set_bloodtype(random_record.get_bloodtype()) + general.set_dna(random_record.get_bloodtype()) if(I) - general.fields["fingerprint"] = I.fingerprint_hash - medical.fields["b_type"] = I.blood_type - medical.fields["b_dna"] = I.dna_hash + general.set_fingerprint(I.fingerprint_hash) + general.set_bloodtype(I.blood_type) + general.set_dna(I.dna_hash) - AnnounceArrival(general.fields["name"], general.fields["rank"], "has completed cryogenic revival") + AnnounceArrival(general.get_name(), general.get_job(), "has completed cryogenic revival") return 1 /datum/uplink_item/abstract/announcements/fake_ion_storm diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm index 414f37d219f..8c30760d562 100644 --- a/code/defines/procs/announce.dm +++ b/code/defines/procs/announce.dm @@ -119,4 +119,7 @@ datum/announcement/proc/Log(message as text, message_title as text) if(issilicon(character)) global_announcer.autosay("A new [rank] [join_message].", ANNOUNCER_NAME, use_text_to_speech = TRUE) else - global_announcer.autosay("[character.real_name], [rank], [join_message].", ANNOUNCER_NAME, use_text_to_speech = TRUE) + if(istype(character)) + global_announcer.autosay("[character.real_name], [rank], [join_message].", ANNOUNCER_NAME, use_text_to_speech = TRUE) + else if(istext(character)) + global_announcer.autosay("[character], [rank], [join_message].", ANNOUNCER_NAME, use_text_to_speech = TRUE) // send the text diff --git a/code/game/jobs/jobs.dm b/code/game/jobs/jobs.dm index 4fe53b73120..89df2e1fc66 100644 --- a/code/game/jobs/jobs.dm +++ b/code/game/jobs/jobs.dm @@ -78,7 +78,7 @@ var/list/science_positions = list(JOBS_SCIENCE) var/list/moebius_positions = list(JOBS_MOEBIUS) //BS12 EDIT -var/list/cargo_positions = list(JOBS_CARGO) +var/list/guild_positions = list(JOBS_GUILD) var/list/church_positions = list(JOBS_CHURCH) @@ -90,8 +90,8 @@ var/list/civilian_positions = list(JOBS_CIVILIAN) var/list/security_positions = list(JOBS_SECURITY) var/list/armory_positions = list(JOBS_ARMORY) -var/list/nonhuman_positions = list(JOBS_NONHUMAN) +var/list/silicon_positions = list(JOBS_SILICON) /proc/guest_jobbans(var/job) - return ((job in command_positions) || (job in nonhuman_positions) || (job in armory_positions)) + return ((job in command_positions) || (job in silicon_positions) || (job in armory_positions)) diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 12f408b42ef..622b5b938d9 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -1193,7 +1193,7 @@ FIRE ALARM /obj/machinery/firealarm/Destroy() GLOB.firealarm_list -= src - ..() + . = ..() /* FIRE ALARM CIRCUIT diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index 7e5e36a2e6b..c2da5fc236f 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -22,7 +22,7 @@ /obj/machinery/computer/Destroy() GLOB.computer_list -= src - ..() + . = ..() /obj/machinery/computer/Process() if(stat & (NOPOWER|BROKEN)) diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm deleted file mode 100644 index c657a915e49..00000000000 --- a/code/game/machinery/computer/medical.dm +++ /dev/null @@ -1,519 +0,0 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 - -/obj/machinery/computer/med_data//TODO:SANITY - name = "medical records console" - desc = "Used to view, edit and maintain medical records." - icon_keyboard = "med_key" - icon_screen = "medcomp" - light_color = COLOR_LIGHTING_GREEN_MACHINERY - req_one_access = list(access_moebius, access_forensics_lockers) - circuit = /obj/item/electronics/circuitboard/med_data - var/obj/item/card/id/scan - var/authenticated - var/rank - var/screen - var/datum/data/record/active1 - var/datum/data/record/active2 - var/a_id - var/temp - var/printing - -/obj/machinery/computer/med_data/verb/eject_id() - set category = "Object" - set name = "Eject ID Card" - set src in oview(1) - - if(!usr || usr.stat || usr.lying) return - - if(scan) - to_chat(usr, "You remove \the [scan] from \the [src].") - scan.loc = get_turf(src) - if(!usr.get_active_hand() && ishuman(usr)) - usr.put_in_hands(scan) - scan = null - else - to_chat(usr, "There is nothing to remove from the console.") - return - -/obj/machinery/computer/med_data/attackby(var/obj/item/O, var/mob/user) - if(istype(O, /obj/item/card/id) && !scan && user.unEquip(O)) - O.loc = src - scan = O - to_chat(user, "You insert \the [O].") - else - ..() - -/obj/machinery/computer/med_data/attack_hand(mob/user as mob) - if(..()) - return - nano_ui_interact(user) - -/obj/machinery/computer/med_data/nano_ui_interact(mob/user) - var/dat - if (src.temp) - dat = text("[src.temp]

Clear Screen") - else - dat = text("Confirm Identity: []
", src, (src.scan ? text("[]", src.scan.name) : "----------")) - if (src.authenticated) - switch(src.screen) - if(1) - dat += {" -Search Records -
List Records -
Medbot Tracking -
-
Record Maintenance -
{Log Out}
-"} - if(2) - dat += "Record List:
" - if(!isnull(data_core.general)) - for(var/datum/data/record/R in sortRecord(data_core.general)) - dat += text("[]: []
", src, R, R.fields["id"], R.fields["name"]) - //Foreach goto(132) - dat += text("
Back", src) - if(3) - dat += text("Records Maintenance
\nBackup To Disk
\nUpload From disk
\nDelete All Records
\n
\nBack", src, src, src, src) - if(4) - var/icon/front = active1.fields["photo_front"] - var/icon/side = active1.fields["photo_side"] - user << browse_rsc(front, "front.png") - user << browse_rsc(side, "side.png") - dat += "
Medical Record

" - if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1))) - dat += "
Name: [active1.fields["name"]] \ - ID: [active1.fields["id"]]
\n \ - Sex: [active1.fields["sex"]]
\n \ - Age: [active1.fields["age"]]
\n \ - Fingerprint: [active1.fields["fingerprint"]]
\n \ - Physical Status: [active1.fields["p_stat"]]
\n \ - Mental Status: [active1.fields["m_stat"]]
\ - Photo:
" - else - dat += "General Record Lost!
" - if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2))) - dat += text("
\n
Medical Data

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

", src, src.active2.fields["b_type"], src, src.active2.fields["b_dna"], src, src.active2.fields["mi_dis"], src, src.active2.fields["mi_dis_d"], src, src.active2.fields["ma_dis"], src, src.active2.fields["ma_dis_d"], src, src.active2.fields["alg"], src, src.active2.fields["alg_d"], src, src.active2.fields["cdi"], src, src.active2.fields["cdi_d"], src, decode(src.active2.fields["notes"])) - var/counter = 1 - while(src.active2.fields[text("com_[]", counter)]) - dat += text("[]
Delete Entry

", src.active2.fields[text("com_[]", counter)], src, counter) - counter++ - dat += text("Add Entry

", src) - dat += text("Delete Record (Medical Only)

", src) - else - dat += "Medical Record Lost!
" - dat += text("New Record

") - dat += text("\nPrint Record
\nBack
", src, src) - if(6) - dat += "
Medical Robot Monitor
" - dat += "Back" - dat += "
Medical Robots:" - var/bdat - for(var/mob/living/bot/medbot/M in world) - - if(M.z != src.z) continue //only find medibots on the same z-level as the computer - var/turf/bl = get_turf(M) - if(bl) //if it can't find a turf for the medibot, then it probably shouldn't be showing up - bdat += "[M.name] - \[[bl.x],[bl.y]\] - [M.on ? "Online" : "Offline"]
" - if((!isnull(M.reagent_glass)) && M.use_beaker) - bdat += "Reservoir: \[[M.reagent_glass.reagents.total_volume]/[M.reagent_glass.reagents.maximum_volume]\]
" - else - bdat += "Using Internal Synthesizer.
" - if(!bdat) - dat += "
None detected
" - else - dat += "
[bdat]" - - else - else - dat += text("{Log In}", src) - user << browse(text("Medical Records[]", dat), "window=med_rec") - onclose(user, "med_rec") - return - -/obj/machinery/computer/med_data/Topic(href, href_list) - if(..()) - return 1 - - if (!( data_core.general.Find(src.active1) )) - src.active1 = null - - if (!( data_core.medical.Find(src.active2) )) - src.active2 = null - - if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (issilicon(usr))) - usr.set_machine(src) - - if (href_list["temp"]) - src.temp = null - - if (href_list["scan"]) - if (src.scan) - - if(ishuman(usr)) - scan.loc = usr.loc - - if(!usr.get_active_hand()) - usr.put_in_hands(scan) - - scan = null - - else - src.scan.loc = src.loc - src.scan = null - - else - var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/card/id)) - usr.drop_item() - I.loc = src - src.scan = I - - else if (href_list["logout"]) - src.authenticated = null - src.screen = null - src.active1 = null - src.active2 = null - - else if (href_list["login"]) - - if (isAI(usr)) - src.active1 = null - src.active2 = null - src.authenticated = usr.name - src.rank = "AI" - src.screen = 1 - - else if (isrobot(usr)) - src.active1 = null - src.active2 = null - src.authenticated = usr.name - var/mob/living/silicon/robot/R = usr - src.rank = "[R.modtype] [R.braintype]" - src.screen = 1 - - else if (istype(src.scan, /obj/item/card/id)) - src.active1 = null - src.active2 = null - - if (src.check_access(src.scan)) - src.authenticated = src.scan.registered_name - src.rank = src.scan.assignment - src.screen = 1 - - if (src.authenticated) - - if(href_list["screen"]) - src.screen = text2num(href_list["screen"]) - if(src.screen < 1) - src.screen = 1 - - src.active1 = null - src.active2 = null - - if (href_list["del_all"]) - src.temp = text("Are you sure you wish to delete all records?
\n\tYes
\n\tNo
", src, src) - - if (href_list["del_all2"]) - for(var/datum/data/record/R in data_core.medical) - //R = null - qdel(R) - //Foreach goto(494) - src.temp = "All records deleted." - - if (href_list["field"]) - var/a1 = src.active1 - var/a2 = src.active2 - switch(href_list["field"]) - if("fingerprint") - if (istype(src.active1, /datum/data/record)) - var/t1 = sanitize(input("Please input fingerprint hash:", "Med. records", src.active1.fields["fingerprint"], null) as text) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active1 != a1)) - return - src.active1.fields["fingerprint"] = t1 - if("sex") - if (istype(src.active1, /datum/data/record)) - if (src.active1.fields["sex"] == "Male") - src.active1.fields["sex"] = "Female" - else - src.active1.fields["sex"] = "Male" - if("age") - if (istype(src.active1, /datum/data/record)) - var/t1 = input("Please input age:", "Med. records", src.active1.fields["age"], null) as num - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active1 != a1)) - return - src.active1.fields["age"] = t1 - if("mi_dis") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please input minor disabilities list:", "Med. records", src.active2.fields["mi_dis"], null) as text) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2)) - return - src.active2.fields["mi_dis"] = t1 - if("mi_dis_d") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null) as message) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2)) - return - src.active2.fields["mi_dis_d"] = t1 - if("ma_dis") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please input major diabilities list:", "Med. records", src.active2.fields["ma_dis"], null) as text) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2)) - return - src.active2.fields["ma_dis"] = t1 - if("ma_dis_d") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null) as message) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2)) - return - src.active2.fields["ma_dis_d"] = t1 - if("alg") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please state allergies:", "Med. records", src.active2.fields["alg"], null) as text) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2)) - return - src.active2.fields["alg"] = t1 - if("alg_d") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null) as message) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2)) - return - src.active2.fields["alg_d"] = t1 - if("cdi") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please state diseases:", "Med. records", src.active2.fields["cdi"], null) as text) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2)) - return - src.active2.fields["cdi"] = t1 - if("cdi_d") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null) as message) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2)) - return - src.active2.fields["cdi_d"] = t1 - if("notes") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize notes:", "Med. records", html_decode(src.active2.fields["notes"]), null) as message, extra = 0) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2)) - return - src.active2.fields["notes"] = t1 - if("p_stat") - if (istype(src.active1, /datum/data/record)) - src.temp = text("Physical Condition:
\n\t*Deceased*
\n\t*SSD*
\n\tActive
\n\tPhysically Unfit
\n\tDisabled
", src, src, src, src, src) - if("m_stat") - if (istype(src.active1, /datum/data/record)) - src.temp = text("Mental Condition:
\n\t*Insane*
\n\t*Unstable*
\n\t*Watch*
\n\tStable
", src, src, src, src) - if("b_type") - if (istype(src.active2, /datum/data/record)) - src.temp = text("Blood Type:
\n\tA- A+
\n\tB- B+
\n\tAB- AB+
\n\tO- O+
", src, src, src, src, src, src, src, src) - if("b_dna") - if (istype(src.active2, /datum/data/record)) - var/t1 = sanitize(input("Please input DNA hash:", "Med. records", src.active2.fields["b_dna"], null) as text) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2)) - return - src.active2.fields["b_dna"] = t1 - else - - if (href_list["p_stat"]) - if (src.active1) - switch(href_list["p_stat"]) - if("deceased") - src.active1.fields["p_stat"] = "*Deceased*" - if("ssd") - src.active1.fields["p_stat"] = "*SSD*" - if("active") - src.active1.fields["p_stat"] = "Active" - if("unfit") - src.active1.fields["p_stat"] = "Physically Unfit" - if("disabled") - src.active1.fields["p_stat"] = "Disabled" - if(PDA_Manifest.len) - PDA_Manifest.Cut() - - if (href_list["m_stat"]) - if (src.active1) - switch(href_list["m_stat"]) - if("insane") - src.active1.fields["m_stat"] = "*Insane*" - if("unstable") - src.active1.fields["m_stat"] = "*Unstable*" - if("watch") - src.active1.fields["m_stat"] = "*Watch*" - if("stable") - src.active1.fields["m_stat"] = "Stable" - - - if (href_list["b_type"]) - if (src.active2) - switch(href_list["b_type"]) - if("an") - src.active2.fields["b_type"] = "A-" - if("bn") - src.active2.fields["b_type"] = "B-" - if("abn") - src.active2.fields["b_type"] = "AB-" - if("on") - src.active2.fields["b_type"] = "O-" - if("ap") - src.active2.fields["b_type"] = "A+" - if("bp") - src.active2.fields["b_type"] = "B+" - if("abp") - src.active2.fields["b_type"] = "AB+" - if("op") - src.active2.fields["b_type"] = "O+" - - - if (href_list["del_r"]) - if (src.active2) - src.temp = text("Are you sure you wish to delete the record (Medical Portion Only)?
\n\tYes
\n\tNo
", src, src) - - if (href_list["del_r2"]) - if (src.active2) - //src.active2 = null - qdel(src.active2) - - if (href_list["d_rec"]) - var/datum/data/record/R = locate(href_list["d_rec"]) - var/datum/data/record/M = locate(href_list["d_rec"]) - if (!( data_core.general.Find(R) )) - src.temp = "Record Not Found!" - return - for(var/datum/data/record/E in data_core.medical) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - M = E - else - //Foreach continue //goto(2540) - src.active1 = R - src.active2 = M - src.screen = 4 - - if (href_list["new"]) - if ((istype(src.active1, /datum/data/record) && !( istype(src.active2, /datum/data/record) ))) - var/datum/data/record/R = new /datum/data/record( ) - R.fields["name"] = src.active1.fields["name"] - R.fields["id"] = src.active1.fields["id"] - R.name = text("Medical Record #[]", R.fields["id"]) - R.fields["b_type"] = "Unknown" - R.fields["b_dna"] = "Unknown" - R.fields["mi_dis"] = "None" - R.fields["mi_dis_d"] = "No minor disabilities have been declared." - R.fields["ma_dis"] = "None" - R.fields["ma_dis_d"] = "No major disabilities have been diagnosed." - R.fields["alg"] = "None" - R.fields["alg_d"] = "No allergies have been detected in this patient." - R.fields["cdi"] = "None" - R.fields["cdi_d"] = "No diseases have been diagnosed at the moment." - R.fields["notes"] = "No notes." - data_core.medical += R - src.active2 = R - src.screen = 4 - - if (href_list["add_c"]) - if (!( istype(src.active2, /datum/data/record) )) - return - var/a2 = src.active2 - var/t1 = sanitize(input("Add Comment:", "Med. records", null, null) as message) - if ((!( t1 ) || !( src.authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || src.active2 != a2)) - return - var/counter = 1 - while(src.active2.fields[text("com_[]", counter)]) - counter++ - src.active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD")] [stationtime2text()], [game_year]
[t1]") - - if (href_list["del_c"]) - if ((istype(src.active2, /datum/data/record) && src.active2.fields[text("com_[]", href_list["del_c"])])) - src.active2.fields[text("com_[]", href_list["del_c"])] = "Deleted" - - if (href_list["search"]) - var/t1 = input("Search String: (Name, DNA, or ID)", "Med. records", null, null) as text - if ((!( t1 ) || usr.stat || !( src.authenticated ) || usr.restrained() || ((!in_range(src, usr)) && (!issilicon(usr))))) - return - src.active1 = null - src.active2 = null - t1 = lowertext(t1) - for(var/datum/data/record/R in data_core.medical) - if ((lowertext(R.fields["name"]) == t1 || t1 == lowertext(R.fields["id"]) || t1 == lowertext(R.fields["b_dna"]))) - src.active2 = R - else - //Foreach continue //goto(3229) - if (!( src.active2 )) - src.temp = text("Could not locate record [].", t1) - else - for(var/datum/data/record/E in data_core.general) - if ((E.fields["name"] == src.active2.fields["name"] || E.fields["id"] == src.active2.fields["id"])) - src.active1 = E - else - //Foreach continue //goto(3334) - src.screen = 4 - - if (href_list["print_p"]) - if (!( src.printing )) - src.printing = 1 - var/datum/data/record/record1 - var/datum/data/record/record2 - if ((istype(src.active1, /datum/data/record) && data_core.general.Find(src.active1))) - record1 = active1 - if ((istype(src.active2, /datum/data/record) && data_core.medical.Find(src.active2))) - record2 = active2 - sleep(50) - var/obj/item/paper/P = new /obj/item/paper( src.loc ) - P.info = "
Medical Record

" - if (record1) - P.info += text("Name: [] ID: []
\nSex: []
\nAge: []
\nFingerprint: []
\nPhysical Status: []
\nMental Status: []
", record1.fields["name"], record1.fields["id"], record1.fields["sex"], record1.fields["age"], record1.fields["fingerprint"], record1.fields["p_stat"], record1.fields["m_stat"]) - P.name = text("Medical Record ([])", record1.fields["name"]) - else - P.info += "General Record Lost!
" - P.name = "Medical Record" - if (record2) - P.info += text("
\n
Medical Data

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

", record2.fields["b_type"], record2.fields["b_dna"], record2.fields["mi_dis"], record2.fields["mi_dis_d"], record2.fields["ma_dis"], record2.fields["ma_dis_d"], record2.fields["alg"], record2.fields["alg_d"], record2.fields["cdi"], record2.fields["cdi_d"], decode(record2.fields["notes"])) - var/counter = 1 - while(record2.fields[text("com_[]", counter)]) - P.info += text("[]
", record2.fields[text("com_[]", counter)]) - counter++ - else - P.info += "Medical Record Lost!
" - P.info += "" - src.printing = null - - src.add_fingerprint(usr) - src.updateUsrDialog() - return - -/obj/machinery/computer/med_data/emp_act(severity) - if(stat & (BROKEN|NOPOWER)) - ..(severity) - return - - for(var/datum/data/record/R in data_core.medical) - if(prob(10/severity)) - switch(rand(1,6)) - if(1) - R.fields["name"] = "[pick(pick(GLOB.first_names_male), pick(GLOB.first_names_female))] [pick(GLOB.last_names)]" - if(2) - R.fields["sex"] = pick("Male", "Female") - if(3) - R.fields["age"] = rand(5, 85) - if(4) - R.fields["b_type"] = pick("A-", "B-", "AB-", "O-", "A+", "B+", "AB+", "O+") - if(5) - R.fields["p_stat"] = pick("*SSD*", "Active", "Physically Unfit", "Disabled") - if(PDA_Manifest.len) - PDA_Manifest.Cut() - if(6) - R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable") - continue - - else if(prob(1)) - qdel(R) - continue - - ..(severity) - - -/obj/machinery/computer/med_data/laptop - name = "Medical Laptop" - desc = "A cheap laptop." - icon_state = "laptop" - icon_keyboard = "laptop_key" - icon_screen = "medlaptop" - CheckFaceFlag = 0 diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm deleted file mode 100644 index 62cd2c4e956..00000000000 --- a/code/game/machinery/computer/security.dm +++ /dev/null @@ -1,658 +0,0 @@ -/obj/machinery/computer/secure_data - name = "security records console" - desc = "Used to view, edit and maintain security records" - icon_keyboard = "security_key" - icon_screen = "security" - light_color = COLOR_LIGHTING_SCI_BRIGHT - req_one_access = list(access_security) - circuit = /obj/item/electronics/circuitboard/secure_data - var/obj/item/card/id/scan - var/authenticated - var/rank - var/screen - var/datum/data/record/active1 - var/datum/data/record/active2 - var/a_id - var/temp - var/printing - var/can_change_id = 0 - var/list/Perp - var/tempname - //Sorting Variables - var/sortBy = "name" - var/order = 1 // -1 = Descending - 1 = Ascending - -/obj/machinery/computer/secure_data/verb/eject_id() - set category = "Object" - set name = "Eject ID Card" - set src in oview(1) - - if(!usr || usr.stat || usr.lying) return - - if(scan) - to_chat(usr, "You remove \the [scan] from \the [src].") - scan.loc = get_turf(src) - if(!usr.get_active_hand() && ishuman(usr)) - usr.put_in_hands(scan) - scan = null - else - to_chat(usr, "There is nothing to remove from the console.") - return - -/obj/machinery/computer/secure_data/attackby(obj/item/O as obj, user as mob) - if(istype(O, /obj/item/card/id) && !scan) - usr.drop_item() - O.loc = src - scan = O - to_chat(user, "You insert [O].") - ..() - -//Someone needs to break down the dat += into chunks instead of long ass lines. -/obj/machinery/computer/secure_data/attack_hand(mob/user) - if(..()) - return - nano_ui_interact(user) - -/obj/machinery/computer/secure_data/nano_ui_interact(user) - if (src.z > 6) - to_chat(user, "Unable to establish a connection: You're too far away from the station!") - return - - var/dat - if (temp) - dat = text("[]

Clear Screen", temp, src) - else - dat = text("Confirm Identity: []
", src, (scan ? text("[]", scan.name) : "----------")) - if (authenticated) - switch(screen) - if(1) - dat += {"

"} - dat += text("Search Records
", src) - dat += text("New Record
", src) - dat += {" -

- - - - -
Records:
- - - - - - - -"} - if(!isnull(data_core.general)) - for(var/datum/data/record/R in sortRecord(data_core.general, sortBy, order)) - var/crimstat = "" - for(var/datum/data/record/E in data_core.security) - if ((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"])) - crimstat = E.fields["criminal"] - var/background - switch(crimstat) - if("*Arrest*") - background = "'background-color:#DC143C;'" - if("Incarcerated") - background = "'background-color:#CD853F;'" - if("Parolled") - background = "'background-color:#CD853F;'" - if("Released") - background = "'background-color:#3BB9FF;'" - if("None") - background = "'background-color:#00FF7F;'" - if("") - background = "'background-color:#FFFFFF;'" - crimstat = "No Record." - dat += text("", background, src, R, R.fields["name"]) - dat += text("", R.fields["id"]) - dat += text("", R.fields["rank"]) - dat += text("", R.fields["fingerprint"]) - dat += text("", crimstat) - dat += "
NameIDRankFingerprintsCriminal Status
[][][][][]

" - dat += text("Record Maintenance

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

Back" - if(3) - dat += "
Security Record

" - if ((istype(active1, /datum/data/record) && data_core.general.Find(active1))) - user << browse_rsc(active1.fields["photo_front"], "front.png") - user << browse_rsc(active1.fields["photo_side"], "side.png") - dat += {" - -
- Name: [active1.fields["name"]]
- ID: [active1.fields["id"]]
- Sex: [active1.fields["sex"]]
- Age: [active1.fields["age"]]
- Rank: [active1.fields["rank"]]
- Fingerprint: [active1.fields["fingerprint"]]
- Physical Status: [active1.fields["p_stat"]]
- Mental Status: [active1.fields["m_stat"]]
Photo:
- -

- Update front photo

- Update side photo
-
- "} - else - dat += "General Record Lost!
" - if ((istype(active2, /datum/data/record) && data_core.security.Find(active2))) - dat += "
\n
Security Data

\nCriminal Status: \ - [active2.fields["criminal"]]
\n
\n \ - Minor Crimes: [active2.fields["mi_crim"]]
\n \ - Details: [active2.fields["mi_crim_d"]]
\n
\n\ - Major Crimes: [active2.fields["ma_crim"]]
\n \ - Details: [active2.fields["ma_crim_d"]]
\n
\n \ - Important Notes:
\n\t[decode(active2.fields["notes"])]
\n
\n\ -
Comments/Log

" - var/counter = 1 - while(active2.fields["com_[counter]"]) - dat += text("[]
Delete Entry

", active2.fields["com_[counter]"], src, counter) - counter++ - dat += "Add Entry

" - dat += "Delete Record (Security Only)

" - else - dat += "Security Record Lost!
" - dat += "New Security Record

" - dat += "Delete Record (ALL)

\ - Print Record
\ - Print Wanted Poster
\ - Back
" - if(4) - if(!Perp.len) - dat += text("ERROR. String could not be located.

Back", src) - else - dat += {" - -
Search Results for '[tempname]':
- - - - - - - - - "} - for(var/i=1, i<=Perp.len, i += 2) - var/crimstat = "" - var/datum/data/record/R = Perp[i] - if(istype(Perp[i+1],/datum/data/record/)) - var/datum/data/record/E = Perp[i+1] - crimstat = E.fields["criminal"] - var/background - switch(crimstat) - if("*Arrest*") - background = "'background-color:#DC143C;'" - if("Incarcerated") - background = "'background-color:#CD853F;'" - if("Parolled") - background = "'background-color:#CD853F;'" - if("Released") - background = "'background-color:#3BB9FF;'" - if("None") - background = "'background-color:#00FF7F;'" - if("") - background = "'background-color:#FFFFFF;'" - crimstat = "No Record." - dat += text("", background, src, R, R.fields["name"]) - dat += text("", R.fields["id"]) - dat += text("", R.fields["rank"]) - dat += text("", R.fields["fingerprint"]) - dat += text("", crimstat) - dat += "
NameIDRankFingerprintsCriminal Status
[][][][][]

" - dat += text("
Return to index.", src) - else - else - dat += text("{Log In}", src) - user << browse(text("Security Records[]", dat), "window=secure_rec;size=600x400") - onclose(user, "secure_rec") - return - -/*Revised /N -I can't be bothered to look more of the actual code outside of switch but that probably needs revising too. -What a mess.*/ -/obj/machinery/computer/secure_data/Topic(href, href_list) - if(..()) - return 1 - if (!( data_core.general.Find(active1) )) - active1 = null - if (!( data_core.security.Find(active2) )) - active2 = null - if ((usr.contents.Find(src) || (in_range(src, usr) && istype(loc, /turf))) || (issilicon(usr))) - usr.set_machine(src) - switch(href_list["choice"]) -// SORTING! - if("Sorting") - // Reverse the order if clicked twice - if(sortBy == href_list["sort"]) - if(order == 1) - order = -1 - else - order = 1 - else - // New sorting order! - sortBy = href_list["sort"] - order = initial(order) -//BASIC FUNCTIONS - if("Clear Screen") - temp = null - - if ("Return") - screen = 1 - active1 = null - active2 = null - - if("Confirm Identity") - if (scan) - if(ishuman(usr) && !usr.get_active_hand()) - usr.put_in_hands(scan) - else - scan.loc = get_turf(src) - scan = null - else - var/obj/item/I = usr.get_active_hand() - if (istype(I, /obj/item/card/id) && usr.unEquip(I)) - I.loc = src - scan = I - - if("Log Out") - authenticated = null - screen = null - active1 = null - active2 = null - - if("Log In") - if (isAI(usr)) - src.active1 = null - src.active2 = null - src.authenticated = usr.name - src.rank = "AI" - src.screen = 1 - else if (isrobot(usr)) - src.active1 = null - src.active2 = null - src.authenticated = usr.name - var/mob/living/silicon/robot/R = usr - src.rank = "[R.modtype] [R.braintype]" - src.screen = 1 - else if (istype(scan, /obj/item/card/id)) - active1 = null - active2 = null - if(check_access(scan)) - authenticated = scan.registered_name - rank = scan.assignment - screen = 1 -//RECORD FUNCTIONS - if("Search Records") - var/t1 = input("Search String: (Partial Name or ID or Fingerprints or Rank)", "Secure. records", null, null) as text - if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || !in_range(src, usr))) - return - Perp = new/list() - t1 = lowertext(t1) - var/list/components = splittext(t1, " ") - if(components.len > 5) - return //Lets not let them search too greedily. - for(var/datum/data/record/R in data_core.general) - var/temptext = R.fields["name"] + " " + R.fields["id"] + " " + R.fields["fingerprint"] + " " + R.fields["rank"] - for(var/i = 1, i<=components.len, i++) - if(findtext(temptext,components[i])) - var/prelist = new/list(2) - prelist[1] = R - Perp += prelist - for(var/i = 1, i<=Perp.len, i+=2) - for(var/datum/data/record/E in data_core.security) - var/datum/data/record/R = Perp[i] - if ((E.fields["name"] == R.fields["name"] && E.fields["id"] == R.fields["id"])) - Perp[i+1] = E - tempname = t1 - screen = 4 - - if("Record Maintenance") - screen = 2 - active1 = null - active2 = null - - if ("Browse Record") - var/datum/data/record/R = locate(href_list["d_rec"]) - var/S = locate(href_list["d_rec"]) - if (!( data_core.general.Find(R) )) - temp = "Record Not Found!" - else - for(var/datum/data/record/E in data_core.security) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - S = E - active1 = R - active2 = S - screen = 3 - -/* if ("Search Fingerprints") - var/t1 = input("Search String: (Fingerprint)", "Secure. records", null, null) as text - if ((!( t1 ) || usr.stat || !( authenticated ) || usr.restrained() || (!in_range(src, usr)) && (!issilicon(usr)))) - return - active1 = null - active2 = null - t1 = lowertext(t1) - for(var/datum/data/record/R in data_core.general) - if (lowertext(R.fields["fingerprint"]) == t1) - active1 = R - if (!( active1 )) - temp = text("Could not locate record [].", t1) - else - for(var/datum/data/record/E in data_core.security) - if ((E.fields["name"] == active1.fields["name"] || E.fields["id"] == active1.fields["id"])) - active2 = E - screen = 3 */ - - if ("Print Record") - if (!( printing )) - printing = 1 - var/datum/data/record/record1 = null - var/datum/data/record/record2 = null - if ((istype(active1, /datum/data/record) && data_core.general.Find(active1))) - record1 = active1 - if ((istype(active2, /datum/data/record) && data_core.security.Find(active2))) - record2 = active2 - sleep(50) - var/obj/item/paper/P = new /obj/item/paper( loc ) - P.info = "
Security Record

" - if (record1) - P.info += {" - Name: [record1.fields["name"]] ID: [record1.fields["id"]]
- Sex: [record1.fields["sex"]]
- Age: [record1.fields["age"]]
- Fingerprint: [record1.fields["fingerprint"]]
- Physical Status: [record1.fields["p_stat"]]
- Mental Status: [record1.fields["m_stat"]]
- "} - P.name = "Security Record ([record1.fields["name"]])" - else - P.info += "General Record Lost!
" - P.name = "Security Record" - if (record2) - P.info += {" -
Security Data

- Criminal Status: [record2.fields["criminal"]]

- Minor Crimes: [record2.fields["mi_crim"]]
- Details: [record2.fields["mi_crim_d"]]

- Major Crimes: [record2.fields["ma_crim"]]
- Details: [record2.fields["ma_crim_d"]]

- Important Notes:
- \t[decode(record2.fields["notes"])]

-
Comments/Log

- "} - var/counter = 1 - while(record2.fields[text("com_[]", counter)]) - P.info += text("[]
", record2.fields[text("com_[]", counter)]) - counter++ - else - P.info += "Security Record Lost!
" - P.info += "" - printing = null - updateUsrDialog() - - if ("Print Poster") - if(!printing) - var/wanted_name = sanitizeName(input("Please enter an alias for the criminal:", "Print Wanted Poster", active1.fields["name"]) as text, MAX_NAME_LEN, 1) - if(wanted_name) - var/default_description = "A poster declaring [wanted_name] to be a dangerous individual, wanted by Nanotrasen. Report any sightings to security immediately." - var/major_crimes = active2.fields["ma_crim"] - var/minor_crimes = active2.fields["mi_crim"] - default_description += "\n[wanted_name] is wanted for the following crimes:\n" - default_description += "\nMinor Crimes:\n[minor_crimes]\n[active2.fields["mi_crim_d"]]\n" - default_description += "\nMajor Crimes:\n[major_crimes]\n[active2.fields["ma_crim_d"]]\n" - printing = 1 - spawn(30) - playsound(loc, 'sound/items/poster_being_created.ogg', 100, 1) - if((istype(active1, /datum/data/record) && data_core.general.Find(active1)))//make sure the record still exists. - new /obj/item/contraband/poster/wanted(src.loc, active1.fields["photo_front"], wanted_name, default_description) - printing = 0 -//RECORD DELETE - if ("Delete All Records") - temp = "" - temp += "Are you sure you wish to delete all Security records?
" - temp += "Yes
" - temp += "No" - - if ("Purge All Records") - for(var/datum/data/record/R in data_core.security) - qdel(R) - temp = "All Security records deleted." - - if ("Add Entry") - if (!( istype(active2, /datum/data/record) )) - return - var/a2 = active2 - var/t1 = sanitize(input("Add Comment:", "Secure. records", null, null) as message) - if ((!( t1 ) || !( authenticated ) || usr.stat || usr.restrained() || (!in_range(src, usr) && (!issilicon(usr))) || active2 != a2)) - return - var/counter = 1 - while(active2.fields[text("com_[]", counter)]) - counter++ - active2.fields[text("com_[counter]")] = text("Made by [authenticated] ([rank]) on [time2text(world.realtime, "DDD MMM DD")] [stationtime2text()], [game_year]
[t1]") - - if ("Delete Record (ALL)") - if (active1) - temp = "
Are you sure you wish to delete the record (ALL)?
" - temp += "Yes
" - temp += "No" - - if ("Delete Record (Security)") - if (active2) - temp = "
Are you sure you wish to delete the record (Security Portion Only)?
" - temp += "Yes
" - temp += "No" - - if ("Delete Entry") - if ((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])])) - active2.fields[text("com_[]", href_list["del_c"])] = "Deleted" -//RECORD CREATE - if ("New Record (Security)") - if ((istype(active1, /datum/data/record) && !( istype(active2, /datum/data/record) ))) - active2 = data_core.CreateSecurityRecord(active1.fields["name"], active1.fields["id"]) - screen = 3 - - if ("New Record (General)") - active1 = data_core.CreateGeneralRecord() - active2 = null - -//FIELD FUNCTIONS - if ("Edit") - if (is_not_allowed(usr)) - return - var/a1 = active1 - var/a2 = active2 - switch(href_list["field"]) - if("name") - if (istype(active1, /datum/data/record)) - var/t1 = sanitizeName(input("Please input name:", "Secure. records", active1.fields["name"], null) as text) - if (!t1 || active1 != a1) - return - active1.fields["name"] = t1 - if("id") - if (istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please input id:", "Secure. records", active1.fields["id"], null) as text) - if (!t1 || active1 != a1) - return - active1.fields["id"] = t1 - if("fingerprint") - if (istype(active1, /datum/data/record)) - var/t1 = sanitize(input("Please input fingerprint hash:", "Secure. records", active1.fields["fingerprint"], null) as text) - if (!t1 || active1 != a1) - return - active1.fields["fingerprint"] = t1 - if("sex") - if (istype(active1, /datum/data/record)) - if (active1.fields["sex"] == "Male") - active1.fields["sex"] = "Female" - else - active1.fields["sex"] = "Male" - if("age") - if (istype(active1, /datum/data/record)) - var/t1 = input("Please input age:", "Secure. records", active1.fields["age"], null) as num - if (!t1 || active1 != a1) - return - active1.fields["age"] = t1 - if("mi_crim") - if (istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please input minor disabilities list:", "Secure. records", active2.fields["mi_crim"], null) as text) - if (!t1 || active2 != a2) - return - active2.fields["mi_crim"] = t1 - if("mi_crim_d") - if (istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize minor dis.:", "Secure. records", active2.fields["mi_crim_d"], null) as message) - if (!t1 || active2 != a2) - return - active2.fields["mi_crim_d"] = t1 - if("ma_crim") - if (istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please input major diabilities list:", "Secure. records", active2.fields["ma_crim"], null) as text) - if (!t1 || active2 != a2) - return - active2.fields["ma_crim"] = t1 - if("ma_crim_d") - if (istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize major dis.:", "Secure. records", active2.fields["ma_crim_d"], null) as message) - if (!t1 || active2 != a2) - return - active2.fields["ma_crim_d"] = t1 - if("notes") - if (istype(active2, /datum/data/record)) - var/t1 = sanitize(input("Please summarize notes:", "Secure. records", html_decode(active2.fields["notes"]), null) as message, extra = 0) - if (!t1 || active2 != a2) - return - active2.fields["notes"] = t1 - if("criminal") - if (istype(active2, /datum/data/record)) - temp = "
Criminal Status:
" - temp += "" - if("rank") - var/list/L = list( "First Officer", "Captain", "AI" ) - //This was so silly before the change. Now it actually works without beating your head against the keyboard. /N - if ((istype(active1, /datum/data/record) && L.Find(rank))) - temp = "
Rank:
" - temp += "" - else - alert(usr, "You do not have the required rank to do this!") - if("species") - if (istype(active1, /datum/data/record)) - var/t1 = sanitize(input("Please enter race:", "General records", active1.fields["species"], null) as message) - if (!t1 || active1 != a1) - return - active1.fields["species"] = t1 - if("photo front") - var/icon/photo = get_photo(usr) - if(photo) - active1.fields["photo_front"] = photo - if("photo side") - var/icon/photo = get_photo(usr) - if(photo) - active1.fields["photo_side"] = photo - - -//TEMPORARY MENU FUNCTIONS - else//To properly clear as per clear screen. - temp=null - switch(href_list["choice"]) - if ("Change Rank") - if (active1) - active1.fields["rank"] = href_list["rank"] - if(href_list["rank"] in GLOB.joblist) - active1.fields["real_rank"] = href_list["real_rank"] - - if ("Change Criminal Status") - if (active2) - for(var/mob/living/carbon/human/H in GLOB.player_list) - BITSET(H.hud_updateflag, WANTED_HUD) - switch(href_list["criminal2"]) - if("none") - active2.fields["criminal"] = "None" - if("arrest") - active2.fields["criminal"] = "*Arrest*" - if("incarcerated") - active2.fields["criminal"] = "Incarcerated" - if("parolled") - active2.fields["criminal"] = "Parolled" - if("released") - active2.fields["criminal"] = "Released" - - if ("Delete Record (Security) Execute") - if (active2) - qdel(active2) - - if ("Delete Record (ALL) Execute") - if (active1) - for(var/datum/data/record/R in data_core.medical) - if ((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"])) - qdel(R) - else - qdel(active1) - if (active2) - qdel(active2) - else - temp = "This function does not appear to be working at the moment. Our apologies." - - add_fingerprint(usr) - updateUsrDialog() - return - -/obj/machinery/computer/secure_data/proc/is_not_allowed(var/mob/user) - return !src.authenticated || user.stat || user.restrained() || (!in_range(src, user) && (!issilicon(user))) - -/obj/machinery/computer/secure_data/proc/get_photo(var/mob/user) - if(istype(user.get_active_hand(), /obj/item/photo)) - var/obj/item/photo/photo = user.get_active_hand() - return photo.img - if(issilicon(user)) - var/mob/living/silicon/tempAI = usr - var/obj/item/photo/selection = tempAI.GetPicture() - if (selection) - return selection.img - -/obj/machinery/computer/secure_data/emp_act(severity) - if(stat & (BROKEN|NOPOWER)) - ..(severity) - return - - for(var/datum/data/record/R in data_core.security) - if(prob(10/severity)) - switch(rand(1,6)) - if(1) - R.fields["name"] = "[pick(pick(GLOB.first_names_male), pick(GLOB.first_names_female))] [pick(GLOB.last_names)]" - if(2) - R.fields["sex"] = pick("Male", "Female") - if(3) - R.fields["age"] = rand(5, 85) - if(4) - R.fields["criminal"] = pick("None", "*Arrest*", "Incarcerated", "Parolled", "Released") - if(5) - R.fields["p_stat"] = pick("*Unconcious*", "Active", "Physically Unfit") - if(PDA_Manifest.len) - PDA_Manifest.Cut() - if(6) - R.fields["m_stat"] = pick("*Insane*", "*Unstable*", "*Watch*", "Stable") - continue - - else if(prob(1)) - qdel(R) - continue - - ..(severity) - -/obj/machinery/computer/secure_data/detective_computer - icon = 'icons/obj/computer.dmi' - icon_state = "messyfiles" diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 5741b5f4dd3..030d1994869 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -51,7 +51,7 @@ /obj/machinery/door/Destroy() GLOB.all_doors -= src - ..() + . = ..() /obj/machinery/door/can_prevent_fall(above) return above ? density : null diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 84ef9938851..cf5b00ad86d 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -241,9 +241,8 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ var/obj/effect/overlay/hologram = new(T)//Spawn a blank effect at the location. if(caller_id) var/icon/tempicon = new - for(var/datum/data/record/t in data_core.locked) - if(t.fields["name"]==caller_id.name) - tempicon = t.fields["image"] + var/datum/computer_file/report/crew_record/t = get_crewmember_record(caller_id.name) + tempicon = t.photo_front hologram.overlays += getHologramIcon(icon(tempicon)) // Add the callers image as an overlay to keep coloration! else hologram.overlays += A.holo_icon // Add the AI's configured holo Icon diff --git a/code/game/objects/items/devices/lighting/toggleable/flashlight.dm b/code/game/objects/items/devices/lighting/toggleable/flashlight.dm index 4287451346b..35293fa94ec 100644 --- a/code/game/objects/items/devices/lighting/toggleable/flashlight.dm +++ b/code/game/objects/items/devices/lighting/toggleable/flashlight.dm @@ -243,7 +243,7 @@ if(ismob(src.loc)) to_chat(src.loc, SPAN_WARNING("Your flashlight dies. You are alone now.")) turn_off() - else if(cell.percent() <= 25) + else if(cell && (cell.percent() <= 25)) apply_power_deficiency() /obj/item/device/lighting/toggleable/flashlight/attack(mob/living/M, mob/living/user) diff --git a/code/game/objects/items/devices/pipe_painter.dm b/code/game/objects/items/devices/pipe_painter.dm index 386216bf09b..31d157d3bcd 100644 --- a/code/game/objects/items/devices/pipe_painter.dm +++ b/code/game/objects/items/devices/pipe_painter.dm @@ -17,7 +17,7 @@ if(!proximity) return - if(!istype(A,/obj/machinery/atmospherics/pipe) || istype(A,/obj/machinery/atmospherics/pipe/tank) || istype(A,/obj/machinery/atmospherics/pipe/vent) || istype(A,/obj/machinery/atmospherics/pipe/simple/heat_exchanging) || istype(A,/obj/machinery/atmospherics/pipe/simple/insulated) || !in_range(user, A)) + if(!istype(A,/obj/machinery/atmospherics/pipe) || istype(A,/obj/machinery/atmospherics/pipe/vent) || istype(A,/obj/machinery/atmospherics/pipe/simple/heat_exchanging) || istype(A,/obj/machinery/atmospherics/pipe/simple/insulated) || !in_range(user, A)) return var/obj/machinery/atmospherics/pipe/P = A diff --git a/code/game/objects/items/devices/uplink.dm b/code/game/objects/items/devices/uplink.dm index aa9da5de9d1..01cd5aaaf64 100644 --- a/code/game/objects/items/devices/uplink.dm +++ b/code/game/objects/items/devices/uplink.dm @@ -234,14 +234,14 @@ A list of items and costs is stored under the datum of every game mode, alongsid nanoui_data["items"] = items else if(nanoui_menu == 2) var/permanentData[0] - for(var/datum/data/record/L in sortRecord(data_core.locked)) - permanentData[++permanentData.len] = list(Name = L.fields["name"],"id" = L.fields["id"]) + for(var/datum/computer_file/report/crew_record/L in GLOB.all_crew_records) + permanentData[++permanentData.len] = list(Name = L.get_name(), "id" = jointext(L.get_name(), L.get_job())) nanoui_data["exploit_records"] = permanentData else if(nanoui_menu == 21) nanoui_data["exploit_exists"] = 0 - for(var/datum/data/record/L in data_core.locked) - if(L.fields["id"] == exploit_id) + for(var/datum/computer_file/report/crew_record/L in GLOB.all_crew_records) + if(jointext(L.get_name(), L.get_job()) == exploit_id) // datacore used name and job to make their IDs, so this would be the same level of specificity as it was in datacore nanoui_data["exploit"] = list() // Setting this to equal L.fields passes it's variables that are lists as reference instead of value. // We trade off being able to automatically add shit for more control over what gets passed to json // and if it's sanitized for html. diff --git a/code/game/objects/items/weapons/candle.dm b/code/game/objects/items/weapons/candle.dm index d490e7e0c13..0a9a68243c2 100644 --- a/code/game/objects/items/weapons/candle.dm +++ b/code/game/objects/items/weapons/candle.dm @@ -55,7 +55,7 @@ if(!wax) new/obj/item/trash/candle(src.loc) if(ismob(loc)) - src.dropped(usr) + src.dropped(loc) qdel(src) update_icon() if(istype(loc, /turf)) //start a fire if possible diff --git a/code/game/objects/items/weapons/circuitboards/computer/computer.dm b/code/game/objects/items/weapons/circuitboards/computer/computer.dm index f5be72a64bc..9717514e5d0 100644 --- a/code/game/objects/items/weapons/circuitboards/computer/computer.dm +++ b/code/game/objects/items/weapons/circuitboards/computer/computer.dm @@ -18,9 +18,6 @@ build_path = /obj/machinery/computer/borgupload origin_tech = list(TECH_DATA = 4) -/obj/item/electronics/circuitboard/med_data - name = T_BOARD("medical records console") - build_path = /obj/machinery/computer/med_data /obj/item/electronics/circuitboard/communications name = T_BOARD("command and communications console") @@ -33,9 +30,6 @@ build_path = /obj/machinery/computer/teleporter origin_tech = list(TECH_DATA = 2, TECH_BLUESPACE = 2) -/obj/item/electronics/circuitboard/secure_data - name = T_BOARD("security records console") - build_path = /obj/machinery/computer/secure_data /obj/item/electronics/circuitboard/atmos_alert rarity_value = 13.3 diff --git a/code/game/objects/items/weapons/implant/implants/carrion/identity_spider.dm b/code/game/objects/items/weapons/implant/implants/carrion/identity_spider.dm index 8be0c312aa4..5248bde7c36 100644 --- a/code/game/objects/items/weapons/implant/implants/carrion/identity_spider.dm +++ b/code/game/objects/items/weapons/implant/implants/carrion/identity_spider.dm @@ -8,7 +8,7 @@ if(!owner_mob) return if(wearer) - if(wearer.type == /mob/living/carbon/human) + if(ishuman(wearer)) var/obj/item/organ/internal/carrion/core/C = owner_mob.random_organ_by_process(BP_SPCORE) C.absorbed_dna |= wearer.real_name to_chat(owner_mob, SPAN_NOTICE("You absorb [wearer]'s DNA")) diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index c08f5f1a525..ee19caa1e5d 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -245,10 +245,12 @@ /obj/item/storage/briefcase/antimaterial_rifle/populate_contents() new /obj/item/ammo_casing/antim(src) - new /obj/item/part/gun/frame/heavysniper(src) + new /obj/item/gun/projectile/automatic/modular/bolt/sniper(src) new /obj/item/part/gun/modular/grip/serb(src) - new /obj/item/part/gun/modular/mechanism/boltgun(src) - new /obj/item/part/gun/modular/barrel/antim(src) + new /obj/item/part/gun/modular/mechanism/boltgun/heavy(src) + new /obj/item/part/gun/modular/barrel/antim/long(src) + new /obj/item/part/gun/modular/stock/heavy(src) + new /obj/item/part/gun/modular/sights/customizable/scopeheavy(src) /obj/item/storage/box/syndie_kit/toxin name = "toxin kit" diff --git a/code/game/objects/items/weapons/storage/wallets.dm b/code/game/objects/items/weapons/storage/wallets.dm index 4fbe7fa18fe..e4794fea619 100644 --- a/code/game/objects/items/weapons/storage/wallets.dm +++ b/code/game/objects/items/weapons/storage/wallets.dm @@ -86,7 +86,7 @@ if(prob(50)) to_add = pick(/obj/item/spacecash/bundle/c10,/obj/item/spacecash/bundle/c100,/obj/item/spacecash/bundle/c1000,/obj/item/spacecash/bundle/c20,/obj/item/spacecash/bundle/c200,/obj/item/spacecash/bundle/c50,/obj/item/spacecash/bundle/c500) new to_add(src) - to_add = pick(/obj/item/coin/silver, /obj/item/coin/silver, /obj/item/coin/gold, /obj/item/coin/iron, /obj/item/coin/iron, /obj/item/coin/iron) + to_add = pick(/obj/item/coin/silver, /obj/item/coin/silver, /obj/item/coin/gold, /obj/item/coin/plasteel, /obj/item/coin/plasteel, /obj/item/coin/plasteel) new to_add(src) if(prob(20)) new /obj/item/card/id/randomassistant(src) diff --git a/code/game/objects/items/weapons/tools/_tools.dm b/code/game/objects/items/weapons/tools/_tools.dm index 84553c2a515..be2bc5a2dfd 100644 --- a/code/game/objects/items/weapons/tools/_tools.dm +++ b/code/game/objects/items/weapons/tools/_tools.dm @@ -529,7 +529,7 @@ failtypes["damage"] = 2.5 // You can only fail with tools you are holding - if(user && T.loc == user) + if(user && loc == user) failtypes["slip"] = 2 failtypes["swing"] = 1 if(ishuman(user)) diff --git a/code/game/objects/items/weapons/tools/knives.dm b/code/game/objects/items/weapons/tools/knives.dm index 9185df41241..ce70ea421b5 100644 --- a/code/game/objects/items/weapons/tools/knives.dm +++ b/code/game/objects/items/weapons/tools/knives.dm @@ -32,7 +32,7 @@ I.weapon_upgrades = list( GUN_UPGRADE_BAYONET = TRUE, GUN_UPGRADE_MELEEDAMAGE = 5, - GUN_UPGRADE_MELEEPENETRATION = ARMOR_PEN_MODERATE, + GUN_UPGRADE_MELEEPENETRATION = (ARMOR_PEN_MODERATE-1), GUN_UPGRADE_OFFSET = 4 ) I.gun_loc_tag = GUN_UNDERBARREL diff --git a/code/game/objects/items/weapons/tools/mods/_upgrades.dm b/code/game/objects/items/weapons/tools/mods/_upgrades.dm index de7453f9590..dee5b963e1f 100644 --- a/code/game/objects/items/weapons/tools/mods/_upgrades.dm +++ b/code/game/objects/items/weapons/tools/mods/_upgrades.dm @@ -255,6 +255,7 @@ P.forceMove(get_turf(I)) UnregisterSignal(I, COMSIG_ADDVAL) UnregisterSignal(I, COMSIG_APPVAL) + reset_owner() /datum/component/item_upgrade/proc/apply_values(atom/holder) //SIGNAL_HANDLER @@ -327,7 +328,7 @@ G.pierce_multiplier += weapon_upgrades[GUN_UPGRADE_PIERC_MULT] if(weapon_upgrades[GUN_UPGRADE_RICO_MULT]) G.ricochet_multiplier += weapon_upgrades[GUN_UPGRADE_RICO_MULT] - if(weapon_upgrades[GUN_UPGRADE_STEPDELAY_MULT]) + if(!isnull(weapon_upgrades[GUN_UPGRADE_STEPDELAY_MULT])) // so AMR barrel can 0x G.proj_step_multiplier *= weapon_upgrades[GUN_UPGRADE_STEPDELAY_MULT] if(weapon_upgrades[GUN_UPGRADE_FIRE_DELAY_MULT]) G.fire_delay *= weapon_upgrades[GUN_UPGRADE_FIRE_DELAY_MULT] @@ -375,6 +376,12 @@ if(ismob(G.loc)) var/mob/user = G.loc user.update_action_buttons() + if(weapon_upgrades[GUN_UPGRADE_SCOPEVISION]) + G.see_invisible_gun = max(G.see_invisible_gun, weapon_upgrades[GUN_UPGRADE_SCOPEVISION]) // scope stats should take best of class + if(weapon_upgrades[GUN_UPGRADE_SCOPECORRECTION]) + G.scoped_offset_reduction = max(G.scoped_offset_reduction, weapon_upgrades[GUN_UPGRADE_SCOPECORRECTION]) + if(weapon_upgrades[GUN_UPGRADE_DARKSCOPE]) + G.darkness_view = max(G.darkness_view, weapon_upgrades[GUN_UPGRADE_DARKSCOPE]) if(weapon_upgrades[GUN_UPGRADE_THERMAL]) G.vision_flags = SEE_MOBS if(weapon_upgrades[GUN_UPGRADE_GILDED]) @@ -388,6 +395,11 @@ G.armor_divisor += weapon_upgrades[GUN_UPGRADE_MELEEPENETRATION] if(weapon_upgrades[GUN_UPGRADE_ONEHANDPENALTY]) G.recoil = G.recoil.modifyRating(_one_hand_penalty = weapon_upgrades[GUN_UPGRADE_ONEHANDPENALTY]) + if(weapon_upgrades[GUN_UPGRADE_MOVEPENALTY]) + G.recoil = G.recoil.modifyRating(_brace_penalty = weapon_upgrades[GUN_UPGRADE_MOVEPENALTY]) + if(weapon_upgrades[GUN_UPGRADE_RECOILBUILDUP]) + G.recoil = G.recoil.modifyRating(_recoil_buildup = weapon_upgrades[GUN_UPGRADE_RECOILBUILDUP]) + if(weapon_upgrades[GUN_UPGRADE_DNALOCK]) G.dna_compare_samples = TRUE @@ -430,6 +442,14 @@ M.verbs += /obj/item/gun/projectile/automatic/modular/proc/quick_fold // Grant the verb for folding stocks if(weapon_upgrades[GUN_UPGRADE_DEFINE_GRIP]) M.grip_type = weapon_upgrades[GUN_UPGRADE_DEFINE_GRIP] + if(weapon_upgrades[GUN_UPGRADE_DEFINE_LOADER]) + M.load_method = weapon_upgrades[GUN_UPGRADE_DEFINE_LOADER] + if(weapon_upgrades[GUN_UPGRADE_DENY_MAG]) + M.no_internal_mag = TRUE + if(weapon_upgrades[GUN_UPGRADE_DEFINE_WCLASS]) + M.w_class += weapon_upgrades[GUN_UPGRADE_DEFINE_WCLASS] + if(weapon_upgrades[GUN_UPGRADE_SCOPE_POWER]) + M.scope_damage_adds.Add(weapon_upgrades[GUN_UPGRADE_SCOPE_POWER]) for(var/datum/firemode/F in G.firemodes) apply_values_firemode(F) @@ -440,6 +460,29 @@ if(weapon_upgrades[GUN_UPGRADE_FIREMODES]) for(var/FM in weapon_upgrades[GUN_UPGRADE_FIREMODES]) G.add_firemode(FM) + if(istype(G, /obj/item/gun/projectile/automatic/modular)) + if(weapon_upgrades[GUN_UPGRADE_REPLACE_INTERACTIONS]) + var/obj/item/gun/projectile/automatic/modular/interactive = G + var/datum/gunoverrides/overrided = interactive.overridedatum + if(overrided) + var/datum/guninteraction/interaction = weapon_upgrades[GUN_UPGRADE_REPLACE_INTERACTIONS] + interaction.parentgun = G + if(islist(overrided.priorities["[interaction.priority]"])) + var/list/currentpriority = overrided.priorities["[interaction.priority]"] + currentpriority.Add(interaction) + else + overrided.priorities["[interaction.priority]"] = list(interaction) + +/datum/component/item_upgrade/proc/reset_owner() + if(weapon_upgrades[GUN_UPGRADE_REPLACE_INTERACTIONS]) + var/datum/guninteraction/interaction = weapon_upgrades[GUN_UPGRADE_REPLACE_INTERACTIONS] + if(istype(interaction)) + interaction.parentgun = null + if(weapon_upgrades[GUN_UPGRADE_DEFINE_WCLASS]) + if(istype(parent, /obj/item/part/gun/modular/stock)) + var/obj/item/part/gun/modular/stock/base = parent + weapon_upgrades[GUN_UPGRADE_DEFINE_WCLASS] = base.wclassmod + /datum/component/item_upgrade/proc/apply_values_firemode(datum/firemode/F) for(var/i in F.settings) diff --git a/code/game/turfs/simulated/floor_attackby.dm b/code/game/turfs/simulated/floor_attackby.dm index e365e0b9081..fafb07e083f 100644 --- a/code/game/turfs/simulated/floor_attackby.dm +++ b/code/game/turfs/simulated/floor_attackby.dm @@ -128,7 +128,7 @@ if(is_damaged()) if(I.use_tool(user, src, flooring.removal_time, tool_type, FAILCHANCE_VERY_EASY, required_stat = STAT_MEC)) to_chat(user, SPAN_NOTICE("You remove the broken [flooring.descriptor].")) - make_plating() + make_plating(TRUE, null, TRUE) return else if(flooring.flags & TURF_IS_FRAGILE) if(I.use_tool(user, src, flooring.removal_time, tool_type, FAILCHANCE_VERY_EASY, required_stat = STAT_MEC)) @@ -138,7 +138,7 @@ else if(flooring.flags & TURF_REMOVE_CROWBAR) if(I.use_tool(user, src, flooring.removal_time, tool_type, FAILCHANCE_VERY_EASY, required_stat = STAT_MEC)) to_chat(user, SPAN_NOTICE("You lever off the [flooring.descriptor].")) - make_plating(1) + make_plating(TRUE) return return @@ -146,21 +146,21 @@ if((!(is_damaged()) && !is_plating()) || flooring.flags & TURF_REMOVE_SCREWDRIVER) if(I.use_tool(user, src, flooring.removal_time*1.5, tool_type, FAILCHANCE_VERY_EASY, required_stat = STAT_MEC)) to_chat(user, SPAN_NOTICE("You unscrew and remove the [flooring.descriptor].")) - make_plating(1) + make_plating(TRUE) return if(QUALITY_BOLT_TURNING) if(flooring.flags & TURF_REMOVE_WRENCH) if(I.use_tool(user, src, flooring.removal_time, tool_type, FAILCHANCE_NORMAL, required_stat = STAT_MEC)) to_chat(user, SPAN_NOTICE("You unwrench and remove the [flooring.descriptor].")) - make_plating(1) + make_plating(TRUE) return if(QUALITY_SHOVELING) if(flooring.flags & TURF_REMOVE_SHOVEL) if(I.use_tool(user, src, flooring.removal_time, tool_type, FAILCHANCE_VERY_EASY, required_stat = STAT_MEC)) to_chat(user, SPAN_NOTICE("You shovel off the [flooring.descriptor].")) - make_plating(1) + make_plating(TRUE) return if(QUALITY_WELDING) @@ -179,7 +179,7 @@ to_chat(user, SPAN_NOTICE("You start cutting through the [flooring.descriptor].")) if(I.use_tool(user, src, flooring.removal_time, tool_type, FAILCHANCE_NORMAL, required_stat = STAT_MEC)) to_chat(user, SPAN_NOTICE("You cut through and remove the [flooring.descriptor].")) - make_plating(1) + make_plating(TRUE) if(ABORT_CHECK) return diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index a9c97abf497..5adc512afab 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -69,7 +69,9 @@ girder.is_low = is_low_wall girder.is_reinforced = is_reinforced girder.update_icon() - qdel(src) + remove_neighbour_connections() + ChangeTurf(/turf/floor/plating) + updateVisibility(src) /turf/wall/get_matter() return list(MATERIAL_STEEL = 5) diff --git a/code/modules/admin/DB ban/functions.dm b/code/modules/admin/DB ban/functions.dm index 9bfa1824162..2cfe8bb1ec2 100644 --- a/code/modules/admin/DB ban/functions.dm +++ b/code/modules/admin/DB ban/functions.dm @@ -341,7 +341,7 @@ datum/admins/proc/DB_ban_unban_by_id(var/id) output += "" for(var/j in get_all_jobs()) output += "" - for(var/j in nonhuman_positions) + for(var/j in silicon_positions) output += "" var/list/bantypes = list("contractor","carrion","operative","revolutionary","cultist","wizard") //For legacy bans. for(var/ban_type in GLOB.antag_bantypes) // Grab other bans. diff --git a/code/modules/admin/secrets/admin_secrets/show_crew_manifest.dm b/code/modules/admin/secrets/admin_secrets/show_crew_manifest.dm index 3cbe5062e71..e2c57b04d1e 100644 --- a/code/modules/admin/secrets/admin_secrets/show_crew_manifest.dm +++ b/code/modules/admin/secrets/admin_secrets/show_crew_manifest.dm @@ -7,6 +7,6 @@ return var/dat dat += "

Crew Manifest

" - dat += data_core.get_manifest() + dat += html_crew_manifest(TRUE) user << browse(dat, "window=manifest;size=370x420;can_close=1") diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 6231512f112..03737d21e38 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -321,23 +321,8 @@ Contractors and the like can also be revived with the previous role mostly intac var/mob/living/carbon/human/new_character = new()//The mob being spawned. - var/datum/data/record/record_found //Referenced to later to either randomize or not randomize the character. - if(G_found.mind && !G_found.mind.active) //mind isn't currently in use by someone/something - /*Try and locate a record for the person being respawned through data_core. - This isn't an exact science but it does the trick more often than not.*/ - var/id = md5("[G_found.real_name][G_found.mind.assigned_role]") - for(var/datum/data/record/t in data_core.locked) - if(t.fields["id"]==id) - record_found = t//We shall now reference the record. - break - - if(record_found)//If they have a record we can determine a few things. - new_character.real_name = record_found.fields["name"] - new_character.gender = record_found.fields["sex"] - new_character.age = record_found.fields["age"] - new_character.b_type = record_found.fields["b_type"] - new_character.dna_trace = record_found.fields["b_dna"] - new_character.fingers_trace = record_found.fields["fingerprint"] + if(G_found.client?.prefs)//If they have a record we can determine a few things. + G_found.client?.prefs.copy_to(new_character) else new_character.gender = pick(MALE,FEMALE) var/datum/preferences/A = new() @@ -378,12 +363,13 @@ Contractors and the like can also be revived with the previous role mostly intac //Now for special roles and equipment. SSjob.EquipRank(new_character, new_character.mind.assigned_role) + var/datum/computer_file/report/crew_record/record_found = get_crewmember_record(new_character.name) //Announces the character on all the systems, based on the record. if(!issilicon(new_character))//If they are not a cyborg/AI. if(!record_found && !player_is_antag(new_character.mind, only_offstation_roles = 1)) //If there are no records for them. If they have a record, this info is already in there. MODE people are not announced anyway. //Power to the user! - if(alert(new_character,"Warning: No data core entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?",,"No","Yes")=="Yes") - data_core.manifest_inject(new_character) + if(alert(new_character,"Warning: No record entry detected. Would you like to announce the arrival of this character by adding them to various databases, such as medical records?",,"No","Yes")=="Yes") + CreateModularRecord(new_character) if(alert(new_character,"Would you like an active AI to announce this character?",,"No","Yes")=="Yes") call(/proc/AnnounceArrival)(new_character, new_character.mind.assigned_role) diff --git a/code/modules/asset_cache/assets/legacyuiicons.dm b/code/modules/asset_cache/assets/legacyuiicons.dm new file mode 100644 index 00000000000..5051a76d70a --- /dev/null +++ b/code/modules/asset_cache/assets/legacyuiicons.dm @@ -0,0 +1,5 @@ +/datum/asset/spritesheet/legacyicons + name = "oldicons" + +/datum/asset/spritesheet/legacyicons/create_spritesheets() + InsertAll("", 'icons/ui_icons/dmis/uiicons16.dmi') diff --git a/code/modules/client/preference_setup/background/03_records.dm b/code/modules/client/preference_setup/background/03_records.dm index f65d4407d45..59d34b28a9b 100644 --- a/code/modules/client/preference_setup/background/03_records.dm +++ b/code/modules/client/preference_setup/background/03_records.dm @@ -15,9 +15,6 @@ from_file(S["memory"],pref.memory) /datum/category_item/player_setup_item/background/records/save_character(var/savefile/S) - to_file(S["med_record"],pref.med_record) - to_file(S["sec_record"],pref.sec_record) - to_file(S["gen_record"],pref.gen_record) to_file(S["memory"],pref.memory) /datum/category_item/player_setup_item/background/records/content(var/mob/user) @@ -26,33 +23,30 @@ if(jobban_isbanned(user, "Records")) . += "You are banned from using character records.
" else - . += "Medical Records: " - . += "[TextPreview(pref.med_record,40)]
" - . += "Employment Records: " - . += "[TextPreview(pref.gen_record,40)]
" - . += "Security Records: " - . += "[TextPreview(pref.sec_record,40)]
" + if(pref.med_record) + . += "Medical Records: " + . += "[TextPreview(pref.med_record,40)]
" + if(pref.gen_record) + . += "Employment Records: " + . += "[TextPreview(pref.gen_record,40)]
" + if(pref.sec_record) + . += "Security Records: " + . += "[TextPreview(pref.sec_record,40)]
" . += "Memory: " . += "[TextPreview(pref.memory,40)]
" . = jointext(.,null) /datum/category_item/player_setup_item/background/records/OnTopic(var/href,var/list/href_list, var/mob/user) if(href_list["set_medical_records"]) - var/new_medical = sanitize(input(user,"Enter medical information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.med_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0) - if(!isnull(new_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user)) - pref.med_record = new_medical + input(user,"Read medical information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.med_record)) as message|null return TOPIC_REFRESH else if(href_list["set_general_records"]) - var/new_general = sanitize(input(user,"Enter employment information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.gen_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0) - if(!isnull(new_general) && !jobban_isbanned(user, "Records") && CanUseTopic(user)) - pref.gen_record = new_general + input(user,"Read employment information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.gen_record)) as message|null return TOPIC_REFRESH else if(href_list["set_security_records"]) - var/sec_medical = sanitize(input(user,"Enter security information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.sec_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0) - if(!isnull(sec_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user)) - pref.sec_record = sec_medical + input(user,"Read security information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.sec_record)) as message|null return TOPIC_REFRESH else if(href_list["set_memory"]) @@ -62,3 +56,82 @@ return TOPIC_REFRESH . = ..() + +/datum/category_item/player_setup_item/background/records/proc/load_record(savefile/S, recordtype) + var/recordgiven = S["[recordtype]"] + if(S["version"] >= 19) + if(!recordgiven || !(recordtype in pref.vars)) + return FALSE + + if(istype(recordgiven, /datum/storedrecord)) + pref.vars[recordtype] = recordgiven + else + if(istext(recordgiven) && (recordtype in pref.vars)) + pref.vars[recordtype] = recordgiven + + + +/datum/storedrecord + +/datum/storedrecord/proc/transfertocomputer(datum/report_field/tofile) + // nobody here. +/datum/storedrecord/security + var/list/crimes = list() + var/list/evidence = list() + var/list/locations = list() + + +/datum/storedrecord/security/transfertocomputer(datum/report_field/tofile) + if(!istype(tofile, /datum/report_field/arraylinkage)) + return FALSE + var/datum/report_field/arraylinkage/toset = tofile + toset.arrays = list() + toset.arrays["crimes"] = crimes // edit these appropriately on any changes + toset.arrays["evidence"] = evidence // don't forget to synch these indexes + toset.arrays["locations"] = locations + +/datum/storedrecord/security/default // used by default + crimes = list("No crimes on record.") + evidence = list("N/A.") + locations = list("N/A.") + + +/datum/storedrecord/medical + var/list/prosthetics = list() + var/list/wounds = list() + var/list/bodystate = list() + var/list/chemhistory = list() + var/list/psychological = list() + + +/datum/storedrecord/medical/transfertocomputer(datum/report_field/tofile) + if(!istype(tofile, /datum/report_field/arrayclump)) + return FALSE + var/datum/report_field/arrayclump/toset = tofile + var/list/tochange = toset.value + tochange["prosthetics"] = prosthetics // change these appropriately as well + tochange["wounds"] = wounds // but as an arrayclump, they don't need synchronized indexing + tochange["Body state"] = bodystate + tochange["chemhistory"] = chemhistory + tochange["psychological"] = psychological + + +/datum/storedrecord/medical/default // used by default + prosthetics = list("No prosthetics on record.") + wounds = list("No wounds on record.") + bodystate = list("Alive at time of writing.") + chemhistory = list("Chemical record is clean.") + psychological = list("No psychological profiling has been done at time of writing.") + + +/datum/storedrecord/general + var/background // background is defined by fates + var/origin // origin is defined by origin + + + + +/datum/storedrecord/general/default // used by default + background = list("Unremarkable.") + origin = list("Origin unknown.") + diff --git a/code/modules/client/preference_setup/general/05_records.dm b/code/modules/client/preference_setup/general/05_records.dm deleted file mode 100644 index 28767cd3fa4..00000000000 --- a/code/modules/client/preference_setup/general/05_records.dm +++ /dev/null @@ -1,64 +0,0 @@ -/datum/preferences - var/med_record = "" - var/sec_record = "" - var/gen_record = "" - var/memory = "" - -/datum/category_item/player_setup_item/physical/records - name = "Records" - sort_order = 5 - -/datum/category_item/player_setup_item/physical/records/load_character(var/savefile/S) - from_file(S["med_record"],pref.med_record) - from_file(S["sec_record"],pref.sec_record) - from_file(S["gen_record"],pref.gen_record) - from_file(S["memory"],pref.memory) - -/datum/category_item/player_setup_item/physical/records/save_character(var/savefile/S) - to_file(S["med_record"],pref.med_record) - to_file(S["sec_record"],pref.sec_record) - to_file(S["gen_record"],pref.gen_record) - to_file(S["memory"],pref.memory) - -/datum/category_item/player_setup_item/physical/records/content(var/mob/user) - . = list() - . += "
Records:
" - if(jobban_isbanned(user, "Records")) - . += "You are banned from using character records.
" - else - . += "Medical Records: " - . += "[TextPreview(pref.med_record,40)]
" - . += "Employment Records: " - . += "[TextPreview(pref.gen_record,40)]
" - . += "Security Records: " - . += "[TextPreview(pref.sec_record,40)]
" - . += "Memory: " - . += "[TextPreview(pref.memory,40)]
" - . = jointext(.,null) - -/datum/category_item/player_setup_item/physical/records/OnTopic(var/href,var/list/href_list, var/mob/user) - if(href_list["set_medical_records"]) - var/new_medical = sanitize(input(user,"Enter medical information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.med_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0) - if(!isnull(new_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user)) - pref.med_record = new_medical - return TOPIC_REFRESH - - else if(href_list["set_general_records"]) - var/new_general = sanitize(input(user,"Enter employment information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.gen_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0) - if(!isnull(new_general) && !jobban_isbanned(user, "Records") && CanUseTopic(user)) - pref.gen_record = new_general - return TOPIC_REFRESH - - else if(href_list["set_security_records"]) - var/sec_medical = sanitize(input(user,"Enter security information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.sec_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0) - if(!isnull(sec_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user)) - pref.sec_record = sec_medical - return TOPIC_REFRESH - - else if(href_list["set_memory"]) - var/memes = sanitize(input(user,"Enter memorized information here.",CHARACTER_PREFERENCE_INPUT_TITLE, html_decode(pref.memory)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0) - if(!isnull(memes) && CanUseTopic(user)) - pref.memory = memes - return TOPIC_REFRESH - - . = ..() diff --git a/code/modules/client/preference_setup/loadout/lists/accessories.dm b/code/modules/client/preference_setup/loadout/lists/accessories.dm index 8ef7c68fba2..939ae4b7dae 100644 --- a/code/modules/client/preference_setup/loadout/lists/accessories.dm +++ b/code/modules/client/preference_setup/loadout/lists/accessories.dm @@ -43,7 +43,7 @@ /datum/gear/accessory/guild display_name = "armband, Aster's Guild" path = /obj/item/clothing/accessory/armband/cargo - allowed_roles = list(JOBS_CARGO) + allowed_roles = list(JOBS_GUILD) /datum/gear/accessory/engineering display_name = "armband, Technomancer League" diff --git a/code/modules/client/preference_setup/loadout/lists/suits.dm b/code/modules/client/preference_setup/loadout/lists/suits.dm index aae61f2a909..2915bdfa18f 100644 --- a/code/modules/client/preference_setup/loadout/lists/suits.dm +++ b/code/modules/client/preference_setup/loadout/lists/suits.dm @@ -137,10 +137,10 @@ /datum/gear/suit/guild/black display_name = "black guild coat" path = /obj/item/clothing/suit/storage/cargo_jacket/black - allowed_roles = list(JOBS_CARGO) + allowed_roles = list(JOBS_GUILD) /datum/gear/suit/guild/black/old display_name = "old black guild coat" path = /obj/item/clothing/suit/storage/cargo_jacket/black/old - allowed_roles = list(JOBS_CARGO) + allowed_roles = list(JOBS_GUILD) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index d147644c094..1c99753d81d 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -239,10 +239,7 @@ for(var/lang in alternate_languages) character.add_language(lang) - - character.med_record = med_record - character.sec_record = sec_record - character.gen_record = gen_record + character.exploit_record = exploit_record if(!character.isSynthetic()) character.nutrition = rand(250, 450) diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 3868750180a..c60ce12189c 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -1,5 +1,5 @@ #define SAVEFILE_VERSION_MIN 8 -#define SAVEFILE_VERSION_MAX 18 +#define SAVEFILE_VERSION_MAX 19 /datum/preferences/proc/load_path(ckey,filename="preferences.sav") if(!ckey) diff --git a/code/modules/economy/Accounts.dm b/code/modules/economy/Accounts.dm index 9bd0818e2bf..56100ca2687 100644 --- a/code/modules/economy/Accounts.dm +++ b/code/modules/economy/Accounts.dm @@ -37,8 +37,12 @@ return owner_name //Attempts to return the associated data record for this account +// expensive to run, store the result from this. /datum/money_account/proc/get_record() - return find_general_record("pay_account", account_number) + for(var/datum/computer_file/report/crew_record/CR in GLOB.all_crew_records) + var/accountnum = CR.get_account() + if(account_number == accountnum) + return CR /datum/transaction var/target_name = "" diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm index 882dfea2999..632fed74e37 100644 --- a/code/modules/mining/abandonedcrates.dm +++ b/code/modules/mining/abandonedcrates.dm @@ -68,7 +68,7 @@ if(63 to 64) var/t = rand(4,7) for(var/i = 0, i < t, ++i) - var/newcoin = pick(/obj/item/coin/silver, /obj/item/coin/silver, /obj/item/coin/silver, /obj/item/coin/iron, /obj/item/coin/iron, /obj/item/coin/iron, /obj/item/coin/gold, /obj/item/coin/diamond, /obj/item/coin/plasma, /obj/item/coin/uranium, /obj/item/coin/platinum) + var/newcoin = pick(/obj/item/coin/silver, /obj/item/coin/silver, /obj/item/coin/silver, /obj/item/coin/plasteel, /obj/item/coin/plasteel, /obj/item/coin/plasteel, /obj/item/coin/gold, /obj/item/coin/diamond, /obj/item/coin/plasma, /obj/item/coin/uranium, /obj/item/coin/platinum) new newcoin(src) if(65 to 68) var/t = rand(4,7) diff --git a/code/modules/mining/coins.dm b/code/modules/mining/coins.dm index 1a1b318014c..434638d6e99 100644 --- a/code/modules/mining/coins.dm +++ b/code/modules/mining/coins.dm @@ -20,30 +20,44 @@ /obj/item/coin/gold name = COIN_GOLD icon_state = "coin_gold" + matter = list(MATERIAL_GOLD = 0.2) + price_tag = 10 /obj/item/coin/silver name = COIN_SILVER icon_state = "coin_silver" + matter = list(MATERIAL_SILVER = 0.2) + price_tag = 8 /obj/item/coin/diamond name = COIN_DIAMOND icon_state = "coin_diamond" + matter = list(MATERIAL_DIAMOND = 0.2) + price_tag = 20 -/obj/item/coin/iron - name = COIN_IRON +/obj/item/coin/plasteel + name = COIN_PLASTEEL icon_state = "coin_iron" + matter = list(MATERIAL_PLASTEEL = 0.2) + price_tag = 6 /obj/item/coin/plasma name = COIN_PLASMA icon_state = "coin_plasma" + matter = list(MATERIAL_PLASMA = 0.2) + price_tag = 6 /obj/item/coin/uranium name = COIN_URANIUM icon_state = "coin_uranium" + matter = list(MATERIAL_URANIUM = 0.2) + price_tag = 10 /obj/item/coin/platinum name = COIN_PLATINUM icon_state = "coin_adamantine" + matter = list(MATERIAL_PLATINUM = 0.2) + price_tag = 16 /obj/item/coin/attackby(obj/item/W as obj, mob/user as mob) if(istype(W,/obj/item/stack/cable_coil)) diff --git a/code/modules/mining/drilling/deep_drill.dm b/code/modules/mining/drilling/deep_drill.dm index 0c4f10389a2..f496ec8dda5 100644 --- a/code/modules/mining/drilling/deep_drill.dm +++ b/code/modules/mining/drilling/deep_drill.dm @@ -43,7 +43,7 @@ MATERIAL_PLASTIC = /obj/item/ore/coal ) -/obj/machinery/mining/deep_drill/Initialize() +/obj/machinery/mining/deep_drill/LateInitialize() . = ..() cave_gen = locate(/obj/cave_generator) update_icon() diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm index fdbdc12c46b..de862f2b8ff 100644 --- a/code/modules/mining/machine_processing.dm +++ b/code/modules/mining/machine_processing.dm @@ -149,8 +149,9 @@ for(var/oretype in typesof(/ore)-/ore) var/ore/OD = new oretype() ore_data[OD.name] = OD - ores_processing[OD.name] = 0 - ores_stored[OD.name] = 0 + for(var/ore/OD in ore_data) + ores_processing[OD.name] = 0 + ores_stored[OD.name] = 0 spawn() //Locate our output and input machinery. diff --git a/code/modules/mining/money_bag.dm b/code/modules/mining/money_bag.dm index 03690ad9128..bfa17850c02 100644 --- a/code/modules/mining/money_bag.dm +++ b/code/modules/mining/money_bag.dm @@ -15,7 +15,7 @@ var/amt_gold = 0 var/amt_silver = 0 var/amt_diamond = 0 - var/amt_iron = 0 + var/amt_plasteel = 0 var/amt_plasma = 0 var/amt_uranium = 0 @@ -24,8 +24,8 @@ amt_diamond++; if (istype(C,/obj/item/coin/plasma)) amt_plasma++; - if (istype(C,/obj/item/coin/iron)) - amt_iron++; + if (istype(C,/obj/item/coin/plasteel)) + amt_plasteel++; if (istype(C,/obj/item/coin/silver)) amt_silver++; if (istype(C,/obj/item/coin/gold)) @@ -38,8 +38,8 @@ dat += text("Gold coins: [amt_gold] Remove one
") if (amt_silver) dat += text("Silver coins: [amt_silver] Remove one
") - if (amt_iron) - dat += text("Metal coins: [amt_iron] Remove one
") + if (amt_plasteel) + dat += text("Plasteel coins: [amt_plasteel] Remove one
") if (amt_diamond) dat += text("Diamond coins: [amt_diamond] Remove one
") if (amt_plasma) @@ -73,17 +73,17 @@ COIN = locate(/obj/item/coin/gold,src.contents) if(MATERIAL_SILVER) COIN = locate(/obj/item/coin/silver,src.contents) - if("iron") - COIN = locate(/obj/item/coin/iron,src.contents) + if(MATERIAL_PLASTEEL) + COIN = locate(/obj/item/coin/plasteel,src.contents) if(MATERIAL_DIAMOND) COIN = locate(/obj/item/coin/diamond,src.contents) - if("plasma") + if(MATERIAL_PLASMA) COIN = locate(/obj/item/coin/plasma,src.contents) if(MATERIAL_URANIUM) COIN = locate(/obj/item/coin/uranium,src.contents) if(!COIN) return - COIN.loc = src.loc + COIN.forceMove(get_turf(src)) return diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index a2c889b6124..f35152a5ca2 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -108,9 +108,8 @@ var/mob/living/carbon/human/H = speaker if(H.voice) speaker_name = H.voice - for(var/datum/data/record/G in data_core.general) - if(G.fields["name"] == speaker_name) - return H.rank_prefix_name(speaker_name) + if(get_crewmember_record(speaker_name)) + return H.rank_prefix_name(speaker_name) return voice_name ? voice_name : speaker_name diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm index bf61af693ba..6cf3d470d69 100755 --- a/code/modules/mob/holder.dm +++ b/code/modules/mob/holder.dm @@ -136,10 +136,8 @@ var/list/holder_mob_icon_cache = list() //Repeat this check //If we're still on the turf a few frames later, then we have actually been dropped or thrown //Release the mob accordingly - //addtimer(CALLBACK(src, PROC_REF(post_drop)), 3) + addtimer(CALLBACK(src, PROC_REF(post_drop)), 3) //TODO: Uncomment the above once addtimer is ported - spawn(3) - post_drop() return if (istype(loc, /obj/item/storage)) //The second drop reads the container its placed into as the location @@ -581,6 +579,18 @@ var/list/holder_mob_icon_cache = list() return I return null +//Holders for mice +/obj/item/holder/carrion + name = "spider core" + desc = "A horrifying face on spider-like legs." + desc_dead = "A dead bio-weapon, it probably tastes horrible." + icon = 'icons/mob/animal.dmi' + icon_state = "spider_core" + slot_flags = SLOT_HEAD + origin_tech = list(TECH_BIO = 5) + w_class = ITEM_SIZE_NORMAL + + /* //Lizards diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index c647f21637c..26b9b9510bd 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -44,7 +44,7 @@ W.forceMove(get_turf(src)) W.layer = initial(W.layer) W.set_plane(initial(W.plane)) - W.dropped(usr) + W.dropped(src) // Removes an item from inventory and places it in the target atom. // If canremove or other conditions need to be checked then use unEquip instead. diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 74137ba2483..76fbc1a113e 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -294,7 +294,8 @@ criminal = R ? R.get_criminalStatus() : "None" msg += "Criminal status: \[[criminal]\]\n" - msg += "Security records: \[View\] \[Add comment\]\n" + msg += {"Security records: \[View\] \[View Brief\] + \[Add Note\]\n"} if(hasHUD(user, "medical")) var/perpname = "wot" @@ -306,15 +307,11 @@ perpname = id_card.registered_name else perpname = src.name - - for (var/datum/data/record/E in data_core.general) - if (E.fields["name"] == perpname) - for (var/datum/data/record/R in data_core.general) - if (R.fields["id"] == E.fields["id"]) - medical = R.fields["p_stat"] + var/datum/computer_file/report/crew_record/E = get_crewmember_record(perpname) + medical = E.get_status() msg += "Physical status: \[[medical]\]\n" - msg += "Medical records: \[View\] \[Add comment\]\n" + msg += "Medical records: \[View\]\n" var/obj/item/clothing/under/U = w_uniform if(U && istype(U) && U.sensor_mode >= 2) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index e4a204b26bc..7103825d880 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -425,21 +425,20 @@ var/list/rank_prefix = list(\ if(perpname) var/datum/computer_file/report/crew_record/R = get_crewmember_record(perpname) if(R) + modified = TRUE var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", R.get_criminalStatus()) in GLOB.security_statuses + "Cancel" - if(hasHUD(usr, "security")) - if(setcriminal != "Cancel") - R.set_criminalStatus(setcriminal) - modified = TRUE - BITSET(hud_updateflag, WANTED_HUD) - if(ishuman(usr)) - var/mob/living/carbon/human/U = usr - U.handle_regular_hud_updates() - if(isrobot(usr)) - var/mob/living/silicon/robot/U = usr - U.handle_regular_hud_updates() + if(setcriminal != "Cancel") + R.set_criminalStatus(setcriminal) + BITSET(hud_updateflag, WANTED_HUD) + if(ishuman(usr)) + var/mob/living/carbon/human/U = usr + U.handle_regular_hud_updates() + if(isrobot(usr)) + var/mob/living/silicon/robot/U = usr + U.handle_regular_hud_updates() if(!modified) - to_chat(usr, "\red Unable to locate a data core entry for this person.") + to_chat(usr, "\red Unable to locate a criminal record for this person.") if(href_list["secrecord"]) if(hasHUD(usr,"security")) @@ -452,52 +451,50 @@ var/list/rank_prefix = list(\ else perpname = src.name - for(var/datum/data/record/E in data_core.general) - if(E.fields["name"] == perpname) - for(var/datum/data/record/R in data_core.security) - if(R.fields["id"] == E.fields["id"]) - if(hasHUD(usr,"security")) - to_chat(usr, "Name: [R.fields["name"]] Criminal Status: [R.fields["criminal"]]") - to_chat(usr, "Minor Crimes: [R.fields["mi_crim"]]") - to_chat(usr, "Details: [R.fields["mi_crim_d"]]") - to_chat(usr, "Major Crimes: [R.fields["ma_crim"]]") - to_chat(usr, "Details: [R.fields["ma_crim_d"]]") - to_chat(usr, "Notes: [R.fields["notes"]]") - to_chat(usr, "\[View Comment Log\]") - read = 1 + var/datum/computer_file/report/crew_record/CR = get_crewmember_record(perpname) + if(CR) + to_chat(usr, "Name: [CR.get_name()] Criminal Status: [CR.get_criminalStatus()]") + var/datum/report_field/array/tofetch = CR.get_linkage_secNotes() + var/list/Briefing = tofetch.value_list + if(Briefing.len > 0) + var/list/combined = list() + for(var/iterator = min(Briefing.len-1, 3), iterator > -1, iterator -= 1) + combined.Add(Briefing[Briefing.len - iterator]) + to_chat(usr, "Briefing latest: "+combined.Join(", ")) + to_chat(usr, "\[Add to Brief\]") + to_chat(usr, "\[View Full Brief\]") + read = 1 if(!read) - to_chat(usr, "\red Unable to locate a data core entry for this person.") + to_chat(usr, "\red Unable to locate a criminal record for this person.") - if(href_list["secrecordComment"]) + if(href_list["viewbrief"]) if(hasHUD(usr,"security")) var/perpname = "wot" - var/read = 0 - var/obj/item/card/id/id = GetIdCard() - if(istype(id)) - perpname = id.registered_name + if(wear_id) + var/obj/item/card/id/id + if(istype(wear_id, /obj/item/modular_computer/pda)) + id = wear_id.GetIdCard() + if(!id) + id = get_idcard() + if(id) + perpname = id.registered_name else perpname = src.name - for(var/datum/data/record/E in data_core.general) - if(E.fields["name"] == perpname) - for(var/datum/data/record/R in data_core.security) - if(R.fields["id"] == E.fields["id"]) - if(hasHUD(usr,"security")) - read = 1 - var/counter = 1 - while(R.fields[text("com_[]", counter)]) - to_chat(usr, text("[]", R.fields[text("com_[]", counter)])) - counter++ - if(counter == 1) - to_chat(usr, "No comment found") - to_chat(usr, "\[Add comment\]") - - if(!read) - to_chat(usr, "\red Unable to locate a data core entry for this person.") + var/datum/computer_file/report/crew_record/E = get_crewmember_record(perpname) + if(!E) + to_chat(usr, SPAN_DANGER("Unable to locate a record for this person.")) + return + var/datum/report_field/array/tofetch = E.get_linkage_secNotes() + var/list/Briefing = tofetch.value_list + if(Briefing.len > 0) + to_chat(usr, SPAN_NOTICE("Brief: " + Briefing.Join(", "))) + else + to_chat(usr, SPAN_NOTICE("[perpname] does not have a brief.")) - if(href_list["secrecordadd"]) + if(href_list["secnoteadd"]) if(hasHUD(usr,"security")) var/perpname = "wot" if(wear_id) @@ -506,32 +503,27 @@ var/list/rank_prefix = list(\ id = wear_id.GetIdCard() if(!id) id = get_idcard() - if(id) - perpname = id.registered_name + if(id) + perpname = id.registered_name else perpname = src.name - for(var/datum/data/record/E in data_core.general) - if(E.fields["name"] == perpname) - for(var/datum/data/record/R in data_core.security) - if(R.fields["id"] == E.fields["id"]) - if(hasHUD(usr,"security")) - var/t1 = sanitize(input("Add Comment:", "Sec. records", null, null) as message) - if( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"security")) ) - return - var/counter = 1 - while(R.fields[text("com_[]", counter)]) - counter++ - if(ishuman(usr)) - var/mob/living/carbon/human/U = usr - R.fields[text("com_[counter]")] = text("Made by [U.get_authentification_name()] ([U.get_assignment()]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]
[t1]") - if(isrobot(usr)) - var/mob/living/silicon/robot/U = usr - R.fields[text("com_[counter]")] = text("Made by [U.name] ([U.modtype] [U.braintype]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]
[t1]") + + var/datum/computer_file/report/crew_record/E = get_crewmember_record(perpname) + if(!E) + to_chat(usr, SPAN_WARNING("Record for [perpname] not found!")) + return + var/t1 = sanitize(input("Add to Brief:", "Sec. records", null, null) as text) + if( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"security")) ) + return + + var/datum/report_field/array/recordnote = E.get_linkage_secNotes() + + if(recordnote) + recordnote.add_value(t1) if(href_list["medical"]) if(hasHUD(usr,"medical")) var/perpname = "wot" - var/modified = 0 var/obj/item/card/id/id = GetIdCard() if(istype(id)) @@ -539,126 +531,49 @@ var/list/rank_prefix = list(\ else perpname = src.name - for(var/datum/data/record/E in data_core.general) - if(E.fields["name"] == perpname) - for(var/datum/data/record/R in data_core.general) - if(R.fields["id"] == E.fields["id"]) - - var/setmedical = input(usr, "Specify a new medical status for this person.", "Medical HUD", R.fields["p_stat"]) in list("*SSD*", "*Deceased*", "Physically Unfit", "Active", "Disabled", "Cancel") - - if(hasHUD(usr,"medical")) - if(setmedical != "Cancel") - R.fields["p_stat"] = setmedical - modified = 1 - if(PDA_Manifest.len) - PDA_Manifest.Cut() + var/datum/computer_file/report/crew_record/E = get_crewmember_record(perpname) + if(E) + var/setmedical = input(usr, "Specify a new medical status for this person.", "Medical HUD", E.get_status()) in GLOB.physical_statuses - spawn() - if(ishuman(usr)) - var/mob/living/carbon/human/U = usr - U.handle_regular_hud_updates() - if(isrobot(usr)) - var/mob/living/silicon/robot/U = usr - U.handle_regular_hud_updates() + if(hasHUD(usr,"medical")) + if(setmedical != "Cancel") + E.set_status(setmedical) - if(!modified) - to_chat(usr, "\red Unable to locate a data core entry for this person.") - - if(href_list["medrecord"]) - if(hasHUD(usr,"medical")) - var/perpname = "wot" - var/read = 0 + spawn() + if(ishuman(usr)) + var/mob/living/carbon/human/U = usr + U.handle_regular_hud_updates() + if(isrobot(usr)) + var/mob/living/silicon/robot/U = usr + U.handle_regular_hud_updates() - if(wear_id) - var/obj/item/card/id/id - if(istype(wear_id, /obj/item/modular_computer/pda)) - id = wear_id.GetIdCard() - if(!id) - id = get_idcard() - if(id) - perpname = id.registered_name else - perpname = src.name - for(var/datum/data/record/E in data_core.general) - if(E.fields["name"] == perpname) - for(var/datum/data/record/R in data_core.medical) - if(R.fields["id"] == E.fields["id"]) - if(hasHUD(usr,"medical")) - to_chat(usr, "Name: [R.fields["name"]] Blood Type: [R.fields["b_type"]]") - to_chat(usr, "DNA: [R.fields["b_dna"]]") - to_chat(usr, "Minor Disabilities: [R.fields["mi_dis"]]") - to_chat(usr, "Details: [R.fields["mi_dis_d"]]") - to_chat(usr, "Major Disabilities: [R.fields["ma_dis"]]") - to_chat(usr, "Details: [R.fields["ma_dis_d"]]") - to_chat(usr, "Notes: [R.fields["notes"]]") - to_chat(usr, "\[View Comment Log\]") - read = 1 - - if(!read) - to_chat(usr, "\red Unable to locate a data core entry for this person.") + to_chat(usr, "\red Unable to locate a medical record for this person.") - if(href_list["medrecordComment"]) + if(href_list["medrecord"]) if(hasHUD(usr,"medical")) var/perpname = "wot" var/read = 0 - if(wear_id) - var/obj/item/card/id/id - if(istype(wear_id, /obj/item/modular_computer/pda)) - id = wear_id.GetIdCard() - if(!id) - id = get_idcard() - if(id) - perpname = id.registered_name + var/obj/item/card/id/id = GetIdCard() + if(istype(id)) + perpname = id.registered_name else perpname = src.name - for(var/datum/data/record/E in data_core.general) - if(E.fields["name"] == perpname) - for(var/datum/data/record/R in data_core.medical) - if(R.fields["id"] == E.fields["id"]) - if(hasHUD(usr,"medical")) - read = 1 - var/counter = 1 - while(R.fields[text("com_[]", counter)]) - to_chat(usr, text("[]", R.fields[text("com_[]", counter)])) - counter++ - if(counter == 1) - to_chat(usr, "No comment found") - to_chat(usr, "\[Add comment\]") + var/datum/computer_file/report/crew_record/E = get_crewmember_record(perpname) + var/datum/report_field/arrayclump/M = E.get_linkage_medRecord() + if(E) + to_chat(usr, "Name: [E.get_name()] Blood Type: [E.get_bloodtype()]") + to_chat(usr, "DNA: [E.get_dna()]") + to_chat(usr, "Prosthetics: [M.value["prosthetics"]]") + to_chat(usr, "Recorded Wounds: [M.value["wounds"]]") + to_chat(usr, "Autopsy: [M.value["Body state"]]") + to_chat(usr, "Psychological Profile: [M.value["psychological"]]") + to_chat(usr, "Chemical History: [M.value["chemhistory"]]") + read = 1 if(!read) - to_chat(usr, "\red Unable to locate a data core entry for this person.") - - if(href_list["medrecordadd"]) - if(hasHUD(usr,"medical")) - var/perpname = "wot" - if(wear_id) - var/obj/item/card/id/id - if(istype(wear_id, /obj/item/modular_computer/pda)) - id = wear_id.GetIdCard() - if(!id) - id = get_idcard() - if(id) - perpname = id.registered_name - else - perpname = src.name - for(var/datum/data/record/E in data_core.general) - if(E.fields["name"] == perpname) - for(var/datum/data/record/R in data_core.medical) - if(R.fields["id"] == E.fields["id"]) - if(hasHUD(usr,"medical")) - var/t1 = sanitize(input("Add Comment:", "Med. records", null, null) as message) - if( !(t1) || usr.stat || usr.restrained() || !(hasHUD(usr,"medical")) ) - return - var/counter = 1 - while(R.fields[text("com_[]", counter)]) - counter++ - if(ishuman(usr)) - var/mob/living/carbon/human/U = usr - R.fields[text("com_[counter]")] = text("Made by [U.get_authentification_name()] ([U.get_assignment()]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]
[t1]") - if(isrobot(usr)) - var/mob/living/silicon/robot/U = usr - R.fields[text("com_[counter]")] = text("Made by [U.name] ([U.modtype] [U.braintype]) on [time2text(world.realtime, "DDD MMM DD hh:mm:ss")], [game_year]
[t1]") + to_chat(usr, "\red Unable to locate a medical record for this person.") if(href_list["lookitem"]) var/obj/item/I = locate(href_list["lookitem"]) diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index d38ef6b67fb..5ac925a2773 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -345,7 +345,7 @@ This function restores all organs. organ = def_zone else if(!def_zone) - if(!damagetype == TOX) // global application + if(!(damagetype == TOX)) // global application def_zone = ran_zone(def_zone) organ = get_organ(check_zone(def_zone)) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 771b32d155c..8cc45281e7d 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -37,7 +37,7 @@ meteor_act SP.desc = "[SP.desc] It looks like it was fired from [P.shot_from]." SP.loc = organ if(length(P.matter)) - SP.material = P.matter[1] + SP.material = get_material_by_name(P.matter[1]) SP.amount = P.matter[SP.material] // amount no longer randomized organ.embed(SP) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index f10fe52c7a6..de1bf065ae6 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -84,9 +84,6 @@ var/equipment_prescription // Eye prescription granted by equipped items var/list/equipment_overlays = list() // Extra overlays from equipped items - var/med_record = "" - var/sec_record = "" - var/gen_record = "" var/exploit_record = "" var/stance_damage = 0 //Whether this mob's ability to stand has been affected diff --git a/code/modules/mob/living/carbon/superior_animal/roach/roach.dm b/code/modules/mob/living/carbon/superior_animal/roach/roach.dm index 5de1e56f001..771cb0e171d 100644 --- a/code/modules/mob/living/carbon/superior_animal/roach/roach.dm +++ b/code/modules/mob/living/carbon/superior_animal/roach/roach.dm @@ -120,7 +120,7 @@ comrade.joinOvermind(overseer) overseer.leader = comrade else if(!overseer && comrade.overseer) // or if they have an overmind and we don't, we join - joinOvermind(overseer) + joinOvermind(comrade.overseer) if(/mob/living/carbon/superior_animal/roach/kaiser) // only one possibility requires code with kaiser if(istype(comrade, /mob/living/carbon/superior_animal/roach/fuhrer)) if(overseer && comrade.overseer) @@ -131,5 +131,5 @@ else if(overseer && !comrade.overseer) comrade.joinOvermind(overseer) else - if(!overseer && istype(comrade, /mob/living/carbon/superior_animal/roach/fuhrer) || istype(comrade, /mob/living/carbon/superior_animal/roach/kaiser) && comrade.overseer) + if(!overseer && (istype(comrade, /mob/living/carbon/superior_animal/roach/fuhrer) || istype(comrade, /mob/living/carbon/superior_animal/roach/kaiser)) && comrade.overseer) joinOvermind(comrade.overseer) diff --git a/code/modules/mob/living/carbon/superior_animal/roach/roachmind.dm b/code/modules/mob/living/carbon/superior_animal/roach/roachmind.dm index 5709077ab16..4df847b22bc 100644 --- a/code/modules/mob/living/carbon/superior_animal/roach/roachmind.dm +++ b/code/modules/mob/living/carbon/superior_animal/roach/roachmind.dm @@ -33,7 +33,7 @@ var/list/highest[] // an overmind ruled by a fuhrer is subordinate to one ruled by a kaiser. if(istype(leader, /mob/living/carbon/superior_animal/roach/kaiser)) highest += src - if(!istype(collatewith.leader, /mob/living/carbon/superior_animal/roach/kaiser)) + if(istype(collatewith.leader, /mob/living/carbon/superior_animal/roach/kaiser)) highest += collatewith if(length(highest) == 1) if(highest[1] == src) diff --git a/code/modules/mob/living/carbon/superior_animal/roach/types/kaiser.dm b/code/modules/mob/living/carbon/superior_animal/roach/types/kaiser.dm index 37951ccf651..45c8c8adb7e 100644 --- a/code/modules/mob/living/carbon/superior_animal/roach/types/kaiser.dm +++ b/code/modules/mob/living/carbon/superior_animal/roach/types/kaiser.dm @@ -106,6 +106,25 @@ Has ability of every roach. gas_sac.clear_reagents() return TRUE +/mob/living/carbon/superior_animal/roach/kaiser/leaveOvermind() + var/mob/living/carbon/superior_animal/roach/backup + overseer.removeHarrier(src) + for(var/mob/living/carbon/superior_animal/roach/tocheck in overseer.members) + if(istype(tocheck, /mob/living/carbon/superior_animal/roach/kaiser)) + overseer.leader = tocheck + overseer?.casualties.Remove(src) + overseer = null + return + else if(istype(tocheck, /mob/living/carbon/superior_animal/roach/fuhrer)) + backup = tocheck + for(var/datum/overmind/roachmind/subordinate in overseer.subordinates) //by this point if there even is a new leader, it is a "mere fuhrer". + subordinate.superior = null + overseer.subordinates.Cut() + overseer.leader = backup + if(!backup && !QDELETED(overseer)) // kaiser is always the leader + qdel(overseer) // disband + overseer = null + /mob/living/carbon/superior_animal/roach/kaiser/findTarget() . = ..() if(. && gas_attack()) diff --git a/code/modules/mob/living/carbon/taste.dm b/code/modules/mob/living/carbon/taste.dm index e723e0b9ff3..39a4a498c85 100644 --- a/code/modules/mob/living/carbon/taste.dm +++ b/code/modules/mob/living/carbon/taste.dm @@ -23,6 +23,8 @@ calculate text size per text. continue if(R.id == "nutriment") var/list/t = R.get_data() + if(!t) // no data, nutriment made from no source? + continue for(var/i in 1 to t.len) var/A = t[i] if(!(A in tastes)) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 50684da1ed4..cd8fa61de9d 100755 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -500,17 +500,8 @@ default behaviour is: // Delete them from datacore. - if(PDA_Manifest.len) - PDA_Manifest.Cut() - for(var/datum/data/record/R in data_core.medical) - if ((R.fields["name"] == src.real_name)) - qdel(R) - for(var/datum/data/record/T in data_core.security) - if ((T.fields["name"] == src.real_name)) - qdel(T) - for(var/datum/data/record/G in data_core.general) - if ((G.fields["name"] == src.real_name)) - qdel(G) + var/datum/todelete = get_crewmember_record(name) + qdel(todelete) //This should guarantee that ghosts don't spawn. src.ckey = null diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index a4387a8c287..711932dc7b6 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -550,8 +550,8 @@ var/list/ai_verbs_default = list( var/personnel_list[] = list() - for(var/datum/data/record/t in data_core.locked)//Look in data core locked. - personnel_list["[t.fields["name"]]: [t.fields["rank"]]"] = t.fields["image"]//Pull names, rank, and image. + for(var/datum/computer_file/report/crew_record/t in GLOB.all_crew_records) + personnel_list["[t.get_name()]: [t.get_job()]"] = t.photo_front//Pull names, rank, and image. if(personnel_list.len) input = input("Select a crew member:") as null|anything in personnel_list diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index adb433f583e..eec8f2cf1fd 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -58,12 +58,10 @@ var/medHUD = FALSE // Toggles whether the Medical HUD is active or not var/medical_cannotfind = 0 - var/datum/data/record/medicalActive1 // Datacore record declarations for record software - var/datum/data/record/medicalActive2 + var/datum/data/record/medicalActive // Datacore record declarations for record software var/security_cannotfind = 0 - var/datum/data/record/securityActive1 // Could probably just combine all these into one - var/datum/data/record/securityActive2 + var/datum/data/record/securityActive var/obj/machinery/door/hackdoor // The airlock being hacked var/hackprogress = 0 // Possible values: 0 - 1000, >= 1000 means the hack is complete and will be reset upon next check @@ -158,11 +156,9 @@ set category = "pAI Commands" set name = "Reset Records Software" - securityActive1 = null - securityActive2 = null + securityActive = null security_cannotfind = 0 - medicalActive1 = null - medicalActive2 = null + medicalActive = null medical_cannotfind = 0 SSnano.update_uis(src) to_chat(usr, SPAN_NOTICE("You reset your record-viewing software.")) diff --git a/code/modules/mob/living/silicon/pai/software_modules.dm b/code/modules/mob/living/silicon/pai/software_modules.dm index 7855c6da1a5..7e9f4306c97 100644 --- a/code/modules/mob/living/silicon/pai/software_modules.dm +++ b/code/modules/mob/living/silicon/pai/software_modules.dm @@ -118,21 +118,19 @@ ram_cost = 5 id = "manifest" toggle = 0 + var/datum/nano_module/crew_manifest/manifestmodule + var/datum/topic_manager/program/mandatorymanager - on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=1) - data_core.get_manifest_json() - - var/data[0] - // This is dumb, but NanoUI breaks if it has no data to send - data["manifest"] = list("__json_cache" = ManifestJSON) + New() + mandatorymanager = new() + manifestmodule = new(src, mandatorymanager) + + Destroy() + . = ..() + QDEL_NULL(manifestmodule) - ui = SSnano.try_update_ui(user, user, id, ui, data, force_open) - if(!ui) - // Don't copy-paste this unless you're making a pAI software module! - ui = new(user, user, id, "pai_manifest.tmpl", "Crew Manifest", 450, 600) - ui.set_initial_data(data) - ui.open() - ui.set_auto_update(1) + on_ui_interact(mob/living/silicon/pai/user, datum/nanoui/ui=null, force_open=NANOUI_REINITIALIZE) + manifestmodule.nano_ui_interact(user, ui, "main", force_open) // transfers applicable vars to manifestmodule /datum/pai_software/med_records name = "Medical Records" @@ -144,18 +142,23 @@ var/data[0] var/records[0] - for(var/datum/data/record/general in sortRecord(data_core.general)) + for(var/datum/computer_file/report/crew_record/general in GLOB.all_crew_records) var/record[0] - record["name"] = general.fields["name"] + record["name"] = general.get_name() record["ref"] = "\ref[general]" records[++records.len] = record data["records"] = records - var/datum/data/record/G = user.medicalActive1 - var/datum/data/record/M = user.medicalActive2 - data["general"] = G ? G.fields : null - data["medical"] = M ? M.fields : null + var/datum/computer_file/report/crew_record/G = user.securityActive + var/datum/report_field/arrayclump/M = G?.get_linkage_medRecord() + data["general"] = G ? list("name" = G.get_name(), "sex" = G.get_sex(), "species" = G.get_species(), "age" = G.get_age(), \ + "job" = G.get_job(), "fingerprint" = G.get_fingerprint(), "status" = G.get_status(), "bloodtype" = G.get_bloodtype()) : null + data["prosthetics"] = M ? M.value["prosthetics"] : null + data["wounds"] = M ? M.value["wounds"] : null + data["Body state"] = M ? M.value["body state"] : null + data["chemhistory"] = M ? M.value["chemhistory"] : null + data["psychological"] = M ? M.value["psychological"] : null data["could_not_find"] = user.medical_cannotfind ui = SSnano.try_update_ui(user, user, id, ui, data, force_open) @@ -169,24 +172,15 @@ Topic(href, href_list) var/mob/living/silicon/pai/P = usr if(!istype(P)) return - + if(href_list["select"]) - var/datum/data/record/record = locate(href_list["select"]) - if(record) - var/datum/data/record/R = record - var/datum/data/record/M = null - if (!( data_core.general.Find(R) )) - P.medical_cannotfind = 1 - else - P.medical_cannotfind = 0 - for(var/datum/data/record/E in data_core.medical) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - M = E - P.medicalActive1 = R - P.medicalActive2 = M + var/datum/computer_file/report/crew_record/record = locate(href_list["select"]) + if(istype(record)) + P.medical_cannotfind = 0 + P.medicalActive = record else P.medical_cannotfind = 1 - return 1 + return TRUE /datum/pai_software/sec_records name = "Security Records" @@ -198,18 +192,18 @@ var/data[0] var/records[0] - for(var/datum/data/record/general in sortRecord(data_core.general)) + for(var/datum/computer_file/report/crew_record/general in GLOB.all_crew_records) var/record[0] - record["name"] = general.fields["name"] + record["name"] = general.get_name() record["ref"] = "\ref[general]" records[++records.len] = record data["records"] = records - var/datum/data/record/G = user.securityActive1 - var/datum/data/record/S = user.securityActive2 - data["general"] = G ? G.fields : null - data["security"] = S ? S.fields : null + var/datum/computer_file/report/crew_record/G = user.securityActive + data["general"] = G ? list("name" = G.get_name(), "sex" = G.get_sex(), "species" = G.get_species(), "age" = G.get_age(), \ + "job" = G.get_job(), "fingerprint" = G.get_fingerprint(), "status" = G.get_status(), "criminalStatus" = G.get_criminalStatus(), \ + "secNotes" = G.get_linkage_secNotes()) : null data["could_not_find"] = user.security_cannotfind ui = SSnano.try_update_ui(user, user, id, ui, data, force_open) @@ -225,26 +219,14 @@ if(!istype(P)) return if(href_list["select"]) - var/datum/data/record/record = locate(href_list["select"]) - if(record) - var/datum/data/record/R = record - var/datum/data/record/S = null - if (!( data_core.general.Find(R) )) - P.securityActive1 = null - P.securityActive2 = null - P.security_cannotfind = 1 - else - P.security_cannotfind = 0 - for(var/datum/data/record/E in data_core.security) - if ((E.fields["name"] == R.fields["name"] || E.fields["id"] == R.fields["id"])) - S = E - P.securityActive1 = R - P.securityActive2 = S + var/datum/computer_file/report/crew_record/record = locate(href_list["select"]) + if(istype(record)) + P.security_cannotfind = 0 + P.securityActive = record else - P.securityActive1 = null - P.securityActive2 = null + P.securityActive = null P.security_cannotfind = 1 - return 1 + return TRUE /datum/pai_software/door_jack name = "Door Jack" diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index cc3da5e05aa..e4680aebb17 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -86,9 +86,6 @@ squeals++ last_squealgain = world.time - else - if ((world.time - timeofdeath) > decompose_time) - dust() //Pixel offsetting as they scamper around diff --git a/code/modules/mob/living/simple_animal/spider_core.dm b/code/modules/mob/living/simple_animal/spider_core.dm index 4f2a0cc6204..0359f5a965a 100644 --- a/code/modules/mob/living/simple_animal/spider_core.dm +++ b/code/modules/mob/living/simple_animal/spider_core.dm @@ -24,6 +24,7 @@ hunger_enabled = FALSE pass_flags = PASSTABLE universal_understand = 1 + holder_type = /obj/item/holder/carrion density = TRUE //Should be 0, but then these things would be a nightmare to kill. faction = "spiders" @@ -35,7 +36,12 @@ /mob/living/simple_animal/spider_core/proc/generate_body)) /mob/living/simple_animal/spider_core/death() - gibs(loc, null, /obj/effect/gibspawner/generic, "#666600", "#666600") + var/obj/item/organ/internal/core = locate(/obj/item/organ/internal/carrion/core) in contents + if(core) + core.forceMove(loc) + core.status |= ORGAN_DEAD // todo: make wound somehow + core.refresh_damage() + playsound(loc, 'sound/voice/shriek1.ogg', 50) qdel(src) diff --git a/code/modules/mob/mob_grab_specials.dm b/code/modules/mob/mob_grab_specials.dm index 027cb9ce6e3..29b394e0ebc 100644 --- a/code/modules/mob/mob_grab_specials.dm +++ b/code/modules/mob/mob_grab_specials.dm @@ -74,8 +74,8 @@ else visible_message(SPAN_NOTICE("[user] finishes putting pressure on [H]'s wounds.")) for(var/datum/wound/W in bodypart.wounds) - W.current_stage++ - W.bleed_timer -= 5 + W.clamped = TRUE + bodypart.stopBleeding() //do not kill the grab diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index ea7c4bebbf3..bce2ea9e511 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -490,11 +490,11 @@ proc/is_blind(A) if(id) perpname = id.registered_name - var/datum/data/record/R = find_security_record("name", perpname) - if(check_records && !R) + var/datum/computer_file/report/crew_record/CR = get_crewmember_record(perpname) + if(check_records && !CR) threatcount += 4 - if(check_arrest && R && (R.fields["criminal"] == "*Arrest*")) + if(check_arrest && CR && (CR?.get_criminalStatus() == "*Arrest*")) // why is paperwork's folly being translated to electronic format? threatcount += 4 return threatcount diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index cee4bf2988a..4fae2968ad0 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -318,7 +318,6 @@ if(SSjob.ShouldCreateRecords(job.title)) if(character.mind.assigned_role != "Robot") CreateModularRecord(character) - data_core.manifest_inject(character) matchmaker.do_matchmaking() SSticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn diff --git a/code/modules/modular_computers/computers/modular_computer/core.dm b/code/modules/modular_computers/computers/modular_computer/core.dm index 1a01fb8f1d1..22c3b472a3f 100644 --- a/code/modules/modular_computers/computers/modular_computer/core.dm +++ b/code/modules/modular_computers/computers/modular_computer/core.dm @@ -308,6 +308,8 @@ SetName(initial(name)) /obj/item/modular_computer/proc/update_uis() + if(active_program && istype(active_program?.nanomodule_path, /datum/nano_module/tgui)) + return FALSE if(active_program) //Should we update program ui or computer ui? SSnano.update_uis(active_program) if(active_program.NM) diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index 6e3a4dd9015..04407afb0f1 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -195,7 +195,10 @@ if(ui) ui.close() return computer.nano_ui_interact(user) - if(istype(NM)) + if(istype(NM, /datum/nano_module/tgui)) + NM.ui_interact(user) + return FALSE + else if(istype(NM)) NM.nano_ui_interact(user, ui_key, null, force_open) return 0 return 1 diff --git a/code/modules/modular_computers/file_system/programs/command/card.dm b/code/modules/modular_computers/file_system/programs/command/card.dm index 4835caca081..3fc804a66de 100644 --- a/code/modules/modular_computers/file_system/programs/command/card.dm +++ b/code/modules/modular_computers/file_system/programs/command/card.dm @@ -62,7 +62,7 @@ data["security_jobs"] = format_jobs(security_positions) //data["exploration_jobs"] = format_jobs(exploration_positions) data["service_jobs"] = format_jobs(civilian_positions) - data["supply_jobs"] = format_jobs(cargo_positions) + data["supply_jobs"] = format_jobs(guild_positions) data["church_jobs"] = format_jobs(church_positions) //data["civilian_jobs"] = format_jobs(civilian_positions) data["centcom_jobs"] = format_jobs(get_all_centcom_jobs()) diff --git a/code/modules/modular_computers/file_system/programs/generic/records.dm b/code/modules/modular_computers/file_system/programs/generic/records.dm index 2836b1a741b..01fb6a442d1 100644 --- a/code/modules/modular_computers/file_system/programs/generic/records.dm +++ b/code/modules/modular_computers/file_system/programs/generic/records.dm @@ -1,3 +1,5 @@ + +#define NULL_RECORD list("name" = null, "uid" = null, "creator" = null, "file_time" = null, "fields" = null, "access" = null, "access_edit" = null) /datum/computer_file/program/records filename = "crewrecords" filedesc = "Crew Records" @@ -7,22 +9,22 @@ size = 14 requires_ntnet = TRUE available_on_ntnet = TRUE - nanomodule_path = /datum/nano_module/records + nanomodule_path = /datum/nano_module/tgui/records usage_flags = PROGRAM_ALL -/datum/nano_module/records +/datum/nano_module/tgui/records name = "Crew Records" var/datum/computer_file/report/crew_record/active_record var/message = null -/datum/nano_module/records/nano_ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = NANOUI_FOCUS, state = GLOB.default_state) +/datum/nano_module/tgui/records/ui_data(mob/user) var/list/data = host.initial_data() var/list/user_access = get_record_access(user) data["message"] = message if(active_record) - user << browse_rsc(active_record.photo_front, "front_[active_record.uid].png") - user << browse_rsc(active_record.photo_side, "side_[active_record.uid].png") + data["front_pic"] = icon2base64html(active_record.photo_front) + data["side_pic"] = icon2base64html(active_record.photo_side) data["pic_edit"] = check_access(user, access_heads) || check_access(user, access_security) data += active_record.generate_nano_data(user_access) else @@ -38,16 +40,20 @@ data["creation"] = check_access(user, access_heads) data["dnasearch"] = check_access(user, access_moebius) || check_access(user, access_forensics_lockers) data["fingersearch"] = check_access(user, access_security) + data += NULL_RECORD + return data +#undef NULL_RECORD + + - ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open) +/datum/nano_module/tgui/records/ui_interact(mob/user, datum/tgui/ui = null) + ui = SStgui.try_update_ui(user, src, ui || currentui) if (!ui) - ui = new(user, src, ui_key, "crew_records.tmpl", name, 700, 540, state = state) - ui.auto_update_layout = 1 - ui.set_initial_data(data) - ui.open() + currentui = new(user, src, "CrewRecords", name) + currentui.open() -/datum/nano_module/records/proc/get_record_access(var/mob/user) +/datum/nano_module/tgui/records/proc/get_record_access(var/mob/user) var/list/user_access = using_access || user.GetAccess() var/obj/item/modular_computer/PC = nano_host() @@ -57,7 +63,7 @@ return user_access -/datum/nano_module/records/proc/edit_field(var/mob/user, var/field_ID) +/datum/nano_module/tgui/records/proc/edit_field(var/mob/user, var/field_ID) var/datum/computer_file/report/crew_record/R = active_record if(!R) return @@ -69,67 +75,68 @@ return F.ask_value(user) -/datum/nano_module/records/Topic(href, href_list) +/datum/nano_module/tgui/records/ui_act(action, params) if(..()) return 1 - if(href_list["clear_active"]) - active_record = null - return 1 - if(href_list["clear_message"]) - message = null - return 1 - if(href_list["set_active"]) - var/ID = text2num(href_list["set_active"]) - for(var/datum/computer_file/report/crew_record/R in GLOB.all_crew_records) - if(R.uid == ID) - active_record = R - break - return 1 - if(href_list["new_record"]) - if(!check_access(usr, access_heads)) - to_chat(usr, "Access Denied.") - return - active_record = new/datum/computer_file/report/crew_record() - GLOB.all_crew_records.Add(active_record) - return 1 - if(href_list["print_active"]) - if(!active_record) - return - print_text(record_to_html(active_record, get_record_access(usr)), usr) - return 1 - if(href_list["search"]) - var/field_name = href_list["search"] - var/search = sanitize(input("Enter the value for search for.") as null|text) - if(!search) + switch(action) + + if("clear_active") + active_record = null return 1 - for(var/datum/computer_file/report/crew_record/R in GLOB.all_crew_records) - var/datum/report_field/field = R.field_from_name(field_name) - if(lowertext(field.get_value()) == lowertext(search)) - active_record = R + if("clear_message") + message = null + return 1 + if("set_active") + var/ID = text2num(params["set_active"]) + for(var/datum/computer_file/report/crew_record/R in GLOB.all_crew_records) + if(R.uid == ID) + active_record = R + break + return 1 + if("new_record") + if(!check_access(usr, access_heads)) + to_chat(usr, "Access Denied.") + return + active_record = new/datum/computer_file/report/crew_record() + GLOB.all_crew_records.Add(active_record) + return 1 + if("print_active") + if(!active_record) + return + print_text(record_to_html(active_record, get_record_access(usr)), usr) + return 1 + if("search") + var/field_name = params["search"] + var/search = sanitize(input("Enter the value for search for.") as null|text) + if(!search) return 1 - message = "Unable to find record containing '[search]'" - return 1 + for(var/datum/computer_file/report/crew_record/R in GLOB.all_crew_records) + var/datum/report_field/field = R.field_from_name(field_name) + if(lowertext(field.get_value()) == lowertext(search)) + active_record = R + return 1 + message = "Unable to find record containing '[search]'" + return 1 var/datum/computer_file/report/crew_record/R = active_record if(!istype(R)) return 1 - if(href_list["edit_photo_front"]) - var/photo = get_photo(usr) - if(photo && active_record) - active_record.photo_front = photo - nano_ui_interact(usr) - return 1 - if(href_list["edit_photo_side"]) - var/photo = get_photo(usr) - if(photo && active_record) - active_record.photo_side = photo - nano_ui_interact(usr) - return 1 - if(href_list["edit_field"]) - edit_field(usr, text2num(href_list["edit_field"])) - return 1 + switch(action) + if("edit_photo_front") + var/photo = get_photo(usr) + if(photo && active_record) + active_record.photo_front = photo + return 1 + if("edit_photo_side") + var/photo = get_photo(usr) + if(photo && active_record) + active_record.photo_side = photo + return 1 + if("edit_field") + edit_field(usr, text2num(params["edit_field"])) + return 1 -/datum/nano_module/records/proc/get_photo(var/mob/user) +/datum/nano_module/tgui/records/proc/get_photo(var/mob/user) if(istype(user.get_active_hand(), /obj/item/photo)) var/obj/item/photo/photo = user.get_active_hand() return photo.img 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 dda21f39149..1a058588995 100644 --- a/code/modules/modular_computers/file_system/reports/crew_record.dm +++ b/code/modules/modular_computers/file_system/reports/crew_record.dm @@ -53,34 +53,131 @@ GLOBAL_VAR_INIT(arrest_security_status, "Arrest") // Medical record set_bloodtype(H ? H.b_type : "Unset") - set_medRecord((H && H.med_record && !jobban_isbanned(H, "Records") ? html_decode(H.med_record) : "No record supplied")) + var/datum/preferences/loadedprefs = H?.client?.prefs + var/datum/report_field/arrayclump/medRecord = get_linkage_medRecord() + if(H) + var/list/wounds = list() + var/list/prosthetics = list() + var/list/scannedlimbs = list() + for(var/datum/organ_description/OD in H.species.has_limbs) // default limbs for species + if(H.organs_by_name[OD.organ_tag]) + if(istype(H.organs_by_name[OD.organ_tag], OD.default_type)) // these lists contain abnormalilities, so normalities are skipped. + continue + else + var/obj/item/organ/external/organthing = H.organs_by_name[OD.organ_tag] + if(organthing.is_stump()) + wounds.Add("[organthing.name] instead of [OD.name]") + else + prosthetics.Add(organthing.name) + + scannedlimbs.Add(organthing) + // TODO: add organ checks once FBPs are better coded + else + wounds.Add("Missing [OD.name]") + var/list/addictions = list() + for(var/datum/reagent/addicted in H.metabolism_effects.addiction_list) + addictions.Add("Observed addicted to [addicted.name]") + + var/bodystate + switch(H.stat) + if(DEAD) + bodystate = list("Dead at time of writing") + if(UNCONSCIOUS) + if(H.getOxyLoss() > H.species.total_health/2) + bodystate = list("Comatose at time of writing") + else + bodystate = list("Alive at time of writing") + if(CONSCIOUS) + bodystate = list("Alive at time of writing") + + medRecord.value["wounds"] = wounds.len ? wounds : list("No wounds on record.") + medRecord.value["prosthetics"] = prosthetics.len ? prosthetics : list("No prosthetics on record.") + medRecord.value["Body state"] = bodystate ? bodystate : list("\[Data Missing\]") + medRecord.value["chemhistory"] = addictions.len ? addictions : list("Chemical record is clean.") + + var/list/psychological = list() + for(var/datum/perk/profile in H.stats.perks) + switch(profile.type) + if(PERK_NIHILIST) + psychological.Add("Has an empty outlook on life.") + if(PERK_MORALIST) + psychological.Add("High morale in groups.") + if(PERK_DRUG_ADDICT) + psychological.Add("Easily addicted, remains addicted indefinitely.") + if(PERK_ALCOHOLIC) + psychological.Add("Psychologically dependent on alcohol.") + if(PERK_REJECTED_GENIUS, PERK_NOBLE) + psychological.Add("Mentally destabilized by minor stressing factors.") + if(PERK_RAT) + psychological.Add("Innately stressed by environments, to some degree.") + if(PERK_PAPER_WORM) + psychological.Add("Accustomed to over-stress.") + if(PERK_OBORIN_SYNDROME) + psychological.Add("Innately resilient to mental harm.") + if(PERK_LOWBORN, PERK_VAGABOND) + psychological |= "Accustomed to bad living conditions." + if(PERK_SURVIVOR) + psychological.Add("Accustomed to the presence of death.") + if(PERK_NEAT) + psychological.Add("Accustomed to the presence of grime, and comforted by its removal.") + if(PERK_GREEN_THUMB) + psychological.Add("Comforted by gardening.") + if(PERK_CLUB) + psychological.Add("Provides a comfortingly professional presence.") + if(PERK_CHAINGUN_SMOKER) + psychological.Add("Invigorated by smoking.") + if(PERK_CHARMING_PERSONALITY) + psychological.Add("Provides a comfortingly charming presence.") + if(PERK_HORRIBLE_DEEDS) + psychological.Add("UNSETTLING.") + if(PERK_TERRIBLE_FATE) + psychological.Add("More afraid of death than usual.") + if(PERK_BALLS_OF_PLASTEEL) + psychological.Add("Higher pain tolerance than otherwise indicated.") + if(PERK_ARTIST) + psychological.Add("Looks at life as art.") + + medRecord.value["psychological"] = psychological.len ? psychological : list("No psychological abnormality at time of writing.") + else // if there isn't a human + var/datum/storedrecord/medical/default/medrecord = new() // just use the defaults + medrecord.transfertocomputer(medRecord) + qdel(medrecord) // Security record set_criminalStatus(GLOB.default_security_status) set_dna(H ? H.dna_trace : "") set_fingerprint(H ? H.fingers_trace : "") - set_secRecord(H && H.sec_record && !jobban_isbanned(H, "Records") ? html_decode(H.sec_record) : "No record supplied") - // Employment record - var/employment_record = "No record supplied" if(H) - if(H.gen_record && !jobban_isbanned(H, "Records")) - employment_record = html_decode(H.gen_record) - if(H.client && H.client.prefs) - var/list/qualifications - if(LAZYLEN(qualifications)) - employment_record = "[employment_record ? "[employment_record]\[br\]" : ""][jointext(qualifications, "\[br\]>")]" - set_emplRecord(employment_record) - - - if(H) - var/stats = list() - for(var/statName in ALL_STATS) - var/points = H.stats.getStat(statName,pure = TRUE) - if(points > STAT_LEVEL_NONE) - stats += "[statName]: [points] ([statPointsToLevel(points)])" + for(var/datum/perk/fate/profile in H.stats.perks) + switch(profile) + if(PERK_PAPER_WORM) + set_emplRecord("Experienced in bureacracy.") + if(PERK_FREELANCER) + set_emplRecord("Wide variety of employments.") + if(PERK_DRUG_ADDICT) + set_emplRecord("Has a history of drug addiction.") + if(PERK_ALCOHOLIC) + set_emplRecord("Is an alcoholic.") + if(PERK_NOBLE) + set_emplRecord("Is of noble origin.") + if(PERK_LOWBORN) + set_emplRecord("Was hired from poverty.") + if(!get_emplRecord()) + set_emplRecord("Standard background.") + else + set_emplRecord("No record supplied.") - set_skillset(jointext(stats,"\n")) + if(loadedprefs) + var/originfound + for(var/datum/category_group/setup_option_category/background/origin/OriginBG in loadedprefs.setup_options) + if(loadedprefs.loaded_character[OriginBG.name]) + originfound = OriginBG.name + break + if(originfound) + set_origin(originfound) + else + set_origin("Origin not on record.") // Antag record set_antagRecord(H && H.exploit_record && !jobban_isbanned(H, "Records") ? html_decode(H.exploit_record) : "") @@ -96,16 +193,16 @@ GLOBAL_VAR_INIT(arrest_security_status, "Arrest") /proc/SortModularRecords() // improved bubble sort - if(GLOB.all_crew_records.len > 1) - for(var/i = 1, i <= GLOB.all_crew_records.len, i++) - var/flag = FALSE - for(var/j = 1, j <= GLOB.all_crew_records.len - 1, j++) - var/datum/computer_file/report/crew_record/CR = GLOB.all_crew_records[j] - var/datum/computer_file/report/crew_record/CR_NEXT = GLOB.all_crew_records[j+1] - if(sorttext(CR.get_name(), CR_NEXT.get_name()) == -1) - flag = TRUE - GLOB.all_crew_records.Swap(j,j+1) - if(!flag) + if(GLOB.all_crew_records.len > 1) // if list is big enough to sort + for(var/i = 1, i <= GLOB.all_crew_records.len, i++) // for each entry in list + var/flag = FALSE // define a var as false + for(var/j = GLOB.all_crew_records.len-1, j >= 1, j--) // cycle through all entries, + var/datum/computer_file/report/crew_record/CR = GLOB.all_crew_records[j] // starting from the one before the last + var/datum/computer_file/report/crew_record/CR_NEXT = GLOB.all_crew_records[j+1] // and the last + if(sorttext(CR.get_name(), CR_NEXT.get_name()) == 1) // if the one before the last is bigger than the last + flag = TRUE // reset the var to true + GLOB.all_crew_records.Swap(j,j+1) // and swap the last and the one before the last + if(!flag) // if no work was done, stop break // Gets crew records filtered by set of positions @@ -161,9 +258,13 @@ GLOBAL_VAR_INIT(arrest_security_status, "Arrest") #define GETTER_SETTER(PATH, KEY) /datum/computer_file/report/crew_record/proc/get_##KEY(){var/datum/report_field/F = locate(/datum/report_field/##PATH/##KEY) in fields; if(F) return F.get_value()} \ /datum/computer_file/report/crew_record/proc/set_##KEY(given_value){var/datum/report_field/F = locate(/datum/report_field/##PATH/##KEY) in fields; if(F) F.set_value(given_value)} +#define SELF_GETTER(PATH, KEY) /datum/computer_file/report/crew_record/proc/get_linkage_##KEY(){return locate(/datum/report_field/##PATH/##KEY) in fields} #define SETUP_FIELD(NAME, KEY, PATH, ACCESS, ACCESS_EDIT) GETTER_SETTER(PATH, KEY); /datum/report_field/##PATH/##KEY;\ /datum/computer_file/report/crew_record/generate_fields(){..(); var/datum/report_field/##KEY = add_field(/datum/report_field/##PATH/##KEY, ##NAME);\ KEY.set_access(ACCESS, ACCESS_EDIT || ACCESS || access_heads)} +#define SETUP_ARRAYFIELD(NAME, KEY, PATH, ACCESS, ACCESS_EDIT) SELF_GETTER(PATH, KEY); /datum/report_field/##PATH/##KEY;\ +/datum/computer_file/report/crew_record/generate_fields(){..(); var/datum/report_field/##KEY = add_field(/datum/report_field/##PATH/##KEY, ##NAME);\ +KEY.set_access(ACCESS, ACCESS_EDIT || ACCESS || access_heads)} // Fear not the preprocessor, for it is a friend. To add a field, use one of these, depending on value type and if you need special access to see it. // It will also create getter/setter procs for record datum, named like /get_[key here]() /set_[key_here](value) e.g. get_name() set_name(value) @@ -174,6 +275,8 @@ KEY.set_access(ACCESS, ACCESS_EDIT || ACCESS || access_heads)} #define FIELD_LIST(NAME, KEY, OPTIONS, ACCESS, ACCESS_EDIT) FIELD_LIST_EDIT(NAME, KEY, OPTIONS, ACCESS, ACCESS_EDIT) #define FIELD_LIST_EDIT(NAME, KEY, OPTIONS, ACCESS, ACCESS_EDIT) SETUP_FIELD(NAME, KEY, options/crew_record, ACCESS, ACCESS_EDIT);\ /datum/report_field/options/crew_record/##KEY/get_options(){return OPTIONS} +#define ARRAYFIELD_SINGLE(NAME, KEY, ACCESS, ACCESS_EDIT) SETUP_ARRAYFIELD(NAME, KEY, array/crew_record, ACCESS, ACCESS_EDIT) +#define ARRAYFIELD_CLUMP(NAME, KEY, ACCESS, ACCESS_EDIT) SETUP_ARRAYFIELD(NAME, KEY, arrayclump/crew_record, ACCESS, ACCESS_EDIT) // GENERIC RECORDS FIELD_SHORT("Name", name, null, access_change_ids) @@ -189,17 +292,17 @@ FIELD_NUM("Account",account, null, access_change_ids) // MEDICAL RECORDS FIELD_LIST("Blood Type", bloodtype, GLOB.blood_types, access_moebius, access_moebius) -FIELD_LONG("Medical Record", medRecord, access_moebius, access_moebius) +ARRAYFIELD_CLUMP("Medical Record", medRecord, access_moebius, access_moebius) // SECURITY RECORDS FIELD_LIST("Criminal Status", criminalStatus, GLOB.security_statuses, access_security, access_security) -FIELD_LONG("Security Record", secRecord, access_security, access_security) +ARRAYFIELD_SINGLE("Brief", secNotes, access_security, access_security) FIELD_SHORT("DNA", dna, access_security, access_security) FIELD_SHORT("Fingerprint", fingerprint, access_security, access_security) // EMPLOYMENT RECORDS FIELD_LONG("Employment Record", emplRecord, access_heads, access_heads) -FIELD_LONG("Qualifications", skillset, access_heads, access_heads) +FIELD_LONG("Place of origin", origin, access_heads, access_heads) // ANTAG RECORDS FIELD_LONG("Exploitable Information", antagRecord, access_syndicate, access_syndicate) @@ -240,9 +343,13 @@ FIELD_LONG("Exploitable Information", antagRecord, access_syndicate, access_synd . |= BR.name */ #undef GETTER_SETTER +#undef SELF_GETTER #undef SETUP_FIELD +#undef SETUP_ARRAYFIELD #undef FIELD_SHORT #undef FIELD_LONG #undef FIELD_NUM #undef FIELD_LIST #undef FIELD_LIST_EDIT +#undef ARRAYFIELD_SINGLE +#undef ARRAYFIELD_CLUMP diff --git a/code/modules/modular_computers/file_system/reports/report.dm b/code/modules/modular_computers/file_system/reports/report.dm index 9df7d118d09..739c004893f 100644 --- a/code/modules/modular_computers/file_system/reports/report.dm +++ b/code/modules/modular_computers/file_system/reports/report.dm @@ -133,7 +133,22 @@ If the override option is set to 0, the access supplied will instead be added as dat["access"] = field.verify_access(given_access) dat["access_edit"] = field.verify_access_edit(given_access) dat["name"] = field.display_name() - dat["value"] = field.get_value() + + if(istype(field, /datum/report_field/array)) + var/datum/report_field/array/arrayfield = field + dat["list_value"] = arrayfield.value_list.Copy() + dat["list_clumps"] = null // must override with null values or else react gets weird + dat["value"] = null + else if(istype(field, /datum/report_field/arrayclump)) + var/datum/report_field/arrayclump/clumpfield = field + dat["list_value"] = null + dat["list_clumps"] = clumpfield.value + dat["value"] = null + else + dat["list_value"] = null + dat["list_clumps"] = null + dat["value"] = field.get_value() + dat["can_edit"] = field.can_edit dat["needs_big_box"] = field.needs_big_box dat["ignore_value"] = field.ignore_value diff --git a/code/modules/modular_computers/file_system/reports/report_field.dm b/code/modules/modular_computers/file_system/reports/report_field.dm index b36c199e1d9..df2e78a1327 100644 --- a/code/modules/modular_computers/file_system/reports/report_field.dm +++ b/code/modules/modular_computers/file_system/reports/report_field.dm @@ -211,4 +211,151 @@ Basic field subtypes. value_list.Remove(given_value) /datum/report_field/array/ask_value(mob/user) - add_value(input(user, "Add value", "") as null|text) + var/inputchoice = input(user, "Add or Remove value", "Field Edit", "Add") in list("Add", "Remove") + if(inputchoice == "Add") + var/toadd = input(user, "Add value", "Field Input") as null|text + if(!isnull(toadd)) + add_value(toadd) + else if(inputchoice == "Remove") + remove_value(input(user, "Choose value to remove", "Field Reduce") as null|anything in value_list ) + + + +/datum/report_field/arraylinkage + var/list/arrays = list() + ignore_value = TRUE // value is too generic to use + +// retrieves index of key +// can retrieve additional entries of same index using additionalarrays param +/datum/report_field/arraylinkage/proc/retrieve_index_of_array(key, index = 0, additionalarrays = list()) + if(!(key && (arrays.len > 0) && index > 0)) // can we access? + return FALSE + var/primeretrieved = arrays[key] // key's array + if(!(index && primeretrieved && length(primeretrieved) >= index)) // can we access the index asked for using the key? + return FALSE + var/list/toreturn = list(primeretrieved[index]) + for(var/arrayexists in additionalarrays) // all linked arrays we also want index of + if((arrayexists in arrays) && length(arrays[arrayexists]) >= index) + var/list/toadd = arrays[arrayexists] + toreturn.Add(toadd[index]) + else + return FALSE // we really don't want input from bad sources. + . = toreturn // succeeded all the checks? caller's will be done. + +// adds one index to the end of each list +// sets the contents of each list for the created index on demand using either keys or arrangement of any given input of proper size +/datum/report_field/arraylinkage/proc/add_index(list/new_entries, keyed = FALSE) + if(!new_entries || new_entries.len > arrays.len) + return FALSE + if(new_entries.len != arrays.len) // only accept using list-order based indexing when it has a 1 to 1 ratio + keyed = TRUE + var/count = 1 + if(keyed) + for(var/key in arrays) // unfitting keys are discarded, but can still disqualify a list. + var/list/currentarray = arrays[key] + if(new_entries[key]) + currentarray.Add(new_entries[key]) + else + currentarray.Add(null) // all arrays must have the same indexing for the linkage to work. + . = TRUE + else + for(var/entry in new_entries) // sanitize before it's t oo late + if(new_entries[entry]) + CRASH("keyed outside of key mode in add_index") + for(var/entry in new_entries) + var/list/currentarray = arrays?[count] + if(!currentarray) // in case a check breaks + return + count ++ + currentarray.Add(entry) + . = TRUE + +// set one entry in one list +/datum/report_field/arraylinkage/proc/edit_index(key, setto, index) + if(!arrays[key] || length(arrays[key]) < index || !islist(arrays[key])) + return FALSE + var/list/accessed = arrays[key] + if(accessed) + accessed[index] = setto + . = TRUE + +// delete one index of all lists in arraylinkage +/datum/report_field/arraylinkage/proc/remove_index(index) + if(!length(arrays) || length(arrays[1]) < index) // check if there are arrays and the first one is long enough + return FALSE // hopefully all arrays have the same length as the first one + for(var/list/arraytocut in arrays) + arraytocut.Cut(index, index+1) + . = TRUE + +/datum/report_field/arraylinkage/ask_value(mob/user) + +/datum/report_field/arrayclump // these arrays are explicitly unlinked and are stored here for categorization + value = list() // only input key=array as entry + +/datum/report_field/arrayclump/set_value(given_value) + if(!islist(given_value)) + return FALSE + . = ..() + +/datum/report_field/arrayclump/ask_value(mob/user) + . = TRUE + var/list/clumpvalue = value + if(!istype(clumpvalue)) + return FALSE + var/list/entries = clumpvalue.Copy() + entries.Add("") + + var/entrychoice = input(user, "Choose Entry Category", "Entry Category") as null | anything in entries + if(entrychoice == "" ) + var/entryname = input(user, "Choose Entry Name", "Entry Name") as text | null + entryname = sanitizeSafe(entryname) + if(!istext(entryname)) + to_chat(user, SPAN_NOTICE("Edit canceled successfully.")) + return FALSE + if(clumpvalue[entryname]) // only replace entry with alert + if(alert(user, "Replace old entry?", "Entry Replacement", "Yes", "No") == "No") + to_chat(user, SPAN_NOTICE("Edit canceled successfully.")) + return FALSE + var/startingvalue = input(user, "Create Entry", "Entry Creation") as text | null + startingvalue = sanitizeSafe(startingvalue) + if(!istext(startingvalue)) + to_chat(user, SPAN_NOTICE("Edit canceled successfully.")) + return FALSE + to_chat(user, SPAN_NOTICE("You have successfully added an entry to [name].")) + value[entryname] = list(startingvalue) + + else if(entrychoice) + var/list/selections = clumpvalue[entrychoice] + selections = selections.Copy() // don't edit the original list + selections.Add("") + var/selectionchoice = input(user, "Select Entry", "Entry") as null | anything in selections + if(!istext(selectionchoice)) + return FALSE + if(selectionchoice == "") + var/nextvalue = input(user, "Add Value", "Value") as text | null + nextvalue = sanitizeSafe(nextvalue) + if(!istext(nextvalue)) + to_chat(user, SPAN_NOTICE("Addition canceled successfully.")) + return FALSE + else + var/list/entrytoaddto = clumpvalue[entrychoice] + if(istype(entrytoaddto)) + entrytoaddto.Add(nextvalue) + else + CRASH("Type Mismatch in clump list") + + else + var/newvalue = input(user, "New Value", "Value") as text | null + newvalue = sanitizeSafe(newvalue) + if(!istext(newvalue)) + to_chat(user, SPAN_NOTICE("Replacement canceled successfully.")) + return FALSE + var/list/intermediaryvalue = clumpvalue[entrychoice] + if(istype(intermediaryvalue)) + var/indexhound = clumpvalue.Find(intermediaryvalue) // the Hound finds the value we splice + intermediaryvalue.Splice(indexhound, indexhound+1, newvalue) + else + CRASH("Type Mismatch in clump list") + + + diff --git a/code/modules/nano/modules/tgui_type.dm b/code/modules/nano/modules/tgui_type.dm new file mode 100644 index 00000000000..e605715301b --- /dev/null +++ b/code/modules/nano/modules/tgui_type.dm @@ -0,0 +1,92 @@ +/datum/nano_module/tgui + var/datum/tgui/currentui // gotta save it, we can't get it any other way + var/show_map ; var/map_z_level // the sins of our predecessors, brought to the present by the sins of our own + +/datum/nano_module/tgui/ui_host(mob/user) + return nano_host() + +/datum/nano_module/tgui/ui_close(mob/user) + . = ..() + currentui = null // must clear reference to ui + +/datum/nano_module/tgui/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/legacyicons) + ) + + +/datum/nano_module/tgui/ui_act(action, params) + . = ..() + + if(istype(host, /datum/computer_file/program)) + var/datum/computer_file/program/program = host + switch(action) + if("PC_exit") + program.computer.kill_program() + return TRUE + if("PC_enable_component") + var/obj/item/computer_hardware/H = program.computer.find_hardware_by_name(params["component"]) + if(istype(H) && !H.enabled) + H.enabled = TRUE + H.enabled() + . = TRUE + if("PC_disable_component") + var/obj/item/computer_hardware/H = program.computer.find_hardware_by_name(params["component"]) + if(istype(H) && H.enabled) + H.enabled = FALSE + H.disabled() + . = TRUE + if("PC_toggle_component") + var/obj/item/computer_hardware/H = program.computer.find_hardware_by_name(params["component"]) + if(istype(H)) + H.enabled = !H.enabled + if(H.enabled) + H.enabled() + else + H.disabled() + . = TRUE + if("PC_shutdown") + program.computer.shutdown_computer() + return TRUE + if("PC_minimize") + var/mob/user = usr + program.computer.minimize_program(user) + + if("PC_killprogram") + var/prog_name = params["PC_killprogram"] + var/obj/item/computer_hardware/hard_drive/prog_disk = locate(params["disk"]) in program.computer + if(!prog_disk) + return TRUE + + for(var/p in program.computer.all_threads) + var/datum/computer_file/program/PRG = p + if(PRG.program_state == PROGRAM_STATE_KILLED) + continue + + if(PRG.filename == prog_name && (PRG in prog_disk.stored_files)) + PRG.kill_program(forced=TRUE) + to_chat(usr, SPAN_NOTICE("Program [PRG.filename].[PRG.filetype] has been killed.")) + . = TRUE + + if("PC_runprogram") + var/obj/item/computer_hardware/hard_drive/prog_disk = locate(params["disk"]) in program.computer + return program.computer.run_program(params["PC_runprogram"], prog_disk) + + if("PC_setautorun") + if(!program.computer.hard_drive) + return + program.computer.set_autorun(params["PC_setautorun"]) + if("PC_terminal") + program.computer.open_terminal(usr) + return TRUE + +/datum/nano_module/tgui/ui_status(mob/user, datum/ui_state/state) + . = ..(user, state ? state : GLOB.default_state) + if(. > UI_DISABLED && istype(host, /datum/computer_file/program)) + var/datum/computer_file/program/relevant = host + if(relevant.program_state == PROGRAM_STATE_KILLED) + . = UI_CLOSE + else if(relevant.program_state == PROGRAM_STATE_BACKGROUND) + . = min(., UI_UPDATE) // theoretically might be necessary with a new system, if redundant just collapse this with the killing check. + + diff --git a/code/modules/organs/internal/_internal.dm b/code/modules/organs/internal/_internal.dm index 069c688417f..447f0bea084 100644 --- a/code/modules/organs/internal/_internal.dm +++ b/code/modules/organs/internal/_internal.dm @@ -56,7 +56,7 @@ UnregisterSignal(src, COMSIG_IORGAN_ADD_WOUND) UnregisterSignal(src, COMSIG_IORGAN_REMOVE_WOUND) UnregisterSignal(src, COMSIG_IORGAN_REFRESH_SELF) - ..() + . = ..() /obj/item/organ/internal/removed() UnregisterSignal(parent, COMSIG_IORGAN_WOUND_COUNT) @@ -405,6 +405,7 @@ /obj/item/organ/internal/rejuvenate() status = null + current_blood = initial(current_blood) for(var/woundtype in wounddatums) remove_wound(wounddatums[woundtype]) diff --git a/code/modules/organs/internal/carrion.dm b/code/modules/organs/internal/carrion.dm index 67fdc9aa3ab..2891cdc4219 100644 --- a/code/modules/organs/internal/carrion.dm +++ b/code/modules/organs/internal/carrion.dm @@ -32,6 +32,7 @@ /obj/item/organ/internal/carrion max_damage = 15 //resilient scanner_hidden = TRUE //sneaky + origin_tech = list(TECH_BIO = 5) /obj/item/organ/internal/carrion/chemvessel name = "chemical vessel" @@ -376,12 +377,17 @@ to_chat(owner, SPAN_WARNING("You can't eat nothing.")) return - if(istype(food, /obj/item/grab)) + var/obj/item/holder/overcomplicated = istype(food, /obj/item/holder) ? food : null + if(istype(food, /obj/item/grab) || overcomplicated && ishuman(overcomplicated.contained)) var/obj/item/grab/grab = food - var/mob/living/carbon/human/H = grab.affecting - if (grab.state < GRAB_AGGRESSIVE) - to_chat(owner, SPAN_WARNING("Your grip upon [H.name] is too weak.")) - return + var/mob/living/carbon/human/H + if(istype(grab)) + H = grab.affecting + if (grab.state < GRAB_AGGRESSIVE) + to_chat(owner, SPAN_WARNING("Your grip upon [H.name] is too weak.")) + return + else if(overcomplicated) + H = overcomplicated.contained if(istype(H)) var/obj/item/organ/external/E = H.get_organ(owner.targeted_organ) if (tearing) // one at a time, thank you. @@ -401,8 +407,7 @@ for (var/obj/item/organ/internal/to_blacklist in E.internal_organs) if (istype(to_blacklist, /obj/item/organ/internal/bone/)) blacklist += to_blacklist - continue - if (istype(to_blacklist, /obj/item/organ/internal/vital/brain/)) + else if (istype(to_blacklist, /obj/item/organ/internal/vital/brain/)) blacklist += to_blacklist// removing bones from a valid_organs list based on var/list/valid_organs = E.internal_organs - blacklist// E.internal_organs gibs the victim. if (!valid_organs.len) @@ -419,7 +424,7 @@ to_chat(owner, SPAN_WARNING("You can only tear flesh out of humanoids!")) return - if(istype(food, /obj/item/organ) || istype(food, /obj/item/reagent_containers/food/snacks/meat)) + if(istype(food, /obj/item/organ) || istype(food, /obj/item/reagent_containers/food/snacks/meat) || istype(food, /obj/item/holder)) var/geneticpointgain = 0 var/chemgain = 0 var/taste_description = "" @@ -437,11 +442,15 @@ var/obj/item/organ/internal/carrion/core/G = owner.random_organ_by_process(BP_SPCORE) if(O in G.associated_carrion_organs) taste_description = "albeit delicious, your own organs carry no new genetic material" + chemgain = 50 else owner.carrion_hunger += 3 geneticpointgain = 4 chemgain = 50 taste_description = "carrion organs taste heavenly, you need more!" + if(istype(O, /obj/item/organ/internal/carrion/core)) + var/obj/item/organ/internal/carrion/core/devoured = O + G.absorbed_dna |= devoured.absorbed_dna else if(istype(O, /obj/item/organ/internal)) var/organ_rotten = FALSE if (O.status & ORGAN_DEAD) @@ -464,9 +473,25 @@ taste_description = "human meat is satisfying." else - chemgain = 5 - owner.carrion_hunger -= 1 //Prevents meat eating spam for infinate chems - taste_description = "this meat is bland." + if(istype(food, /obj/item/holder/carrion)) + owner.carrion_hunger += 9 + geneticpointgain = 10 + chemgain = 50 + var/obj/item/holder/spiderholder = food + var/mob/living/simple_animal/spider_core/tastyspider = spiderholder.contained + var/obj/item/organ/internal/carrion/core/devoured = locate(/obj/item/organ/internal/carrion/core) in tastyspider.contents + var/obj/item/organ/internal/carrion/core/C = owner.random_organ_by_process(BP_SPCORE) + if(devoured && C) + C.absorbed_dna |= devoured.absorbed_dna + taste_description = "carrions taste heavenly, if only there was more!" + qdel(tastyspider) + else + if(istype(food, /obj/item/holder)) + var/obj/item/holder/bland_animal = food + qdel(bland_animal.contained) + chemgain = 5 + owner.carrion_hunger -= 1 //Prevents meat eating spam for infinate chems + taste_description = "this meat is bland." var/obj/item/organ/internal/carrion/core/C = owner.random_organ_by_process(BP_SPCORE) if(C) @@ -477,7 +502,7 @@ var/chemvessel_efficiency = owner.get_organ_efficiency(OP_CHEMICALS) if(chemvessel_efficiency > 1) - owner.carrion_stored_chemicals = min(owner.carrion_stored_chemicals + 0.01 * chemvessel_efficiency , 0.5 * chemvessel_efficiency) + owner.carrion_stored_chemicals = min(owner.carrion_stored_chemicals + 0.01 * chemvessel_efficiency * chemgain , 0.5 * chemvessel_efficiency) to_chat(owner, SPAN_NOTICE("You consume \the [food], [taste_description].")) visible_message(SPAN_DANGER("[owner] devours \the [food]!")) @@ -555,7 +580,7 @@ continue toxin_attack(creature, rand(1, 3)) -/obj/effect/decal/cleanable/solid_biomass/attackby(var/obj/item/I, var/mob/user) +/obj/effect/decal/cleanable/carrion_puddle/attackby(var/obj/item/I, var/mob/user) if(istype(I, /obj/item/mop) || istype(I, /obj/item/soap)) to_chat(user, SPAN_NOTICE("You started cleaning this [src].")) if(do_after(user, 3 SECONDS, src)) diff --git a/code/modules/organs/internal/internal_organ_processes.dm b/code/modules/organs/internal/internal_organ_processes.dm index 1b9b97dd5b5..05590ed2015 100644 --- a/code/modules/organs/internal/internal_organ_processes.dm +++ b/code/modules/organs/internal/internal_organ_processes.dm @@ -259,6 +259,10 @@ if(carrion_hunger < max_hunger) carrion_hunger = min(carrion_hunger + (round(1* (maw_efficiency / 100))), max_hunger) else + if(ingested.has_reagent("nutriment", 1)) + ingested.remove_reagent("nutriment", 1) + else + nutrition = max(0, nutrition - 20) // equivalent to a unit of nutriment to_chat(src, SPAN_WARNING("Your hunger is restless!")) carrion_last_hunger = world.time diff --git a/code/modules/organs/wound.dm b/code/modules/organs/wound.dm index 3c0e65a0e9a..37d86a53b89 100644 --- a/code/modules/organs/wound.dm +++ b/code/modules/organs/wound.dm @@ -143,6 +143,7 @@ proc/open_wound(damage) src.damage += damage bleed_timer += damage + clamped = FALSE while(src.current_stage > 1 && src.damage_list[current_stage-1] <= src.damage / src.amount) src.current_stage-- diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index db805e53355..481428103a6 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -107,22 +107,12 @@ /obj/structure/filingcabinet/security/populate() if(virgin) - for(var/datum/data/record/G in data_core.general) - var/datum/data/record/S - for(var/datum/data/record/R in data_core.security) - if((R.fields["name"] == G.fields["name"] || R.fields["id"] == G.fields["id"])) - S = R - break + for(var/datum/computer_file/report/crew_record/G in GLOB.all_crew_records) var/obj/item/paper/P = new /obj/item/paper(src) P.info = "
Security Record

" - P.info += "Name: [G.fields["name"]] ID: [G.fields["id"]]
\nSex: [G.fields["sex"]]
\nAge: [G.fields["age"]]
\nFingerprint: [G.fields["fingerprint"]]
\nPhysical Status: [G.fields["p_stat"]]
\nMental Status: [G.fields["m_stat"]]
" - P.info += "
\n
Security Data

\nCriminal Status: [S.fields["criminal"]]
\n
\nMinor Crimes: [S.fields["mi_crim"]]
\nDetails: [S.fields["mi_crim_d"]]
\n
\nMajor Crimes: [S.fields["ma_crim"]]
\nDetails: [S.fields["ma_crim_d"]]
\n
\nImportant Notes:
\n\t[S.fields["notes"]]
\n
\n
Comments/Log

" - var/counter = 1 - while(S.fields["com_[counter]"]) - P.info += "[S.fields["com_[counter]"]]
" - counter++ + P.info += "Name: [G.get_name()]
\nSex: [G.get_sex()]
\nAge: [G.get_age()]
\nFingerprint: [G.get_fingerprint()]
" P.info += "" - P.name = "Security Record ([G.fields["name"]])" + P.name = "Security Record ([G.get_name()])" virgin = 0 //tabbing here is correct- it's possible for people to try and use it //before the records have been generated, so we do this inside the loop. @@ -142,24 +132,21 @@ /obj/structure/filingcabinet/medical/populate() if(virgin) - for(var/datum/data/record/G in data_core.general) - var/datum/data/record/M - for(var/datum/data/record/R in data_core.medical) - if((R.fields["name"] == G.fields["name"] || R.fields["id"] == G.fields["id"])) - M = R - break + for(var/datum/computer_file/report/crew_record/G in GLOB.all_crew_records) + var/datum/report_field/arrayclump/M = G.get_linkage_medRecord() if(M) var/obj/item/paper/P = new /obj/item/paper(src) - P.info = "
Medical Record

" - P.info += "Name: [G.fields["name"]] ID: [G.fields["id"]]
\nSex: [G.fields["sex"]]
\nAge: [G.fields["age"]]
\nFingerprint: [G.fields["fingerprint"]]
\nPhysical Status: [G.fields["p_stat"]]
\nMental Status: [G.fields["m_stat"]]
" - - P.info += "
\n
Medical Data

\nBlood Type: [M.fields["b_type"]]
\nDNA: [M.fields["b_dna"]]
\n
\nMinor Disabilities: [M.fields["mi_dis"]]
\nDetails: [M.fields["mi_dis_d"]]
\n
\nMajor Disabilities: [M.fields["ma_dis"]]
\nDetails: [M.fields["ma_dis_d"]]
\n
\nAllergies: [M.fields["alg"]]
\nDetails: [M.fields["alg_d"]]
\n
\nCurrent Diseases: [M.fields["cdi"]] (per disease info placed in log/comment section)
\nDetails: [M.fields["cdi_d"]]
\n
\nImportant Notes:
\n\t[M.fields["notes"]]
\n
\n
Comments/Log

" - var/counter = 1 - while(M.fields["com_[counter]"]) - P.info += "[M.fields["com_[counter]"]]
" - counter++ - P.info += "" - P.name = "Medical Record ([G.fields["name"]])" + var/list/infostoadd = list() + infostoadd += "
Medical Record

" + infostoadd += "Name: [G.get_name()]
\nSex: [G.get_sex()]
\nAge: [G.get_age()]
" + + infostoadd += "
\n
Medical Data

\nBlood Type: [G.get_bloodtype()]
\nDNA: [G.get_dna()]
" + infostoadd += "
\nProsthetics: [M.value["prosthetics"]]
\nWounds: [M.value["wounds"]]
\n
\nAutopsy: [M.value["Body state"]]
" + infostoadd +="
\nChemical History: [M.value["chemhistory"]]
\nPsychological Profile: [M.value["psychological"]]
" + + infostoadd += "" + P.name = "Medical Record ([G.get_name()])" + P.info = infostoadd.Join() // minor optimization virgin = 0 //tabbing here is correct- it's possible for people to try and use it //before the records have been generated, so we do this inside the loop. diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 68adc53e1f1..a846b75f986 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -230,7 +230,7 @@ if(flashlight_attachment) flashlight_attachment.forceMove(get_turf(src)) flashlight_attachment = null - ..() + . = ..() /obj/item/gun/proc/set_item_state(state, hands = TRUE, back = FALSE, onsuit = FALSE) var/wield_state @@ -1017,6 +1017,7 @@ sharp = initial(sharp) braceable = initial(braceable) recoil = getRecoil(init_recoil[1], init_recoil[2], init_recoil[3]) + w_class = initial(w_class) attack_verb = list() if(LAZYLEN(custom_default)) // this override is used by the artwork_revolver for RNG gun stats diff --git a/code/modules/projectiles/guns/projectile/battle_rifle/boltgun.dm b/code/modules/projectiles/guns/projectile/battle_rifle/boltgun.dm index 90694a08547..6630573aa64 100644 --- a/code/modules/projectiles/guns/projectile/battle_rifle/boltgun.dm +++ b/code/modules/projectiles/guns/projectile/battle_rifle/boltgun.dm @@ -77,14 +77,14 @@ playsound(src.loc, 'sound/weapons/guns/interact/rifle_boltback.ogg', 75, 1) bolt_open = !bolt_open if(bolt_open) - if(contents.len) + if(length(loaded)) if(chambered) to_chat(user, SPAN_NOTICE("You work the [message] open, ejecting [chambered]!")) chambered.forceMove(get_turf(src)) loaded -= chambered chambered = null else - var/obj/item/ammo_casing/B = loaded[loaded.len] + var/obj/item/ammo_casing/B = loaded[1] if(!B.is_caseless) to_chat(user, SPAN_NOTICE("You work the [message] open, ejecting [B]!")) B.forceMove(get_turf(src)) @@ -196,7 +196,7 @@ icon = 'icons/obj/guns/projectile/riose.dmi' icon_state = "boltgun_hand" item_suffix = "_hand" - matter = list(MATERIAL_STEEL = 10, MATERIAL_WOOD = 5) + matter = list(MATERIAL_STEEL = 13, MATERIAL_WOOD = 5) wielded_item_state = "_doble_hand" w_class = ITEM_SIZE_HUGE slot_flags = SLOT_BACK @@ -221,7 +221,7 @@ matter = list(MATERIAL_STEEL = 5) resultvars = list(/obj/item/gun/projectile/boltgun/handmade) gripvars = list(/obj/item/part/gun/modular/grip/wood) - mechanismvar = /obj/item/part/gun/modular/mechanism/boltgun + mechanismvar = /obj/item/part/gun/modular/mechanism/boltgun/junk barrelvars = list(/obj/item/part/gun/modular/barrel/lrifle/steel, /obj/item/part/gun/modular/barrel/srifle/steel, /obj/item/part/gun/modular/barrel/clrifle/steel) //// OBREZ //// diff --git a/code/modules/projectiles/guns/projectile/flaregun.dm b/code/modules/projectiles/guns/projectile/flaregun.dm index bf1f285697b..5a2c1eea232 100644 --- a/code/modules/projectiles/guns/projectile/flaregun.dm +++ b/code/modules/projectiles/guns/projectile/flaregun.dm @@ -45,14 +45,14 @@ playsound(loc, 'sound/weapons/guns/interact/rev_cock.ogg', 75, 1) bolt_open = !bolt_open if(bolt_open) - if(loaded.len) + if(length(loaded)) if(chambered) to_chat(user, SPAN_NOTICE("You snap the barrel open, ejecting [chambered]!")) chambered.forceMove(get_turf(src)) loaded -= chambered chambered = null else - var/obj/item/ammo_casing/shell = loaded[loaded.len] + var/obj/item/ammo_casing/shell = loaded[1] to_chat(user, SPAN_NOTICE("You snap the barrel open, ejecting [shell]!")) shell.forceMove(get_turf(src)) loaded -= shell diff --git a/code/modules/projectiles/guns/projectile/modular.dm b/code/modules/projectiles/guns/projectile/modular.dm index f5ea3f514c0..0d230834c44 100644 --- a/code/modules/projectiles/guns/projectile/modular.dm +++ b/code/modules/projectiles/guns/projectile/modular.dm @@ -51,6 +51,9 @@ max_upgrades = 6 + var/list/scope_damage_adds = list() + var/datum/gunoverrides/overridedatum + /obj/item/gun/projectile/automatic/modular/Initialize() gun_tags += GUN_MODULAR @@ -59,6 +62,7 @@ var/obj/item/part/gun/modular/new_part = new partPath(quality = gun_parts[partPath]) if(!new_part.I.rapid_apply(src)) visible_message(SPAN_WARNING("Something seems wrong... Maybe you should ask a professional for help?")) + overridedatum = new() refresh_upgrades() . = ..() update_icon() @@ -80,7 +84,12 @@ verbs -= MODULAR_VERBS // Removes all modularized verbs grip_type = initial(grip_type) good_calibers = list() // Won't ever be redefined, mechanism determines this, and when no mechanism is installed, we don't want anything here anyways + no_internal_mag = initial(no_internal_mag) + scope_damage_adds = list() + overridedatum?.reset() // clear first ..() + reset_action_buttons() + overridedatum?.cycle() // then use an assignment sort name = get_initial_name() /obj/item/gun/projectile/automatic/modular/update_icon() // V2 @@ -157,6 +166,75 @@ // Interactions +/datum/gunoverrides + var/list/priorities = list() + +/datum/gunoverrides/proc/reset() + for(var/list/wiped in priorities) + wiped.Cut() + priorities.Cut() + +/datum/gunoverrides/proc/call_Flag(obj/item/load, user, flag) + for(var/key in priorities) + var/list/priority = priorities[key] + var/done = FALSE + for(var/datum/guninteraction/tocheck in priority) // highest numbers first. + if(tocheck.interactionflags & flag) + switch(flag) + if(GI_ATTACKSELF) + if(tocheck.attack_self(user)) + done = TRUE + if(GI_LOAD) + if(tocheck.load_ammo(load, user)) + done = TRUE + if(GI_UNLOAD) + if(tocheck.unload_ammo(user)) + done = TRUE + if(GI_SPECIAL) + if(tocheck.special_check(user)) + done = TRUE + if(done) + return TRUE + +/datum/gunoverrides/proc/cycle() + var/list/slate = list() + for(var/number = 4, number >= 0, number -= 1) + slate["[number]"] = priorities["[number]"] ? priorities["[number]"] : null + priorities = slate.Copy() + +/obj/item/gun/projectile/automatic/modular/attack_self(mob/user) + if(!overridedatum.call_Flag(user = user, flag = GI_ATTACKSELF)) + . = ..() + +/obj/item/gun/projectile/automatic/modular/load_ammo(obj/item/A, mob/user) + if(!overridedatum.call_Flag(load = A, user = user, flag = GI_LOAD)) + . = ..() + + +/obj/item/gun/projectile/automatic/modular/unload_ammo(mob/user, allow_dump) + if(!overridedatum.call_Flag(user = user, flag = GI_UNLOAD)) + . = ..() + +/obj/item/gun/projectile/automatic/modular/special_check(mob/user) + if(!overridedatum.call_Flag(user = user, flag = GI_SPECIAL)) + . = ..() + +/obj/item/gun/projectile/automatic/modular/hand_spin(mob/living/carbon/caller) + overridedatum.call_Flag(user = caller, flag = GI_SPIN) + +/obj/item/gun/projectile/automatic/modular/proc/reset_action_buttons() + for(var/key in overridedatum.priorities) + var/list/priority = overridedatum.priorities[key] + for(var/datum/guninteraction/tocheck in priority) // highest numbers first. + if(tocheck.action_button_name && tocheck.action_button_proc) + action_button_name = tocheck.action_button_name + action_button_proc = tocheck.action_button_proc + return TRUE // can only have one button + // if we didn't override them + action_button_name = initial(action_button_name) + action_button_proc = initial(action_button_proc) + qdel(action) + /obj/item/gun/projectile/automatic/modular/can_interact(mob/user) if((!ishuman(user) && (loc != user)) || user.stat || user.restrained()) return 1 @@ -194,16 +272,19 @@ /obj/item/gun/projectile/automatic/modular/proc/fold(user) if(PARTMOD_FOLDING_STOCK & spriteTags) - if(PARTMOD_FOLDING_STOCK & statusTags) - to_chat(user, SPAN_NOTICE("You fold the stock on \the [src].")) - statusTags -= PARTMOD_FOLDING_STOCK - w_class = initial(w_class) - else - to_chat(user, SPAN_NOTICE("You unfold the stock on \the [src].")) - statusTags |= PARTMOD_FOLDING_STOCK - w_class = initial(w_class) + 1 - + for(var/obj/item/part/gun/modular/stock/toedit in gun_parts) // only gonna edit one, doing this to find it + if(PARTMOD_FOLDING_STOCK & statusTags) + to_chat(user, SPAN_NOTICE("You fold the stock on \the [src].")) + statusTags -= PARTMOD_FOLDING_STOCK + toedit.I.weapon_upgrades[GUN_UPGRADE_DEFINE_WCLASS] = 0 + else + to_chat(user, SPAN_NOTICE("You unfold the stock on \the [src].")) + statusTags |= PARTMOD_FOLDING_STOCK + toedit.I.weapon_upgrades[GUN_UPGRADE_DEFINE_WCLASS] = toedit.wclassmod + break + refresh_upgrades() + playsound(loc, 'sound/weapons/guns/interact/selector.ogg', 100, 1) update_icon() @@ -218,3 +299,14 @@ return FALSE load_ammo(I, user) update_held_icon() + +/obj/item/gun/projectile/automatic/modular/zoom(tileoffset, viewsize, stayzoomed) + ..() + refresh_upgrades() + if(zoom) + var/currentzoom = zoom_factors.Find(active_zoom_factor) + var/extra_damage + if(scope_damage_adds[currentzoom]) + extra_damage = scope_damage_adds[currentzoom] + damage_multiplier += extra_damage + diff --git a/code/modules/projectiles/guns/projectile/modular/interactions.dm b/code/modules/projectiles/guns/projectile/modular/interactions.dm new file mode 100644 index 00000000000..92cc43349c8 --- /dev/null +++ b/code/modules/projectiles/guns/projectile/modular/interactions.dm @@ -0,0 +1,99 @@ +/datum/guninteraction + var/obj/item/gun/projectile/automatic/modular/parentgun + var/obj/item/part/gun/modular/parentpart + var/priority = 0 + var/interactionflags + var/action_button_name = "" + var/action_button_proc = "" + +/datum/guninteraction/proc/attack_self(mob/user) + +/datum/guninteraction/proc/update_icon() + +/datum/guninteraction/proc/load_ammo(var/obj/item/A, mob/user) + +/datum/guninteraction/proc/unload_ammo(mob/user, var/allow_dump=1) + +/datum/guninteraction/proc/special_check(mob/user) + +/datum/guninteraction/New(newparent) + parentpart = newparent + +/datum/guninteraction/bolted + var/bolt_open = FALSE + var/message = "bolt" + interactionflags = GI_ATTACKSELF|GI_LOAD|GI_UNLOAD|GI_SPECIAL + + +/datum/guninteraction/bolted/New(newparent) + ..() + parentpart.part_overlay = jointext(list(initial(parentpart.part_overlay),"bolt_closed"), "") + +/datum/guninteraction/bolted/attack_self(mob/user) + bolt_act(user) + . = TRUE + +/datum/guninteraction/bolted/update_icon() + if(bolt_open) + parentpart.part_overlay = jointext(list(initial(parentpart.part_overlay),"bolt_open"), "") + else + parentpart.part_overlay = jointext(list(initial(parentpart.part_overlay),"bolt_closed"), "") + parentgun.update_icon() + +/datum/guninteraction/bolted/load_ammo(var/obj/item/A, mob/user) + if(!bolt_open) + return TRUE // disable operations + +/datum/guninteraction/bolted/unload_ammo(mob/user, var/allow_dump=1) + if(!bolt_open) + return TRUE // disable operations + + +/datum/guninteraction/bolted/special_check(mob/user) + if(bolt_open) + to_chat(user, SPAN_WARNING("You can't fire [parentgun] while the [message] is open!")) + return TRUE + +/datum/guninteraction/bolted/proc/bolt_act(mob/living/user) + + playsound(parentgun.loc, 'sound/weapons/guns/interact/rifle_boltback.ogg', 75, 1) + bolt_open = !bolt_open + if(bolt_open) + if(length(parentgun.loaded)||parentgun.chambered) + if(parentgun.chambered) + to_chat(user, SPAN_NOTICE("You work the [message] open, ejecting [parentgun.chambered]!")) + parentgun.chambered.forceMove(get_turf(parentgun)) + parentgun.loaded -= parentgun.chambered + parentgun.chambered = null + else + var/obj/item/ammo_casing/B = parentgun.loaded[1] + if(!B.is_caseless) + to_chat(user, SPAN_NOTICE("You work the [message] open, ejecting [B]!")) + B.forceMove(get_turf(parentgun)) + parentgun.loaded -= B + else + to_chat(user, SPAN_NOTICE("You work the [message] open.")) + B = parentgun.loaded[1] + parentgun.loaded -= B + qdel(B) + else + to_chat(user, SPAN_NOTICE("You work the [message] open.")) + else + to_chat(user, SPAN_NOTICE("You work the [message] closed.")) + playsound(parentgun.loc, 'sound/weapons/guns/interact/rifle_boltforward.ogg', 75, 1) + bolt_open = 0 + parentgun.add_fingerprint(user) + update_icon() + +/datum/guninteraction/zoomed + priority = 1 + interactionflags = GI_ATTACKSELF + +/datum/guninteraction/zoomed/attack_self(mob/user) + if(parentgun?.zoom) + parentgun.toggle_scope(user) + return TRUE + +/datum/guninteraction/zoomed/multizoom + action_button_name = "Switch zoom level" + action_button_proc = "switch_zoom" diff --git a/code/modules/projectiles/guns/projectile/modular/modular_bolt.dm b/code/modules/projectiles/guns/projectile/modular/modular_bolt.dm new file mode 100644 index 00000000000..ab1bb03f566 --- /dev/null +++ b/code/modules/projectiles/guns/projectile/modular/modular_bolt.dm @@ -0,0 +1,83 @@ +/obj/item/gun/projectile/automatic/modular/bolt // frame + name = "Excelsior BR .30 \"Kardashev-Mosin\"" + desc = "Weapon for hunting, or endless trench warfare. \ + If you’re on a budget, it’s a darn good rifle for just about everything." + icon = 'icons/obj/guns/projectile/modular/bolt.dmi' + slot_flags = SLOT_BACK + origin_tech = list(TECH_COMBAT = 2, TECH_MATERIAL = 2) + w_class = ITEM_SIZE_BULKY + force = WEAPON_FORCE_ROBUST + handle_casings = HOLD_CASINGS + load_method = SINGLE_CASING|SPEEDLOADER + matter = list(MATERIAL_PLASTEEL = 5, MATERIAL_PLASTIC = 4) + price_tag = 900 + spawn_blacklisted = TRUE + twohanded = TRUE + spriteTagBans = PARTMOD_FOLDING_STOCK + init_recoil = SLATE_RECOIL(1.5) + required_parts = list(/obj/item/part/gun/modular/barrel = 0, /obj/item/part/gun/modular/grip = 0, /obj/item/part/gun/modular/stock = 0,\ + /obj/item/part/gun/modular/mechanism/boltgun = 0, /obj/item/part/gun/modular/sights = -1, /obj/item/part/gun/modular/bayonet = -1) + init_firemodes = list() // boltguns don't have firemodes! + +/obj/item/gun/projectile/automatic/modular/bolt/get_initial_name() + if(grip_type) + switch(grip_type) + if("wood") + if(caliber == CAL_SRIFLE) + return "FS SR .20 \"Arasaka\"" // or small + else + return "SA SR [caliber] \"Novakovic\"" // we love/fear them all + if("black") + return "NT SR [caliber] \"Eradicator\"" + if("rubber") + return "FS SR [caliber] \"Kadmin\"" + if("excelsior") + return "Excelsior SR [caliber] \"Kardashev-Mosin\"" + if("serbian") + return "SA AMR [caliber] \"Hristov\"" // big + if("makeshift") + return "HM SR [caliber] \"Riose\"" + else + return "SR [caliber] \"Boltie\"" + +/obj/item/gun/projectile/automatic/modular/bolt/excel + gun_parts = list(/obj/item/part/gun/modular/grip/excel = 0, /obj/item/part/gun/modular/mechanism/boltgun = 0, /obj/item/part/gun/modular/barrel/lrifle/steel = 0, \ + /obj/item/part/gun/modular/stock/longrifle = 0, /obj/item/part/gun/modular/bayonet = 0) + +/obj/item/gun/projectile/automatic/modular/bolt/serbian + desc = "Weapon for hunting, or endless trench warfare. \ + If you’re on a budget, it’s a darn good rifle for just about everything. \ + This copy, in fact, is a reverse-engineered poor-quality copy of a more perfect copy of an ancient rifle" + init_recoil = SLATE_RECOIL(1.7) + spawn_blacklisted = FALSE + +/obj/item/gun/projectile/automatic/modular/bolt/serbian/finished + gun_parts = list(/obj/item/part/gun/modular/grip/wood = 1, /obj/item/part/gun/modular/mechanism/boltgun = 0,\ + /obj/item/part/gun/modular/barrel/lrifle/steel = 0, /obj/item/part/gun/modular/stock/longrifle = 0, /obj/item/part/gun/modular/bayonet/steel = 0) + +/obj/item/gun/projectile/automatic/modular/bolt/fs + gun_parts = list(/obj/item/part/gun/modular/grip/rubber = 0, /obj/item/part/gun/modular/mechanism/boltgun = 0, /obj/item/part/gun/modular/barrel/srifle/long = 0,\ + /obj/item/part/gun/modular/stock/longrifle = 0, /obj/item/part/gun/modular/sights/scopebig = 0) + +/obj/item/gun/projectile/automatic/modular/bolt/fs/civilian + gun_parts = list(/obj/item/part/gun/modular/grip/wood = -1, /obj/item/part/gun/modular/mechanism/boltgun = 0, /obj/item/part/gun/modular/barrel/srifle/long = 0,\ + /obj/item/part/gun/modular/stock/longrifle = 0, /obj/item/part/gun/modular/sights/scopesmall = 0) // nerfed the stock to simulate civilian shittyness that apparently increases recoil by 1/9th + spawn_blacklisted = FALSE + +/obj/item/gun/projectile/automatic/modular/bolt/handmade + desc = "A handmade bolt action rifle, made from junk and some spare parts." + spawn_blacklisted = FALSE + matter = list(MATERIAL_STEEL = 4) + init_recoil = SLATE_RECOIL(2) // lower quality frame + price_tag = 800 + +/obj/item/gun/projectile/automatic/modular/bolt/handmade/finished + gun_parts = list(/obj/item/part/gun/modular/grip/makeshift = 0, /obj/item/part/gun/modular/mechanism/boltgun/junk = 0, /obj/item/part/gun/modular/barrel/lrifle/steel = 0,\ + /obj/item/part/gun/modular/stock/longrifle = 0, /obj/item/part/gun/modular/bayonet = 0) + +/obj/item/gun/projectile/automatic/modular/bolt/sniper + desc = "A portable anti-armour rifle, it was originally designed for use against armoured exosuits. It is capable of punching through windows and non-reinforced walls with ease, but suffers from overpenetration at close range. Fires armor piercing .60 shells." + +/obj/item/gun/projectile/automatic/modular/bolt/sniper/finished + gun_parts = list(/obj/item/part/gun/modular/grip/serb = 0, /obj/item/part/gun/modular/mechanism/boltgun/heavy = 0, /obj/item/part/gun/modular/barrel/antim/long = 0,\ + /obj/item/part/gun/modular/stock/heavy = 0, /obj/item/part/gun/modular/sights/customizable/scopeheavy = 0) diff --git a/code/modules/projectiles/guns/projectile/shotgun/doublebarrel.dm b/code/modules/projectiles/guns/projectile/shotgun/doublebarrel.dm index 55441bf8449..e1e211f294c 100644 --- a/code/modules/projectiles/guns/projectile/shotgun/doublebarrel.dm +++ b/code/modules/projectiles/guns/projectile/shotgun/doublebarrel.dm @@ -64,7 +64,6 @@ else playsound(src.loc, 'sound/weapons/guns/interact/shotgun_close.ogg', 75, 1) to_chat(user, SPAN_NOTICE("You snap the barrel closed")) - bolt_open = 0 add_fingerprint(user) update_icon() diff --git a/code/modules/projectiles/guns/projectile/sniper.dm b/code/modules/projectiles/guns/projectile/sniper.dm index 6e3a79cf5e6..66bd2daa097 100644 --- a/code/modules/projectiles/guns/projectile/sniper.dm +++ b/code/modules/projectiles/guns/projectile/sniper.dm @@ -83,14 +83,14 @@ playsound(src.loc, 'sound/weapons/guns/interact/rifle_boltback.ogg', 75, 1) bolt_open = !bolt_open if(bolt_open) - if(contents.len) + if(length(loaded)) if(chambered) to_chat(user, SPAN_NOTICE("You work the bolt open, ejecting [chambered]!")) chambered.forceMove(get_turf(src)) loaded -= chambered chambered = null else - var/obj/item/ammo_casing/B = loaded[loaded.len] + var/obj/item/ammo_casing/B = loaded[1] to_chat(user, SPAN_NOTICE("You work the bolt open, ejecting [B]!")) B.forceMove(get_turf(src)) loaded -= B diff --git a/code/modules/random_map/automata/caves.dm b/code/modules/random_map/automata/caves.dm index 5dac23f32e5..1695af497ea 100644 --- a/code/modules/random_map/automata/caves.dm +++ b/code/modules/random_map/automata/caves.dm @@ -40,6 +40,10 @@ // Create ore turfs. /datum/random_map/automata/cave_system/cleanup() + if(!ore_data || !ore_data.len) + for(var/oretype in typesof(/ore)-/ore) + var/ore/OD = new oretype() + ore_data[OD.name] = OD var/ore_count = round(map.len/20) while((ore_count>0) && (ore_turfs.len>0)) if(!priority_process) sleep(-1) diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm index deb9e45fa08..69cc3f6a172 100644 --- a/code/modules/reagents/reagent_containers/food/snacks.dm +++ b/code/modules/reagents/reagent_containers/food/snacks.dm @@ -3489,7 +3489,9 @@ slice_path = /obj/item/reagent_containers/food/snacks/doughslice slices_num = 3 center_of_mass = list("x"=16, "y"=16) - preloaded_reagents = list("protein" = 1, "nutriment" = 3) + nutriment_desc = list("dough" = 3) + nutriment_amt = 3 + preloaded_reagents = list("protein" = 1) taste_tag = list(BLAND_FOOD,FLOURY_FOOD) /obj/item/reagent_containers/food/snacks/doughslice diff --git a/code/modules/reagents/reagents/core.dm b/code/modules/reagents/reagents/core.dm index b3e3c62df42..e907e0945f7 100644 --- a/code/modules/reagents/reagents/core.dm +++ b/code/modules/reagents/reagents/core.dm @@ -79,7 +79,7 @@ if (prob(5)) T.visible_message(SPAN_WARNING("The water sizzles as it lands on \the [T]!")) - else if(volume >= 10) + else if(volume >= 10 && !QDELING(T)) T.wet_floor(1) return TRUE diff --git a/code/modules/reagents/reagents/toxins.dm b/code/modules/reagents/reagents/toxins.dm index 9183eb1161f..1a76b18968a 100644 --- a/code/modules/reagents/reagents/toxins.dm +++ b/code/modules/reagents/reagents/toxins.dm @@ -564,7 +564,7 @@ to_chat(M, SPAN_DANGER("Your flesh rapidly mutates!")) for(var/obj/item/W in H) //Check all items on the person if(istype(W, /obj/item/organ/external/robotic) || istype(W, /obj/item/implant)) //drop prosthetic limbs and implants, you are a slime now. - W.dropped() + W.dropped(M) H.set_species(SPECIES_SLIME) /datum/reagent/toxin/aslimetoxin @@ -595,7 +595,7 @@ if(istype(W, /obj/item/implant) || istype(W, /obj/item/organ/external/robotic)) //Check if item is implant or prosthetic if(istype(W, /obj/item/implant/core_implant/cruciform)) //If cruciform is present victim is gibbed instead of transformed cruciformed = TRUE - W.dropped() //use the baseline dropped() + W.dropped(M) //use the baseline dropped() continue W.layer = initial(W.layer) W.loc = M.loc diff --git a/code/modules/research/designs/circuits.dm b/code/modules/research/designs/circuits.dm index f5c38fe0f0e..d424223f6d9 100644 --- a/code/modules/research/designs/circuits.dm +++ b/code/modules/research/designs/circuits.dm @@ -36,11 +36,6 @@ sort_string = "MABBA" category = CAT_MISC -/datum/design/research/circuit/secdata - name = "security records console" - build_path = /obj/item/electronics/circuitboard/secure_data - sort_string = "DABAA" - category = CAT_COMP /datum/design/research/circuit/prisonmanage name = "prisoner management console" @@ -48,11 +43,6 @@ sort_string = "DACAA" category = CAT_COMP -/datum/design/research/circuit/med_data - name = "medical records console" - build_path = /obj/item/electronics/circuitboard/med_data - sort_string = "FAAAA" - category = CAT_COMP /datum/design/research/circuit/operating name = "patient monitoring console" diff --git a/code/modules/research/nodes/biotech.dm b/code/modules/research/nodes/biotech.dm index 609699af18e..b0c65c29102 100644 --- a/code/modules/research/nodes/biotech.dm +++ b/code/modules/research/nodes/biotech.dm @@ -17,7 +17,7 @@ /datum/technology/basic_med_machines name = "Basic Medical Machines" - desc = "Basic medical databases and surgical monitoring." + desc = "Basic surgical monitoring." tech_type = RESEARCH_BIOTECH x = 0.25 @@ -28,9 +28,7 @@ required_tech_levels = list() cost = 200 - unlocks_designs = list( /datum/design/research/circuit/med_data, - /datum/design/research/circuit/operating - ) + unlocks_designs = list(/datum/design/research/circuit/operating) /* /datum/technology/virology name = "Virology" diff --git a/code/modules/sanity/breakdowns.dm b/code/modules/sanity/breakdowns.dm index 0d4a81d8745..ea95d2ac83c 100644 --- a/code/modules/sanity/breakdowns.dm +++ b/code/modules/sanity/breakdowns.dm @@ -201,7 +201,7 @@ /datum/breakdown/negative/selfharm/occur() spawn(delay) - ++holder.owner.suppress_communication + ++holder?.owner.suppress_communication return ..() /datum/breakdown/negative/selfharm/conclude() @@ -240,9 +240,9 @@ /datum/breakdown/negative/hysteric/occur() spawn(delay) - holder.owner.SetWeakened(4) - holder.owner.SetStunned(4) - ++holder.owner.suppress_communication + holder?.owner.SetWeakened(4) + holder?.owner.SetStunned(4) + ++holder?.owner.suppress_communication return ..() /datum/breakdown/negative/hysteric/conclude() diff --git a/code/modules/surgery/autodoc.dm b/code/modules/surgery/autodoc.dm index 821ad4939e5..cb80d952e44 100644 --- a/code/modules/surgery/autodoc.dm +++ b/code/modules/surgery/autodoc.dm @@ -116,6 +116,7 @@ if(patchnote.surgery_operations & AUTODOC_TOXIN) to_chat(patient, SPAN_NOTICE("Administering anti-toxin to patient.")) patient.adjustToxLoss(-damage_heal_amount) + patient.add_chemical_effect(CE_ANTITOX, damage_heal_amount/10) if(!patient.getToxLoss()) patchnote.surgery_operations &= ~AUTODOC_TOXIN @@ -132,8 +133,8 @@ else if (patchnote.surgery_operations & AUTODOC_BLOOD) to_chat(patient, SPAN_NOTICE("Administering blood IV to patient.")) var/datum/reagent/organic/blood/blood = patient.vessel.reagent_list[1] - blood.volume += damage_heal_amount - if(blood.volume >= patient.vessel.total_volume) + blood.volume = min(blood.volume + damage_heal_amount, patient.vessel.maximum_volume) + if(blood.volume == patient.vessel.maximum_volume) patchnote.surgery_operations &= ~AUTODOC_BLOOD else if(patchnote.surgery_operations & AUTODOC_DAMAGE) @@ -164,30 +165,31 @@ if(istype(patchnote.organ, /obj/item/organ/internal)) var/obj/item/organ/internal/I = patchnote.organ to_chat(patient, SPAN_NOTICE("Treating internal wounds in the patient's [I.name].")) - SEND_SIGNAL_OLD(I, COMSIG_IWOUND_TREAT, TRUE, TRUE) - patchnote.surgery_operations &= ~AUTODOC_INTERNAL_WOUNDS + var/datum/internal_wound/wound = I.wounddatums[pick(I.wounddatums)] + if(istype(wound)) + wound.treatment(TRUE, TRUE) + if(!length(I.wounddatums)) patchnote.surgery_operations &= ~AUTODOC_INTERNAL_WOUNDS /datum/autodoc/Process() if(!patient) stop() + else if(current_step > picked_patchnotes.len) + stop() + scan_user(patient) + return while(!(picked_patchnotes[current_step].surgery_operations)) - if(current_step + 1 > picked_patchnotes.len) + current_step++ + if(current_step > picked_patchnotes.len) stop() scan_user(patient) return - else - current_step++ if(world.time > (start_op_time + processing_speed)) start_op_time = world.time patient.updatehealth() if(process_note(picked_patchnotes[current_step])) - if(current_step + 1 > picked_patchnotes.len) - stop() - scan_user(patient) - else - current_step++ + current_step++ /datum/autodoc/proc/fail() current_step++ diff --git a/html/changelogs/AutoChangeLog-pr-8570.yml b/html/changelogs/AutoChangeLog-pr-8570.yml new file mode 100644 index 00000000000..5fd14d077a1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8570.yml @@ -0,0 +1,7 @@ +author: chickenish, bobob +delete-after: true +changes: + - rscadd: Added modular bolt-gun config + - tweak: tweaked Riose cost + - bugfix: fixed clrifle bolt action ammo choice discrepancy + - imageadd: added modular boltgun parts diff --git a/html/changelogs/AutoChangeLog-pr-8586.yml b/html/changelogs/AutoChangeLog-pr-8586.yml new file mode 100644 index 00000000000..db1ee805e87 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8586.yml @@ -0,0 +1,9 @@ +author: Chickenish +delete-after: true +changes: + - rscadd: Added Plasteel Coin + - rscdel: Removed Iron Coin + - bugfix: Coins now moderately valuable for use and trade. + - spellcheck: Platinum coin no longer spelled as Platunum coin. + - code_imp: Moneybag no longer shoves coins in the person holding the + moneybag. diff --git a/html/changelogs/AutoChangeLog-pr-8590.yml b/html/changelogs/AutoChangeLog-pr-8590.yml new file mode 100644 index 00000000000..3905262bbaf --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8590.yml @@ -0,0 +1,5 @@ +author: Chickenish +delete-after: true +changes: + - tweak: 'balance: Prying damaged flooring now produces scrap metal instead of deleting + the floor with no returns.' diff --git a/html/changelogs/AutoChangeLog-pr-8594.yml b/html/changelogs/AutoChangeLog-pr-8594.yml new file mode 100644 index 00000000000..9bee9b16fb8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8594.yml @@ -0,0 +1,9 @@ +author: Chickenish +delete-after: true +changes: + - rscadd: Character records are now automatically defined based on the + character they are associated with. + - rscdel: Destroyed Data Core + - tweak: Sechud interface reworked + - bugfix: Security records now accessible via computer + - admin: fully_replace_character_name proc now fully functional diff --git a/html/changelogs/AutoChangeLog-pr-8595.yml b/html/changelogs/AutoChangeLog-pr-8595.yml new file mode 100644 index 00000000000..29a9194ce41 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8595.yml @@ -0,0 +1,4 @@ +author: Chickenish +delete-after: true +changes: + - refactor: stationary Tanks refactored to unique type diff --git a/html/changelogs/AutoChangeLog-pr-8596.yml b/html/changelogs/AutoChangeLog-pr-8596.yml new file mode 100644 index 00000000000..a275c006c75 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8596.yml @@ -0,0 +1,4 @@ +author: Chickenish +delete-after: true +changes: + - bugfix: fixed Autodoc diff --git a/html/changelogs/AutoChangeLog-pr-8610.yml b/html/changelogs/AutoChangeLog-pr-8610.yml new file mode 100644 index 00000000000..f81c629263e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8610.yml @@ -0,0 +1,4 @@ +author: Chickenish +delete-after: true +changes: + - rscadd: Mice can now live. diff --git a/html/changelogs/AutoChangeLog-pr-8612.yml b/html/changelogs/AutoChangeLog-pr-8612.yml new file mode 100644 index 00000000000..d3e8bac789c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8612.yml @@ -0,0 +1,4 @@ +author: Chickenish +delete-after: true +changes: + - bugfix: Holding a candle as it runs out of wax now functions properly. diff --git a/html/changelogs/AutoChangeLog-pr-8613.yml b/html/changelogs/AutoChangeLog-pr-8613.yml new file mode 100644 index 00000000000..04d1924f576 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8613.yml @@ -0,0 +1,5 @@ +author: Chickenish +delete-after: true +changes: + - bugfix: self-harm and hysteric breakdowns no longer cause a runtime when + they begin shortly before the associated human is obliterated. diff --git a/html/changelogs/AutoChangeLog-pr-8615.yml b/html/changelogs/AutoChangeLog-pr-8615.yml new file mode 100644 index 00000000000..02eafbaaede --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8615.yml @@ -0,0 +1,5 @@ +author: Chickenish +delete-after: true +changes: + - bugfix: nutriment made via roach chem decay is now fully drinkable. + - bugfix: Flat Dough and derivatives are now more edible. diff --git a/html/changelogs/AutoChangeLog-pr-8617.yml b/html/changelogs/AutoChangeLog-pr-8617.yml new file mode 100644 index 00000000000..688c64b11bf --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8617.yml @@ -0,0 +1,5 @@ +author: Chickenish +delete-after: true +changes: + - balance: Clamped wounds do not stay clamped when re-opened. + - balance: Pressuring wounds now clamps the wound until re-opened. diff --git a/html/changelogs/AutoChangeLog-pr-8621.yml b/html/changelogs/AutoChangeLog-pr-8621.yml new file mode 100644 index 00000000000..9961f8f1c58 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8621.yml @@ -0,0 +1,10 @@ +author: Chickenish +delete-after: true +changes: + - rscadd: Eating another carrion's core with your maw gives you the other + carrion's disguises + - balance: carrion over-hunger is now punished by making your human form + hungry + - tweak: carrion maw now works with holders. + - tweak: carrions now drop as an inert item if the core is killed. + - bugfix: eating with carrion maw provides proper chem value diff --git a/html/changelogs/AutoChangeLog-pr-8625.yml b/html/changelogs/AutoChangeLog-pr-8625.yml new file mode 100644 index 00000000000..a7f91c96f66 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8625.yml @@ -0,0 +1,5 @@ +author: Chickenish +delete-after: true +changes: + - bugfix: dismantling walls no longer results in GC errors. + - code_imp: Qdel hints are now better diff --git a/html/changelogs/AutoChangeLog-pr-8626.yml b/html/changelogs/AutoChangeLog-pr-8626.yml new file mode 100644 index 00000000000..21592f367e8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-8626.yml @@ -0,0 +1,4 @@ +author: Chickenish +delete-after: true +changes: + - bugfix: fixed a mistake with vague attack logic diff --git a/icons/obj/crafts.dmi b/icons/obj/crafts.dmi index 7f510b84c7e..80c310ea350 100644 Binary files a/icons/obj/crafts.dmi and b/icons/obj/crafts.dmi differ diff --git a/icons/obj/guns/projectile/modular/bolt.dmi b/icons/obj/guns/projectile/modular/bolt.dmi new file mode 100644 index 00000000000..bbbfef4d598 Binary files /dev/null and b/icons/obj/guns/projectile/modular/bolt.dmi differ diff --git a/icons/ui_icons/dmis/uiicons16.dmi b/icons/ui_icons/dmis/uiicons16.dmi new file mode 100644 index 00000000000..7b5d90ace41 Binary files /dev/null and b/icons/ui_icons/dmis/uiicons16.dmi differ diff --git a/maps/main_ship/eris_classic.dmm b/maps/main_ship/eris_classic.dmm index 0f321fdc1e8..f9f6358a91a 100644 --- a/maps/main_ship/eris_classic.dmm +++ b/maps/main_ship/eris_classic.dmm @@ -398,7 +398,7 @@ /turf/floor/tiled/techmaint_panels, /area/eris/maintenance/section1deck5central) "abm" = ( -/obj/machinery/atmospherics/pipe/tank/air, +/obj/machinery/atmospherics/tank/air, /turf/floor/tiled/techmaint, /area/eris/maintenance/section2deck5starboard) "abn" = ( @@ -1014,7 +1014,7 @@ /turf/floor/tiled/dark, /area/eris/security/prison) "acE" = ( -/obj/machinery/atmospherics/pipe/tank/air, +/obj/machinery/atmospherics/tank/air, /obj/machinery/camera/network/security{ dir = 8 }, @@ -6302,7 +6302,7 @@ /turf/floor/tiled/steel, /area/eris/hallway/side/eschangarb) "apa" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 1; initialize_directions = 0 }, @@ -6865,7 +6865,7 @@ /turf/floor/tiled/dark, /area/eris/rnd/podbay) "aqs" = ( -/obj/machinery/atmospherics/pipe/tank/air, +/obj/machinery/atmospherics/tank/air, /turf/floor/tiled/dark, /area/eris/rnd/podbay) "aqt" = ( @@ -7554,7 +7554,7 @@ /turf/wall/low/with_glass/smart, /area/eris/hallway/side/section3starboard) "arR" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 8 }, /turf/floor/tiled/techmaint, @@ -10595,7 +10595,7 @@ /turf/floor/plating/under, /area/eris/maintenance/section4deck5port) "azX" = ( -/obj/machinery/atmospherics/pipe/tank/oxygen{ +/obj/machinery/atmospherics/tank/oxygen{ dir = 4 }, /turf/floor/tiled/steel/brown_platform, @@ -11043,7 +11043,7 @@ /turf/floor/tiled/steel/cargo, /area/eris/maintenance/section3deck2starboard) "aAW" = ( -/obj/machinery/atmospherics/pipe/tank/plasma{ +/obj/machinery/atmospherics/tank/plasma{ dir = 4 }, /turf/floor/tiled/steel/brown_platform, @@ -14625,7 +14625,7 @@ /turf/floor/tiled/steel, /area/eris/hallway/side/eschangarb) "aLw" = ( -/obj/machinery/atmospherics/pipe/tank/air, +/obj/machinery/atmospherics/tank/air, /turf/floor/plating/under, /area/eris/maintenance/section3deck1central) "aLx" = ( @@ -15834,7 +15834,7 @@ /turf/floor/tiled/steel/bluecorner, /area/eris/security/prisoncells) "aPv" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 8 }, /turf/floor/tiled/dark/gray_platform, @@ -16436,7 +16436,7 @@ /turf/wall, /area/eris/maintenance/section4deck5port) "aQw" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 8 }, /turf/floor/plating, @@ -19232,7 +19232,7 @@ /turf/open, /area/eris/security/prisoncells) "aXa" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 4 }, /turf/floor/plating/under, @@ -19313,7 +19313,7 @@ /turf/floor/plating/under, /area/eris/maintenance/section1deck4central) "aXm" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 8 }, /turf/floor/plating/under, @@ -23081,7 +23081,7 @@ /turf/floor/tiled/techmaint, /area/eris/maintenance/section2deck4central) "beN" = ( -/obj/machinery/atmospherics/pipe/tank/air, +/obj/machinery/atmospherics/tank/air, /turf/floor/plating/under, /area/eris/maintenance/section2deck4central) "beO" = ( @@ -23090,7 +23090,7 @@ /turf/floor/plating/under, /area/eris/maintenance/section2deck4starboard) "beP" = ( -/obj/machinery/atmospherics/pipe/tank/air, +/obj/machinery/atmospherics/tank/air, /turf/floor/tiled/techmaint, /area/eris/maintenance/section3deck1central) "beQ" = ( @@ -30376,7 +30376,7 @@ /turf/floor/tiled/steel, /area/eris/hallway/main/section1) "bwC" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 4 }, /obj/structure/railing, @@ -31242,7 +31242,7 @@ /turf/floor/tiled/steel, /area/eris/hallway/main/section2) "byA" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 8 }, /obj/structure/railing, @@ -33830,7 +33830,7 @@ /turf/floor/plating, /area/eris/maintenance/section4deck4port) "bFc" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 4 }, /obj/structure/railing{ @@ -34134,7 +34134,7 @@ }, /area/eris/command/tcommsat/chamber) "bFH" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 8 }, /obj/structure/railing{ @@ -34869,7 +34869,7 @@ /turf/floor/wood, /area/eris/crew_quarters/hydroponics) "bHr" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 4 }, /turf/floor/tiled/steel, @@ -58029,7 +58029,7 @@ /turf/floor/tiled/steel/techfloor_grid, /area/eris/engineering/breakroom) "cNa" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 4 }, /turf/floor/plating/under, @@ -58918,13 +58918,13 @@ }, /area/shuttle/mining/station) "cPO" = ( -/obj/machinery/atmospherics/pipe/tank/air, +/obj/machinery/atmospherics/tank/air, /turf/shuttle/floor/mining{ icon_state = "12,21" }, /area/shuttle/mining/station) "cPP" = ( -/obj/machinery/atmospherics/pipe/tank/air, +/obj/machinery/atmospherics/tank/air, /turf/shuttle/floor/mining{ icon_state = "13,21" }, @@ -61159,7 +61159,7 @@ /turf/floor/tiled/techmaint, /area/eris/maintenance/section4deck3port) "cWa" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 1; initialize_directions = 0 }, @@ -74419,7 +74419,7 @@ /turf/floor/plating/under, /area/eris/medical/medbay) "dBk" = ( -/obj/machinery/atmospherics/pipe/tank/oxygen{ +/obj/machinery/atmospherics/tank/oxygen{ dir = 8 }, /turf/floor/tiled/white/brown_platform, @@ -76993,7 +76993,7 @@ /area/eris/maintenance/section4deck2port) "dHx" = ( /obj/effect/floor_decal/rust, -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 1; initialize_directions = 0 }, @@ -81558,7 +81558,7 @@ /turf/floor/tiled/techmaint, /area/eris/maintenance/section2deck1starboard) "dUS" = ( -/obj/machinery/atmospherics/pipe/tank/air, +/obj/machinery/atmospherics/tank/air, /turf/floor/tiled/techmaint, /area/eris/maintenance/section2deck1port) "dUT" = ( @@ -82964,7 +82964,7 @@ /turf/wall/low/with_glass/reinforced, /area/eris/quartermaster/office) "dYk" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 8 }, /obj/structure/railing{ @@ -88887,7 +88887,7 @@ }, /area/shuttle/research/station) "enr" = ( -/obj/machinery/atmospherics/pipe/tank/air, +/obj/machinery/atmospherics/tank/air, /turf/shuttle/floor/science{ icon_state = "5,5" }, @@ -92886,7 +92886,7 @@ /turf/floor/tiled/steel, /area/eris/hallway/side/section3starboard) "exh" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 8 }, /obj/machinery/alarm{ @@ -95710,7 +95710,7 @@ /turf/floor/tiled/white, /area/eris/rnd/xenobiology/xenoflora) "eDP" = ( -/obj/machinery/atmospherics/pipe/tank/air, +/obj/machinery/atmospherics/tank/air, /obj/structure/sign/atmos_air{ pixel_y = 32 }, @@ -102856,6 +102856,14 @@ }, /turf/floor/plating/under, /area/eris/maintenance/sorter) +"qmi" = ( +/obj/item/cell/medium, +/obj/item/cell/medium, +/obj/item/computer_hardware/processor_unit, +/obj/item/computer_hardware/tesla_link, +/obj/item/computer_hardware/tesla_link, +/turf/floor/hull, +/area/space) "qmJ" = ( /obj/machinery/door/blast/shutters{ dir = 4; @@ -104952,6 +104960,13 @@ }, /turf/floor/plating/under, /area/eris/maintenance/section3deck5port) +"tZv" = ( +/obj/item/computer_hardware/network_card/wired, +/obj/item/computer_hardware/network_card/wired, +/obj/item/computer_hardware/scanner/paper, +/obj/item/computer_hardware/scanner/paper, +/turf/floor/hull, +/area/space) "tZw" = ( /obj/structure/cable/green{ d1 = 4; @@ -205242,7 +205257,7 @@ iEk cBO cwU abF -abF +qmi abF cwU cwU @@ -205444,7 +205459,7 @@ cBO cos cwU abF -abF +tZv abF abF cwU diff --git a/maps/main_ship/eris_smol.dmm b/maps/main_ship/eris_smol.dmm index c5cfdf7338e..0ef1e18d883 100644 --- a/maps/main_ship/eris_smol.dmm +++ b/maps/main_ship/eris_smol.dmm @@ -1035,7 +1035,7 @@ /turf/floor/tiled/dark/panels, /area/eris/crew_quarters/firing_range) "acF" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 4 }, /turf/floor/plating/under, @@ -1170,7 +1170,7 @@ /turf/floor/plating/under, /area/eris/neotheology/bioreactor) "acV" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 8 }, /turf/floor/plating/under, @@ -13403,7 +13403,7 @@ /turf/floor/plating/under, /area/eris/maintenance/section2deck3port) "aGf" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 8 }, /turf/floor/plating/under, @@ -20903,7 +20903,7 @@ /turf/floor/plating/under, /area/eris/maintenance/section2deck3port) "aYq" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 8 }, /obj/structure/railing{ @@ -39583,7 +39583,7 @@ /turf/floor/tiled/steel/bar_dance, /area/eris/command/tcommsat/chamber) "bQs" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 1; initialize_directions = 0 }, @@ -42835,7 +42835,7 @@ /turf/floor/plating/under, /area/eris/maintenance/section1deck1central) "bYe" = ( -/obj/machinery/atmospherics/pipe/tank/plasma{ +/obj/machinery/atmospherics/tank/plasma{ dir = 8 }, /turf/floor/tiled/techmaint_cargo, @@ -44844,7 +44844,7 @@ /turf/floor/tiled/steel, /area/eris/crew_quarters/fitness) "cdj" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 1; initialize_directions = 0 }, @@ -50458,7 +50458,7 @@ /turf/floor/tiled/dark/cargo, /area/eris/crew_quarters/hydroponics) "crf" = ( -/obj/machinery/atmospherics/pipe/tank/air, +/obj/machinery/atmospherics/tank/air, /turf/floor/plating/under, /area/eris/maintenance/section2deck4port) "crg" = ( @@ -51700,7 +51700,7 @@ /turf/floor/plating/under, /area/eris/maintenance/disposal) "cum" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 4; start_pressure = 740.5 }, @@ -55477,7 +55477,7 @@ /turf/floor/grass, /area/eris/crew_quarters/hydroponics/garden) "cDv" = ( -/obj/machinery/atmospherics/pipe/tank/oxygen, +/obj/machinery/atmospherics/tank/oxygen, /turf/floor/plating/under, /area/eris/crew_quarters/sleep/cryo) "cDw" = ( @@ -58144,13 +58144,13 @@ }, /area/shuttle/mining/station) "cJE" = ( -/obj/machinery/atmospherics/pipe/tank/air, +/obj/machinery/atmospherics/tank/air, /turf/shuttle/floor/mining{ icon_state = "12,21" }, /area/shuttle/mining/station) "cJF" = ( -/obj/machinery/atmospherics/pipe/tank/air, +/obj/machinery/atmospherics/tank/air, /turf/shuttle/floor/mining{ icon_state = "13,21" }, @@ -58184,7 +58184,7 @@ /turf/floor/plating/under, /area/eris/maintenance/section2deck1starboard) "cJL" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 1; initialize_directions = 0 }, @@ -60188,7 +60188,7 @@ }, /area/shuttle/research/station) "cPi" = ( -/obj/machinery/atmospherics/pipe/tank/air, +/obj/machinery/atmospherics/tank/air, /turf/shuttle/floor/science{ icon_state = "5,5" }, @@ -60767,7 +60767,7 @@ /turf/floor/tiled/steel/gray_platform, /area/eris/crew_quarters/pubeva) "cQM" = ( -/obj/machinery/atmospherics/pipe/tank/oxygen{ +/obj/machinery/atmospherics/tank/oxygen{ dir = 4 }, /turf/floor/tiled/steel/brown_perforated, @@ -61041,7 +61041,7 @@ /turf/floor/plating/under, /area/eris/storage/tech) "cRy" = ( -/obj/machinery/atmospherics/pipe/tank/plasma{ +/obj/machinery/atmospherics/tank/plasma{ dir = 4 }, /turf/floor/tiled/steel/brown_perforated, @@ -63034,7 +63034,7 @@ /turf/floor/tiled/steel/monofloor, /area/eris/hallway/side/docks) "cXh" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 4 }, /obj/structure/railing{ @@ -63082,7 +63082,7 @@ /turf/floor/plating/under, /area/eris/maintenance/section2deck2port) "cXl" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 4 }, /obj/structure/railing, @@ -63820,7 +63820,7 @@ /turf/floor/tiled/white/brown_perforated, /area/eris/medical/medbreak) "cYR" = ( -/obj/machinery/atmospherics/pipe/tank/oxygen{ +/obj/machinery/atmospherics/tank/oxygen{ dir = 8 }, /obj/structure/railing, @@ -68339,7 +68339,7 @@ /turf/floor/tiled/steel/brown_perforated, /area/eris/quartermaster/miningdock) "djx" = ( -/obj/machinery/atmospherics/pipe/tank/air, +/obj/machinery/atmospherics/tank/air, /obj/structure/railing, /turf/floor/plating/under, /area/eris/maintenance/section2deck1starboard) @@ -73992,7 +73992,7 @@ /turf/floor/tiled/steel/cargo, /area/eris/engineering/foyer) "dwN" = ( -/obj/machinery/atmospherics/pipe/tank/air, +/obj/machinery/atmospherics/tank/air, /obj/machinery/alarm{ pixel_y = 26 }, diff --git a/maps/shuttle/hulk.dmm b/maps/shuttle/hulk.dmm index b98edd87c54..f5aace8a896 100644 --- a/maps/shuttle/hulk.dmm +++ b/maps/shuttle/hulk.dmm @@ -117,7 +117,7 @@ "sL" = (/turf/shuttle/wall/mining{icon_state = "1,19"},/area/space) "te" = (/obj/structure/shuttle_part/mining{icon_state = "5,1"},/turf/space,/area/space) "tf" = (/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/shuttle/floor/mining{icon_state = "10,14"},/area/space) -"tC" = (/obj/machinery/atmospherics/pipe/tank/air,/turf/shuttle/floor/mining{icon_state = "12,21"},/area/space) +"tC" = (/obj/machinery/atmospherics/tank/air,/turf/shuttle/floor/mining{icon_state = "12,21"},/area/space) "tW" = (/turf/shuttle/wall/mining{icon_state = "15,6"; opacity = 0},/area/space) "tZ" = (/obj/structure/table/standard,/obj/item/device/lighting/toggleable/lamp,/turf/shuttle/floor/mining{icon_state = "5,16"},/area/space) "ud" = (/obj/structure/shuttle_part/mining{icon_state = "10,0"},/turf/template_noop,/area/space) @@ -369,7 +369,7 @@ "Yf" = (/obj/structure/shuttle_part/mining{icon_state = "12,0"},/turf/template_noop,/area/space) "Yg" = (/obj/structure/shuttle_part/mining{icon_state = "3,14"},/turf/space,/area/space) "Yk" = (/turf/shuttle/wall/mining{icon_state = "7,18"},/area/space) -"Yq" = (/obj/machinery/atmospherics/pipe/tank/air,/turf/shuttle/floor/mining{icon_state = "13,21"},/area/space) +"Yq" = (/obj/machinery/atmospherics/tank/air,/turf/shuttle/floor/mining{icon_state = "13,21"},/area/space) "Yu" = (/turf/shuttle/wall/mining{icon_state = "11,22"},/area/space) "YK" = (/turf/shuttle/floor/mining{icon_state = "12,13"},/area/space) "YN" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/light/small,/turf/shuttle/floor/mining{icon_state = "4,4"},/area/space) diff --git a/maps/shuttle/nerd.dmm b/maps/shuttle/nerd.dmm index 5e12ce90452..f9fa15dcf67 100644 --- a/maps/shuttle/nerd.dmm +++ b/maps/shuttle/nerd.dmm @@ -10,7 +10,7 @@ "bz" = (/turf/shuttle/wall/science{icon_state = "10,13"},/area/space) "bI" = (/obj/structure/shuttle_part/science{icon_state = "11,0"},/turf/template_noop,/area/space) "bK" = (/obj/machinery/light/small{dir = 1},/turf/shuttle/floor/science{icon_state = "10,12"},/area/space) -"cl" = (/obj/machinery/atmospherics/pipe/tank/air,/turf/shuttle/floor/science{icon_state = "5,5"},/area/space) +"cl" = (/obj/machinery/atmospherics/tank/air,/turf/shuttle/floor/science{icon_state = "5,5"},/area/space) "co" = (/turf/shuttle/wall/science{icon_state = "8,0"},/area/space) "cI" = (/obj/structure/table/standard,/obj/machinery/camera/network/research_outpost{dir = 1},/obj/machinery/recharger,/turf/shuttle/floor/science{icon_state = "7,17"},/area/space) "cM" = (/obj/machinery/atmospherics/pipe/simple/hidden/universal,/turf/shuttle/floor/science{icon_state = "5,4"},/area/space) diff --git a/maps/submaps/centcomm.dmm b/maps/submaps/centcomm.dmm index 40c1ed3fbd0..a4adab0ae35 100644 --- a/maps/submaps/centcomm.dmm +++ b/maps/submaps/centcomm.dmm @@ -2983,7 +2983,7 @@ /turf/space, /area/space) "oz" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 4; start_pressure = 740.5 }, diff --git a/maps/submaps/pulsar.dmm b/maps/submaps/pulsar.dmm index 3a8846416dc..9afa0f086a7 100644 --- a/maps/submaps/pulsar.dmm +++ b/maps/submaps/pulsar.dmm @@ -1141,7 +1141,7 @@ /turf/floor/plating/under, /area/outpost/pulsar/maintenance) "LT" = ( -/obj/machinery/atmospherics/pipe/tank/air{ +/obj/machinery/atmospherics/tank/air{ dir = 8 }, /turf/floor/tiled/steel/brown_platform, diff --git a/nano/templates/crew_records.tmpl b/nano/templates/crew_records.tmpl index 543879ebe0d..009496403e1 100644 --- a/nano/templates/crew_records.tmpl +++ b/nano/templates/crew_records.tmpl @@ -28,6 +28,27 @@ {{if value.needs_big_box}}
{{:value.value}} + {{else}} + {{if value.list_value}} + {{for value.list_value}} + {{:value}} + {{/for}} + {{else}} + {{if value.list_clumps}} + {{for value.list_clumps}} + {{for value}} + {{:value}} + {{/for}} + {{/for}} + {{else}} + {{if value.links}} + {{for 1 to value.links.len}} + {{for value.links}} + + {{/if}} + {{/if}} + {{/if}} + {{/if}}
{{else}}
{{:value.value}}
diff --git a/nano/templates/pai_medrecords.tmpl b/nano/templates/pai_medrecords.tmpl index 37b1d7061ca..b45d66cd2c9 100644 --- a/nano/templates/pai_medrecords.tmpl +++ b/nano/templates/pai_medrecords.tmpl @@ -15,10 +15,6 @@ code/modules/mob/living/silicon/pai/software_modules.dm
Name
{{:data.general.name}}
-
-
Record ID
-
{{:data.general.id}}
-
Sex
{{:data.general.sex}}
@@ -32,50 +28,52 @@ code/modules/mob/living/silicon/pai/software_modules.dm
{{:data.general.age}}
-
Rank
-
{{:data.general.rank}}
+
Job Title
+
{{:data.general.job}}
Fingerprint
{{:data.general.fingerprint}}
-
Physical Status
-
{{:data.general.p_stat}}
+
=Status
+
{{:data.general.status}}
-
Mental Status
-
{{:data.general.m_stat}}
+
Blood Type
+
{{:data.general.bloodtype}}
{{/if}} {{if data.medical}}
-
Blood Type
-
{{:data.medical.b_type}}
-
-
-
Minor Disabilities
-
{{:data.medical.mi_dis}}
-
{{:data.medical.mi_dis_d}}
+
Prosthetics
+ {{for data.medical.value.prosthetics}} +
{{:value}}
+ {{/for}}
-
Major Disabilities
-
{{:data.medical.ma_dis}}
-
{{:data.medical.ma_dis_d}}
+
Wounds
+ {{for data.medical.value.wounds}} +
{{:value}}
+ {{/for}}
-
Allergies
-
{{:data.medical.alg}}
-
{{:data.medical.alg_d}}
+
Body State
+ {{for data.medical.value.body state}} +
{{:value}}
+ {{/for}}
-
Current Diseases
-
{{:data.medical.cdi}}
-
{{:data.medical.cdi_d}}
+
Chemical History
+ {{for data.medical.value.chemhistory}} +
{{:value}}
+ {{/for}}
-
Important Notes
-
{{:data.medical.notes}}
+
Psychological Profile
+ {{for data.medical.value.psychological}} +
{{:value}}
+ {{/for}}
{{/if}} diff --git a/nano/templates/pai_secrecords.tmpl b/nano/templates/pai_secrecords.tmpl index e139034c0de..cdb3321a07c 100644 --- a/nano/templates/pai_secrecords.tmpl +++ b/nano/templates/pai_secrecords.tmpl @@ -15,10 +15,6 @@ code/modules/mob/living/silicon/pai/software_modules.dm
Name
{{:data.general.name}}
-
-
Record ID
-
{{:data.general.id}}
-
Sex
{{:data.general.sex}}
@@ -32,40 +28,24 @@ code/modules/mob/living/silicon/pai/software_modules.dm
{{:data.general.age}}
-
Rank
-
{{:data.general.rank}}
+
Job Title
+
{{:data.general.job}}
Fingerprint
{{:data.general.fingerprint}}
-
Physical Status
-
{{:data.general.p_stat}}
+
Status
+
{{:data.general.status}}
-
-
Mental Status
-
{{:data.general.m_stat}}
-
-{{/if}} -{{if data.security}}
Criminal Status
-
{{:data.security.criminal}}
-
-
-
Minor Crimes
-
{{:data.security.mi_crim}}
-
{{:data.security.mi_crim_d}}
-
-
-
Major Crimes
-
{{:data.security.ma_crim}}
-
{{:data.security.ma_crim_d}}
-
+
{{:data.general.criminalStatus }}
+
Important Notes
-
{{:data.security.notes}}
+
{{:data.general.secNotes}}
{{/if}} diff --git a/tgui/packages/tgui/interfaces/Computer.tsx b/tgui/packages/tgui/interfaces/Computer.tsx new file mode 100644 index 00000000000..cd4fa1f534f --- /dev/null +++ b/tgui/packages/tgui/interfaces/Computer.tsx @@ -0,0 +1,169 @@ +import { BooleanLike } from 'common/react'; +import { Button, Box, Table } from '../components'; +import { TableCell, TableRow } from '../components/Table'; +import { sendAct } from '../backend'; + +export interface ComputerInterface { + PC_batteryicon: string; + PC_batterypercent: string; + PC_showbatteryicon: BooleanLike; + PC_light_name: string; + PC_light_on: BooleanLike; + PC_apclinkicon: string; + PC_ntneticon: string; + has_gps: BooleanLike; + gps_icon: string; + gps_data: string; + PC_programheaders: Programheader[]; + PC_stationtime: string; + PC_hasheader: BooleanLike; + PC_showexitprogram: BooleanLike; + mapZLevels: number[]; + mapZLevel: number; +} + +type Programheader = { + icon: string; +}; + +export const ProgramShell = (props, context) => { + const { + PC_batteryicon, + PC_batterypercent, + PC_showbatteryicon, + PC_light_name, + PC_light_on, + PC_apclinkicon, + PC_ntneticon, + has_gps, + gps_icon, + gps_data, + PC_programheaders, + PC_stationtime, + PC_hasheader, + PC_showexitprogram, + mapZLevels, + mapZLevel, + } = props; + const act = sendAct; + return ( + <> + + { + // Add a template with the key "headerContent" to have it rendered here --> + } + {PC_hasheader} + + + + + + {PC_batteryicon && PC_showbatteryicon && ( + + + + )} + {PC_batterypercent && PC_showbatteryicon && ( + + {PC_batterypercent} + + )} + {PC_ntneticon && ( + + + + )} + {PC_apclinkicon && ( + + + + )} + {PC_stationtime && ( + + {PC_stationtime} + + )} + {PC_programheaders && + PC_programheaders.map((mapped) => ( + + + + ))} + +
+
+
+ + + + {PC_light_name && ( + +
+
+ + {has_gps && ( + + + + + + + {gps_data} + +
+
+ )} +
+
+ + + + {PC_showexitprogram && ( + + + + +
+
+ )} + {PC_showexitprogram || } + + + Initiating... + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/CrewRecords.tsx b/tgui/packages/tgui/interfaces/CrewRecords.tsx new file mode 100644 index 00000000000..3cb3f0bc944 --- /dev/null +++ b/tgui/packages/tgui/interfaces/CrewRecords.tsx @@ -0,0 +1,332 @@ +import { BooleanLike } from 'common/react'; +import { useBackend, sendAct } from '../backend'; +import { Button, Box, Divider, Table } from '../components'; +import { GameIcon } from '../components/GameIcon'; +import { Window } from '../layouts'; +import { ComputerInterface, ProgramShell } from './Computer'; +import { classes } from 'common/react'; + +interface CrewRecordsInterface extends RecordConcrete, ComputerInterface { + message: string; + front_pic: string; + side_pic: string; + pic_edit: BooleanLike; + all_records: RecordAbstract[]; + creation: BooleanLike; + dnasearch: BooleanLike; + fingersearch: BooleanLike; +} + +interface RecordConcrete { + name: string; + uid: number; + creator: string; + filetime: string; + fields: RecordField[]; + access: BooleanLike; + access_edit: BooleanLike; +} +type RecordField = { + access: BooleanLike; + access_edit: BooleanLike; + name: string; + value: string | number | object; + list_value: any[]; + list_clumps: object[]; + can_edit: BooleanLike; + needs_big_box: BooleanLike; + ignore_value: BooleanLike; + ID: number; +}; + +type RecordAbstract = { + name: string; + rank: string; + id: number; +}; + +export const CrewRecords = (props, context) => { + const { act, data } = useBackend(context); + const { + message, + uid, + fields, + front_pic, + side_pic, + pic_edit, + all_records, + creation, + dnasearch, + fingersearch, + } = data; + return ( + + + {ProgramShell(props, context)} + {message &&